以递归方式将属性从一个bean复制到另一个bean(不是同一个类)(包括嵌套bean)

时间:2015-03-27 09:38:55

标签: java spring javabeans spring-bean

哪种方法需要最少量的自己编写的代码才能实现一个bean到另一个bean的深层复制?目标是在源名称和目标属性按名称匹配时以自动方式执行此操作。

源主bean:

public class SourceBean {
    private String beanField;
    private SourceNestedBean nestedBean;

    // getters and setters
}

源嵌套bean:

public class SourceNestedBean {
    private String nestedBeanField;

    // getters and setters
}

目标主bean:

public class TargetBean {
    private String beanField;
    private TargetNestedBean nestedBean;

    // getters and setters        
}

目标嵌套bean:

public class TargetNestedBean {
    private String nestedBeanField;

    // getters and setters
}


使用例如Spring BeanUtils.copyProperites()我可以使用一行代码创建SourceBeanTargetBean的浅表副本,但不会复制嵌套的bean。是否有任何成熟的实用程序(不一定是Spring Framework)允许执行深层复制,而编写尽可能少的自己的代码(与BeanUtils.copyProperties()几乎相同)?

4 个答案:

答案 0 :(得分:12)

通过Jackson ObjectMapper

,可以使用convertValue() method
ObjectMapper mapper = new ObjectMapper();
SourceBean source = ...;
TargetBean target = mapper.convertValue(source, TargetBean.class);

请注意convertValue()已重载以使用泛型类型。还要注意convertValue()在某些情况下会返回您提供的值,例如SourceBean是否可以赋值给TargetBean。

由于Jackson是一个JSON序列化/反序列化库,convertValue()所做的是将source序列化为内存中的JSON,然后将此JSON反序列化为TargetBean的实例。所以不能期待高性能。但是,使用一行代码执行转换。

如果您需要性能,最好是手动进行映射。没有比这更好的了。

如果您需要简单,请按照上面的说明使用Jackson。

一个很好的权衡是Orika,一个高性能的映射器,几乎没有配置不使用反射。

答案 1 :(得分:3)

您可以使用Dozer Mapper进行深度复制。见http://dozer.sourceforge.net/documentation/deepmapping.html

答案 2 :(得分:0)

如果你想在Java中使用深层复制,你应该使用ObjectOutputStream和ObjectInputStream,你需要复制的所有类都应该实现Serializable。

public Object deepCopy() throws IOException, ClassNotFoundException{
    //store object in memory using serial
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(this);
    ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(bis);
    return ois.readObject();
}

答案 3 :(得分:-1)

使用apache commons-lang中的SerializationUtils。并使您的对象可序列化。