如何在MapStruct的MapperA默认方法中使用自定义MapperB?
在MapStruct的Mapper默认方法中使用另一个独立Mapper的正确方式
问题根源
你直接在MapperA接口中声明@Autowired MapperB mapperB的写法存在两个核心问题:
- Java接口语法限制:接口中的字段默认是
public static final,必须初始化,所以IDE会提示「变量未初始化」的警告,且这种写法本身不符合接口的设计规范。 - MapStruct机制不支持:MapStruct只会生成接口的实现类,不会处理接口中定义的
@Autowired字段,运行时会导致NullPointerException。
正确解决方案
利用MapStruct的uses属性声明Mapper依赖,并通过Spring组件模型实现自动注入,步骤如下:
1. 配置MapperB的Spring组件模型
给MapperB添加componentModel = "spring",让MapStruct生成的实现类被Spring管理:
@Mapper(componentModel = "spring") public interface MapperB { AudioDto audioToAudioDto(Audio audio, ApplicationUser loggedInUser); }
2. 配置MapperA依赖MapperB并声明获取方法
在MapperA中通过uses属性指定依赖的MapperB,同时声明一个获取MapperB的方法,MapStruct会自动在实现类中实现该方法并返回注入的实例:
@Mapper(componentModel = "spring", uses = MapperB.class) public interface MapperA { default ArrayList<AudioDto> audiosToDto(List<Audio> audios, ApplicationUser loggedInUser) { return audios.stream() .map(audio -> getMapperB().audioToAudioDto(audio, loggedInUser)) .collect(Collectors.toCollection(ArrayList::new)); } // MapStruct自动实现此方法,返回Spring注入的MapperB实例 MapperB getMapperB(); }
关键说明
- 无需手动给Mapper接口添加
@Component注解,componentModel = "spring"会让MapStruct自动在生成的实现类上添加该注解。 - 执行
mvn clean install后,MapStruct会生成MapperAImpl类,其中会自动注入MapperB实例,并实现getMapperB()方法。 - 这种方式既符合Java语法规范,又遵循了MapStruct的设计机制,同时避免了不推荐的字段注入。
内容的提问来源于stack exchange,提问作者Felix Olszewski
相关产品推荐
相关产品推荐

