最近使用唯品会的vjtools的BeanMapper进行对象的深度克隆转换DTO/VO这种操作,Spring Boot的dev-tools热启动,需要把vjtools和dozer包都放到spring-devtools.properties的incloud里面,否则会出现强转失败的问题,原因是dev-tools的热启动使用的是restartClassLoader。
如果只把vjtools加到spring-devtools.properties内,对于一般的克隆都没问题,但是对于如下情况,List内的元素会使用AppClassCloader加载:
@Data
public class A {
private Long id;
private List<Cc> cc;
}
@Data
public class B {
private Long id;
private List<Cc> cc;
}
public class Dd {
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class Cc {
private String name;
}
}
public class CloneTest {
@Test
public void test1() {
A a = new A();
a.setId(100L);
List<Cc> list = new ArrayList<>();
list.add(Cc.builder().name("w.dehai").build());
a.setCc(list);
Object b = BeanMapper.map(a, B.class);
System.err.println("原始B类加载器:" + B.class.getClassLoader());
System.err.println("map之后获得的B类加载器:" + b.getClass().getClassLoader());
B bb = BeanMapper.map(a, B.class);
Object m = bb.getCc().get(0);
System.err.println(m.getClass().getClassLoader()); // 这里会输出AppClassLoader
}
}
含有静态内部类的List中的元素经过克隆之后会使用AppClassLoader加载,导致报错。所以需要把vjtools和dozer这2个jar包都加到spring-devtools.properties内。
说明:上面代码只是单元测试实例代码,无法重现热加载,如果需要测试,需要在Spring Boot环境中测试。
来源:oschina
链接:https://my.oschina.net/u/4366482/blog/3543920