别再写 setter 了!MapStruct Plus vs MapStruct,谁才是 Bean 转换的真神?

01 引言

日常开发中,我们经常会遇到对象转化的问题。尤其阿里提出了DTO、BO、VO、PO的概念之后,对于转化的场景更多。

转化的工具也不少,BeanUtilsMapStructOrika等工具层出不穷,每个人或者团队的选择也大不相同。

02 三大流派

Java 生态里"对象转对象"这件事大致分为桑哥流派。

2.1 手写派

new 一个对象,然后 setter 挨个赋值。这个是最简单,最常用的手段。但是字段多的话,就会角色很繁琐。

UserDTO dto = new UserDTO();
dto.setId(user.getId());
dto.setName(user.getName());
dto.setAge(user.getAge());
dto.setEmail(user.getEmail());
dto.setPhone(user.getPhone());
dto.setCreateTime(user.getCreateTime());
// ... 30 行 setter
return dto;

但是,AI时代,AI提示工具会帮我们直接联想关联,也省了不少功夫,但是代码量不会变。

优缺点:

  • 优点:性能拉满,可读性尚可。
  • 缺点:字段超过 10 个就开始怀疑人生,字段名修改需要联动修改。

2.2 反射派

反射的工具类代表:Spring BeanUtilsApache Commons BeanUtilsHutool BeanUtil

BeanUtils.copyProperties(source, target);

使用工具类是最省事情的,但是不同的工具参数以及最终的结构都少有差异。如果字段的类型不一致,还可能出现转化失败。最关键的,性能也是最差的。

优缺点:

  • 优点:一行代码搞定,懒人福音。
  • 缺点:运行时反射,性能是硬伤;还不做类型检查,int 字段和 String 字段同名也能给你"成功"转过去——数据错了你都不知道怎么错的。

2.3 编译期生成派

代表:MapStructMapStruct Plus

就是在在你 javac 编译的时候,APT(注解处理器)自动生成转换代码,运行时压根没反射。运行效果同Setter方法。

这也是今天我们要介绍的重点工具。

03 MapStruct

3.1 简介

MapStruct 是 Java 圈做 Bean 映射的事实标准,Apache-2.0 协议,GitHub 上7.7k颗 star,背后有一整个组织在维护。最新稳定版 1.6.3

官网:https://mapstruct.org

GitHub地址:https://github.com/mapstruct/mapstruct

3.2 使用

使用也是非常简单。

Maven依赖

...
<properties>
    <org.mapstruct.version>1.6.3</org.mapstruct.version>
</properties>
...
<dependencies>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>${org.mapstruct.version}</version>
    </dependency>
</dependencies>
...
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>${org.mapstruct.version}</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>
...

定义转化接口

@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
public interface UserMapper {

    UserVO userDtoToVO(UserDTO userDto);
}

这里使用Spring实例模式,定义的方法上可以通过@Mapping(target = "a", source = "b")定制处理不同的字段的映射。

maven 配置annotation processor,编译的时候它就给你生成一个 UserMapperImpl.java,里面全是规规矩矩的 target.setXxx(source.getXxx())

调用

3.3 缺点

这玩意儿最大的问题:烦。

每对类型转换,你都要写一个 @Mapper 接口。如果你项目里 50 个 DTO,那就是 50 个 Converter 类。直接类爆炸!

04 MapStruct Plus

国产"外挂"来了,顾名思义就是MapStruct的加强版。

4.1 简介

Mapstruct Plus 是 Mapstruct 的增强工具,在 Mapstruct 的基础上,实现了自动生成 Mapper 接口的功能,并强化了部分功能,使 Java 类型转换更加便捷、优雅。

可能是最简单最强大的Java Bean转换工具。

Mapstruct Plus所解决的痛点正式取消了定义转化的接口,取而代之的是注解。

官网地址:https://www.mapstruct.plus/

GitHub地址:https://github.com/linpeilie/mapstruct-plus

4.2 使用

Maven依赖

<properties>
    <mapstruct-plus.version>latest version</mapstruct-plus.version>
</properties>
<dependencies>
    <dependency>
        <groupId>io.github.linpeilie</groupId>
        <artifactId>mapstruct-plus-spring-boot-starter</artifactId>
        <version>${mapstruct-plus.version}</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <annotationProcessorPaths>
                    <path>
                        <groupId>io.github.linpeilie</groupId>
                        <artifactId>mapstruct-plus-processor</artifactId>
                        <version>${mapstruct-plus.version}</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

