MapStruct类型转换接口未自动注入到spring容器中
MapStruct类型转换接口未自动注入到spring容器中
- 引
- 依赖
- assembler接口
- 启动报错
- compiler插件
引
MapStruct 是一个属性映射的注解处理器,适用于复杂系统(如分布式、微服务架构)的 POJO 类数据转换,尤其适合处理嵌套对象、集合映射等场景。与BeanUtils采用反射方式复制对象属性的方式不同,MapSturct通过编译时生成类型安全的映射代码,减少手动编写转换逻辑的需求,效率更优。
依赖
推荐使用1.5+版本
<dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>1.5.3.Final</version>
</dependency>
assembler接口
这里只需要定义一个assembler 对象转换接口,将不同的属性显式声明出来。这里注意接口上的注解@Mapper
添加了componentModel = "spring"
属性,这是自动注入为spring容器bean的前提。
@Mapper(componentModel = "spring")
public interface UserLoginAssembler {@Mappings({@Mapping(source = "userName", target = "accountNumber"),@Mapping(source = "userPwd", target = "password"),@Mapping(source = "loginType", target = "loginType", defaultValue = "USER_LOGIN_ACCOUNT")})UserLoginCommand loginRequestConvert(UserLoginAdapterRepDTO userLoginAdapterRepDTO);
}
正常情况下,项目编译后,在assembler接口的同目录下会自动生成实现类文件,并且类标注了@Component注解。
启动报错
然而,事与愿违,服务启动时报错找不到assembler容器bean。
Parameter 6 of constructor in xxx.xxxService required a bean of type 'xxx.WorkflowAssembler' that could not be found.
折腾了一番,检查了依赖版本和lombok是否冲突,依赖注入等可能问题,均为有效处理。
compiler插件
前面提到,MapStruct实现原理是在编译时动态生成类型转换的实现方法,这里还需要在对应module的pom文件中显式声明maven-compiler-plugin的annotationProcessorPaths属性。
<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target><annotationProcessorPaths><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></path><path><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>${mapstruct.version}</version></path></annotationProcessorPaths></configuration></plugin></plugins></build>
最后还有提醒一下,如果你的项目是多个module,在主启动模块的pom中声明annotationProcessorPaths
并不能贯通到所有依赖的模块中。比如在DDD的application层我们使用了MapStruct接口,就需要在这个module的pom文件中添加这个配置,仅在interface层添加后编译,实测无效。重点都可以在module编译后检查assembler接口是否自动编译生成了实现类。