Spring Boot中如何用Mapstruct读取自定义yml映射值完成对象转换?
你遇到的NullPointerException本质是2种常见问题导致的,按优先级排查即可解决:
1. 最高频错误:Mapper实例获取方式错误
如果你的项目中使用componentModel = "spring"声明Mapstruct映射器,绝对不能手动调用Mappers.getMapper(AddressMapper.class)获取实例,这种方式生成的Mapper不受Spring容器管理,@Autowired注入的字段不会被赋值,自然为null。
正确方式是在需要使用Mapper的类(比如Service、Controller)中,通过@Autowired注入AddressMapper实例:
@Service public class AddressService { // 正确:由Spring注入受管的Mapper实例 @Autowired private AddressMapper addressMapper; }
2. 修正映射器字段访问权限
你当前声明的AddressProperties addressProperties没有显式加访问修饰符,默认是包访问权限,部分场景下Mapstruct生成的实现类无法正确读取父类的注入字段,修改为protected即可,优先使用@AfterMapping的方案实现扩展逻辑,避免Java表达式拼写错误引发的编译/运行时异常:
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) public abstract class AddressMapper { // 改为protected权限,保证生成的子类实现可以访问 @Autowired protected AddressProperties addressProperties; abstract Address codeToName(AddressDTO addressDTO); @AfterMapping public void populateNames(@MappingTarget Address address, AddressDTO addressDTO){ address.setCityName(addressProperties.getCity().get(addressDTO.getCityCode())); } }
3. 修正AddressProperties配置(可选,避免配置加载异常)
你当前的AddressProperties写法有不规范的地方,虽然你说Service层可以读取,但仍建议修正避免隐藏问题:
- 移除
@Builder注解:@ConfigurationProperties类需要无参构造函数完成属性绑定,@Builder默认会覆盖无参构造,容易导致实例化失败 - 移除
@Value注入:@ConfigurationProperties本身支持直接绑定配置字段,不需要额外加@Value - 增加
prefix属性:规范配置绑定的前缀,避免和其他配置冲突
修正后的代码:
@Data @NoArgsConstructor @AllArgsConstructor @Configuration @ConfigurationProperties(prefix = "") @PropertySource(value = "classpath:address.yml", factory = YamlPropertySourceFactory.class) public class AddressProperties { private Map<String, String> city; }
同时建议在启动类上增加@EnableConfigurationProperties(AddressProperties.class),显式注册配置类,保证配置在Mapper初始化前已经加载完成。
内容的提问来源于stack exchange,提问作者Arpit
相关产品推荐
相关产品推荐

