Mapstruct是否支持映射包私有属性(不使用Lombok)
Mapstruct无需public getter/setter映射包私有类属性的实现方案
方案1:字段访问策略(Mapstruct 1.4+ 推荐)
Mapstruct 1.4及以上版本原生支持直接访问类字段完成映射,不需要依赖getter/setter方法,配置步骤如下:
- 全局配置(可选):在编译插件的Mapstruct处理器参数中添加默认访问类型:
<!-- 以Maven为例 --> <compilerArgs> <arg>-Amapstruct.defaultAccessType=FIELD</arg> </compilerArgs> - 单个Mapper配置:在Mapper接口的
@Mapper注解中指定访问类型:@Mapper(access = AccessType.FIELD, componentModel = "spring") public interface SourceMapper { // 你的映射方法 } - 包权限适配:将定义的Mapper接口放在和包私有源类相同的包路径下,生成的Mapper实现类即可直接访问源类的包私有字段,不需要任何getter/setter方法。
方案2:包级访问权限的getter/setter(兼容低版本Mapstruct)
不需要将getter/setter设置为public,只要设置为包私有即可满足映射要求:
- 手写方法时省略访问修饰符(Java默认访问权限为包私有)
- 使用Lombok时直接给类添加注解:
@Getter @Setter(AccessLevel.PACKAGE)
只要Mapper和源类同包,Mapstruct就能正常调用这些非public的getter/setter完成映射,不会对外暴露类的属性方法。
方案3:自定义反射映射方法
如果无法将Mapper和源类放在同包,可以在Mapper中写默认方法通过反射直接操作属性:
@Mapper public interface SourceMapper { SourceMapper INSTANCE = Mappers.getMapper(SourceMapper.class); default TargetDto sourceToDto(SourceClass source) throws NoSuchFieldException, IllegalAccessException { if (source == null) { return null; } TargetDto dto = new TargetDto(); // 反射读取源类字段 Field nameField = SourceClass.class.getDeclaredField("name"); nameField.setAccessible(true); dto.setName((String) nameField.get(source)); // 其他字段映射逻辑同理 return dto; } }
注意事项
- 使用字段访问策略时,字段不能被static、final修饰,否则Mapstruct无法完成写入操作
- 采用Spring等组件模型时,Mapper实现类的包路径与定义的Mapper接口路径完全一致,只要保证接口与源类同包即可,不需要额外调整实现类位置
内容的提问来源于stack exchange,提问作者Silaghi Alexandru-Mihail
相关产品推荐
相关产品推荐