定义实体

@Data
@AllArgsConstructor
@NoArgsConstructor
@AutoMapper(target = UserVO.class)
public class UserDTO {
    /**  用户ID */
    private Integer id;
    /**  用户名 */
    private String name;
    /**  出生日期 */
    private Date birthday;
    /**  电话号码 */
    private String phone;
}

这里面最关键注解是@AutoMapper(target = UserVO.class)

调用

就这么简单,一个注解就是实现相互的转化。我们看看为什么,原来是编译的时候,生成相互转化的实现类。

4.3 优点

  • 零接口、零模板——这是核心卖点,CRUD 业务写起来像飞一样。
  • 底层依然是 MapStruct——编译期生成、零反射、类型安全,全部继承。
  • 双向转换自动生成——A→B 和 B→A 都给你生成好,不用写两份。
  • 中英文双文档——这点对国内开发者是真香,作者中文母语,文档写得比 MapStruct 官方还接地气

4.4 缺点

既然是其他工具的增强类,必然依赖者MapStruct

  • 社区体量小——Issue/Discussion 数量远不如 MapStruct,遇冷门问题得自己扒源码。
  • 版本耦合底层——MapStruct 大版本升级,Plus 得跟着更,存在一定不确定性。
  • 复杂自定义场景灵活性略弱——比如 expression、Decorator、SPI 这些高级玩法,Plus 还在追赶原版

05 Bean 转换工具合集

整理一下常用的转化工具:

5.1 编译期派

  • MapStruct:业界标杆,权威。
  • MapStruct Plus:MapStruct 的"懒人版",国内首选。
  • Selma / JMapper:历史方案,已不活跃,不推荐。

5.2 反射派

  • Spring BeanUtils:Spring 自带,单测和小工具用用就好,线上大对象别上
  • Apache Commons BeanUtils:慢到能让你怀疑人生,不推荐
  • Hutool BeanUtil:国内工具包,国产项目首选,但本质还是反射
  • Dozer:XML 配置映射,曾经火过,现在基本凉凉
  • Orika:基于字节码生成,比反射快,比编译期慢,不上不下

5.3 字节码派

  • Cglib BeanCopier:阿里、美团内部爱用,首次创建后缓存,性能接近手写
  • ByteBuddy:现代化方案,Spring 自己也用。

06 小结

选工具不是选最强的,是选最适合的。每一种工具都存在其必要的使用场景,复杂业务永远离不开手写的作为兜底。

企业创新活动具有投入周期长、不确定性高和收益实现滞后等特征,持续稳定的资源支持是保障企业长期创新的重要基础。耐心资本作为一种强调长期价值创造、具备较高风险容忍度并积极参与企业治理的资本形态,能够通过缓解融资约束、优化公司治理结构以及增强企业风险承担能力,为企业持续开展创新活动提供长期稳定支持 本文基于2010—2024年中国A股上市公司样本数据,借鉴《耐心资本对企业持续性创新投入的影响研究》一文中的基准回归设计思路和研究方法,围绕“耐心资本是否能够促进企业持续性创新投入”这一问题展开基准回归实证检验,基准回归结果显示,耐心资本能显著促进企业持续性创新,数据集含原始数据、处理代码、基准回归实证结果 关键指标构建: 1.耐心资本:本文从稳定型股权和关系型债权两个维度刻画企业耐心资本水平,并采用熵权法对两个指标进行加权整合,构建综合耐心资本指数。其中,稳定型股权参考温磊和李思飞(2024)的研究,以长期机构投资者持股比例作为衡量指标;关系型债权参考吴旻佳(2022)、姜中裕(2024)的研究,采用上市公司长期负债占负债总额的比例衡量 2.企业持续性创新:基于研发投入三期动态变化构建,借鉴何郁冰(2017)、杨仁发(2025)的研究思路,计算第t-1至t年研发投入之和与第t-2至t-1年研发投入之和的比值,再将该比值乘以第t-1至t年研发投入之和,以此反映企业在创新投入上的持续性特征 相关数据:上市公司耐心资本数据,上市公司耐心资本投资数据,上市公司研发投入与专利数据 一、数据介绍 数据名称:耐心资本对企业持续性创新投入的影响研究 数据范围:上市公司企业 时间范围:2010-2024年 样本数量:31725条 数据来源:上市公司年报 数据说明:含原始数据、处理过程dofile文件、基准回归结果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智_永无止境

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值