You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MapStruct中无需绑定源属性生成目标属性值?

MapStruct设置无依赖源属性的Instant字段解决方案

方案一:通过自定义Provider组件+qualifiedByName实现

先定义一个封装当前Instant获取逻辑的Spring组件:

@Component
public class InstantProvider {
    @Named("currentInstant")
    public Instant getCurrentInstant() {
        return Instant.now();
    }
}

在MapStruct Mapper中,通过source = ""声明不依赖源对象的任何属性,再用qualifiedByName关联到Provider的方法:

@Mapper(componentModel = "spring", uses = InstantProvider.class)
public interface SourceToTargetMapper {
    @Mapping(target = "createdAt", source = "", qualifiedByName = "currentInstant")
    TargetJpa sourceToTarget(Source source);
}

该方式将获取当前Instant的逻辑统一封装,所有需要的Mapper都能复用这个组件,完全无需绑定多余的源属性。

方案二:通过@AfterMapping+通用接口复用逻辑

如果多个目标类都需要设置createdAt字段,先定义一个标记接口:

public interface HasCreatedAt {
    void setCreatedAt(Instant createdAt);
}

让TargetJpa实现这个接口:

public class TargetJpa implements HasCreatedAt {
    // 其他字段
    private Instant createdAt;

    @Override
    public void setCreatedAt(Instant createdAt) {
        this.createdAt = createdAt;
    }

    // 对应getter方法
}

创建包含通用设置逻辑的基础Mapper接口:

public interface BaseTimestampMapper {
    @AfterMapping
    default void populateCreatedAt(@MappingTarget HasCreatedAt target) {
        target.setCreatedAt(Instant.now());
    }
}

最后让业务Mapper继承该基础接口:

@Mapper(componentModel = "spring")
public interface SourceToTargetMapper extends BaseTimestampMapper {
    TargetJpa sourceToTarget(Source source);
}

MapStruct会在完成基础转换后自动调用populateCreatedAt方法设置字段,既不依赖源属性,又能在多个Mapper间复用逻辑。

这两种方案都避开了在expression中编写字符串形式的Java代码,也无需引入虚拟源属性,完全匹配你的需求。

内容的提问来源于stack exchange,提问作者Kalec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 21:15:42