使用 Lombok 的 @Accessors(chain=true) 的注意事项

前言

  • 大家在日常开发中想必都有使用过 Lombok 的 @Accessors(chain=true) 注解吧,这个确实有时候会让我们的get/set方法变的非常的便捷,但是从中又隐藏了一些注意细节,我们一起来看看。

注解介绍

@Accessors(chain=true)

  • 在我们的实体类或者对象中加入了该注解设置 chain=true,这样我们就可以进行链条式调用参数了。生成setter方法返回this(也就是返回的是对象),代替了默认的返回 void
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class User {
    private Integer id;
    private String name;
    private Integer age;

    // 生成的setter方法如下,方法体略
    public User setId(Integer id) {}
    public User setName(String name) {}
    public User setAge(Integer age) {}
    public static void main(String[] args) {
        //开起chain=true后可以使用链式的set
        User user = new User().setAge(31).setName("pollyduan");//返回对象
        System.out.println(user);
    }
}

@Accessors(fluent = true)

  • 与 chain=true 类似,区别在于 getter 和 setter 不带 set 和 get 前缀
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(fluent = true)
public class User {
    private Integer id;
    private String name;
    private Integer age;

    // 生成的getter和setter方法如下,方法体略
    public Integer id() {}
    public User id(Integer id) {}
    public String name() {}
    public User name(String name) {}
    public Integer age() {}
    public User age(Integer age) {}
    public static void main(String[] args) {
        //fluent=true开启后默认chain=true,故这里也可以使用链式set
        User user = new User().age(31).name("pollyduan");//不需要写set
        System.out.println(user);
    }
}

@Accessors(prefix = " f ")

  • prefix 的中文含义是前缀,用于生成 getter 和 setter 方法的字段名会忽视指定前缀(遵守驼峰命名)
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(prefix = "p")
public class User {
    private Integer pId;
    private String pName;

    // 生成的getter和setter方法如下,方法体略
    public Integer getId() {}
    public void setId(Integer id) {}
    public String getName() {}
    public void setName(String name) {}
}

对象之间的属性复制问题

		//测试使用Lombok的@Accessors(chain=true)后cglib无法复制属性问题
        ConfComponent component = new ConfComponent();
        component.setComponentCode("01").setComponentName("哈哈");

        ConfComponent c2  = new ConfComponent();
        BeanUtils.copyProperties(component,c2);
        System.out.println("spring自带属性复制:"+c2.getComponentCode()+"====="+c2.getComponentName());

        ConfComponent c3 = new ConfComponent();
        BeanUtil.copyProperties(component,c3);
        System.out.println("hutool自带:"+c3.getComponentCode()+"====="+c3.getComponentName());

        //测试使用 @Accessors(chain=true)注解的对象和不使用这个注解的对象是否可以进行属性复制
        com.dcsoft.riverlake.inspection.work.api.model.entity.A a = new com.dcsoft.riverlake.inspection.work.api.model.entity.A();
        BeanUtils.copyProperties(component,a);
        System.out.println("使用@Accessors(chain=true)注解和没使用注解对象之间的属性复制:"+a.getComponentCode()+"========="+a.getComponentName());


        //CglibUtil测试:测试结果:无法复制进去
        ConfComponent c4  = CglibUtil.copy(component,ConfComponent.class);
        System.out.println("CglibUtil测试:"+c4.getComponentCode()+"========"+c4.getComponentName());

测试结果

  • 通过测试我们可以看出,使用 @Accessors(chain=true) 注解后,除了使用 CglibUtil 工具类后无法复制成功,其他都是没有问题的
    在这里插入图片描述

结论

  • 由于 @Accessors(chain=true) 导致 set 方法返回是 this(也就是返回的是对象)而 cglib 只获取返回值是 void 类型的 set 方法,所以出现了这个问题
  • 所以我们在使用的过程中尽量使用:BeanUtil.copyProperties或者org.springframework.beans.BeanUtils.copyProperties(source, target) 这两个方法即可避免这个问题
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值