MapStruct生成的Mapper未调用父类构造函数的解决方法
MapStruct装饰器构造注入编译失败问题解决
问题原因
你遇到的编译失败,核心原因有两个可能:
- 装饰器类错误添加了@Component注解:MapStruct在处理
@DecoratedWith时,会自动生成继承装饰器的实现类并交由Spring管理。如果装饰器本身标记为@Component,Spring会尝试直接实例化抽象类,同时MapStruct生成的实现类无法正确传递构造参数给父类,导致编译报错。 - MapStruct版本过低:1.3.1.Final之前的版本不支持装饰器的构造函数注入,升级到该版本及以上才能正常使用构造注入逻辑。
解决方案
方案1:移除装饰器的@Component注解(推荐)
这是MapStruct官方示例的标准用法,移除@Component后,MapStruct生成的实现类会自动处理delegate的构造注入,调用父类构造函数。
修改后的装饰器代码:
@RequiredArgsConstructor public abstract class CardMapperDecorator implements CardMapper { private final CardMapper delegate; }
Mapper接口保持不变:
@Mapper(componentModel = "spring") @DecoratedWith(CardMapperDecorator.class) public interface CardMapper { }
方案2:保留@Component(需注入其他Spring Bean时)
如果装饰器需要注入其他Spring组件(如Service),可以保留@Component,但需确保:
- MapStruct版本≥1.3.1.Final
- 装饰器的构造函数显式添加
@Autowired(Spring 4.3+虽支持隐式注入,但显式声明更稳妥)
示例代码:
@Component @RequiredArgsConstructor public abstract class CardMapperDecorator implements CardMapper { private final CardMapper delegate; private final SomeService someService; // 额外注入的Spring Bean }
此时MapStruct会生成实现类,自动将delegate和其他Bean注入到父类构造函数中。
关于文档示例的说明
官方示例中构造注入有效,是因为示例里的装饰器没有标记@Component,完全由MapStruct生成的实现类接管Spring组件管理,自然能正确传递构造参数给父类。
内容的提问来源于stack exchange,提问作者Sergey Zolotarev
相关产品推荐
相关产品推荐

