MapStruct已定义映射方法无法调用复用问题咨询
MapStruct跨Mapper映射方法复用问题解决方案
核心原因:你当前手写实现的toStorage属于自定义业务逻辑,MapStruct的uses配置默认只作用于框架自动生成的映射方法,不会自动给你自定义方法注入依赖的Mapper实例。
方案1:手动注入依赖Mapper直接调用(适配手写逻辑场景)
- 首先确认
@Mapper注解指定了componentModel = "spring"(Spring管理场景为最常用场景),同时保留uses配置:
@Mapper( componentModel = "spring", uses = [LocationMapper::class, ResourceMapper::class] ) abstract class StorageMapper { // 声明依赖Mapper,Spring会自动注入实例 @Autowired protected lateinit var locationMapper: LocationMapper @Autowired protected lateinit var resourceMapper: ResourceMapper fun toStorage(storage: StorageDao): Storage { return if (storage.container == null) { // 直接调用LocationMapper中已定义的@Named("toLocation")方法,无需重复声明 locationMapper.toLocation(storage.location!!) } else { resourceMapper.toContainerStorage(storage.container!!) } } }
- 注意检查
@Named注解的包路径,必须导入org.mapstruct.Named,不要误用JSR-330或Jakarta的同名注解。
方案2:改为自动生成映射方法,复用@Named标注的逻辑
如果你不想手动维护注入逻辑,可以把分支判断交给MapStruct处理,无需手写toStorage方法体:
@Mapper( componentModel = "spring", uses = [LocationMapper::class, ResourceMapper::class] ) abstract class StorageMapper { // 容器为空时用location字段映射,调用@Named("toLocation")方法 @Mapping( target = ".", source = "location", qualifiedByName = ["toLocation"], conditionExpression = "java(storage.getContainer() == null)" ) // 容器不为空时用container字段映射,调用对应映射方法 @Mapping( target = ".", source = "container", qualifiedByName = ["toContainerStorage"], conditionExpression = "java(storage.getContainer() != null)" ) abstract fun toStorage(storage: StorageDao): Storage }
- 该方案下无需手动注入Mapper,MapStruct会自动关联
uses中标记了@Named的对应方法。
其他排查点
- 确认依赖的Mapper也配置了相同的
componentModel,否则实例无法被正常注入 - 清理项目编译缓存后重新构建,MapStruct的注解处理器可能因为缓存未生成最新的实现类
内容的提问来源于stack exchange,提问作者Petr Jelínek
相关产品推荐
相关产品推荐

