最近使用惟品會的vjtools的BeanMapper進行對象的深度克隆轉換DTO/VO這種操做,Spring Boot的dev-tools熱啓動,須要把vjtools和dozer包都放到spring-devtools.properties的incloud裏面,不然會出現強轉失敗的問題,緣由是dev-tools的熱啓動使用的是restartClassLoader。spring
若是隻把vjtools加到spring-devtools.properties內,對於通常的克隆都沒問題,可是對於以下狀況,List內的元素會使用AppClassCloader加載:app
@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環境中測試。測試