前言
大家在日常开发中想必都有使用过 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;
public User setId ( Integer id) { }
public User setName ( String name) { }
public User setAge ( Integer age) { }
public static void main ( String [ ] args) {
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;
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) {
User user = new User ( ) . age ( 31 ) . name ( "pollyduan" ) ;
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;
public Integer getId ( ) { }
public void setId ( Integer id) { }
public String getName ( ) { }
public void setName ( String name) { }
}
对象之间的属性复制问题
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 ( ) ) ;
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 ( ) ) ;
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) 这两个方法即可避免这个问题