You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 23:06:02