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

在Mapstruct中如何在一个Mapper中注入另一个Mapper?

在Mapstruct中如何在一个Mapper中注入另一个Mapper?

看起来你在使用MapStruct处理多参数聚合映射时,遇到了依赖Mapper找不到的问题,我来帮你捋清楚怎么解决~

问题分析

你已经通过uses = [MyMapper::class]告诉MapStruct,MyAggregateMapper需要依赖MyMapper,这一步是正确的。但你在expression里直接写myMapper.mapMyTarget(...)时,生成的代码报错找不到myMapper变量,这是因为在手写的Java表达式中,MapStruct不会自动将依赖的Mapper暴露为可用的上下文变量(或者在Kotlin+MapStruct的组合场景下,变量引用的写法需要调整)。

最优解决方案:避免手写Expression,用MapStruct原生映射规则

其实完全不需要写Java表达式,利用MapStruct的多参数映射和qualifiedByName就能优雅解决:

因为MyAggregateMapper的myMapFoo方法已经包含了mySource、myContext1、myContext2这三个MyMapper.mapMyTarget需要的参数,我们只需要给myTarget字段的映射指定要调用的MyMapper中的方法(通过qualifiedByName匹配@Named("mapMyTarget")的方法)即可,MapStruct会自动帮你传递参数。

修改后的MyAggregateMapper代码如下:

@Mapper(
    componentModel = MappingConstants.ComponentModel.SPRING,
    unmappedTargetPolicy = ReportingPolicy.ERROR,
    uses = [MyMapper::class]
)
interface MyAggregateMapper {
    @Named("myAggregateMapper")
    @Mapping(target = "desc", source = "descParam.desc")
    // 直接指定使用MyMapper中名为mapMyTarget的方法,MapStruct会自动匹配所需参数
    @Mapping(target = "myTarget", qualifiedByName = ["mapMyTarget"])
    fun myMapFoo(
        mySource: MySource,
        myContext1: MyContext1,
        myContext2: MyContext2,
        descParam: MyAggregateDescriptionParam
    ): MyAggregateTarget
}

这样MapStruct生成的实现类会自动调用myMapper.mapMyTarget(mySource, myContext1, myContext2)来设置myTarget字段,完全不需要手写容易出错的Java表达式。

如果你坚持要用Expression的解决方案

如果因为某些场景必须使用expression,只需要在表达式中加上this.来引用实例变量即可(因为依赖的MyMapper是注入到MyAggregateMapperImpl中的实例变量):

@Mapping(target = "myTarget", expression = "java(this.myMapper.mapMyTarget(mySource,myContext1,myContext2))")

这样生成的代码中会正确引用注入的myMapper实例,不会再出现找不到变量的错误。

为什么原来的写法会报错?

当你使用uses = [MyMapper::class]时,MapStruct会在生成的MyAggregateMapperImpl中注入MyMapper作为实例变量:

private final MyMapper myMapper;

public MyAggregateMapperImpl(MyMapper myMapper) {
    this.myMapper = myMapper;
}

但手写的Java表达式中直接写myMapper时,在生成的代码里没有明确的上下文引用(MapStruct不会自动补全this.),所以编译器会认为myMapper是局部变量而找不到它,加上this.就能明确引用实例变量了。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 11:14:27