2015-03-27 2 views
9

Welcher Ansatz erfordert die geringste Menge an eigenem geschriebenen Code, um eine tiefe Kopie einer Bohne zu einer anderen zu erreichen? Das Ziel besteht darin, dies automatisch zu tun, wenn die Quell- und Zieleigenschaften mit dem Namen übereinstimmen.Kopieren von Eigenschaften von einer Bean in eine andere (nicht die gleiche Klasse) rekursiv (einschließlich verschachtelte Beans)

Quelle Haupt bean:

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

    // getters and setters 
} 

Quelle geschachtelt bean:

public class SourceNestedBean { 
    private String nestedBeanField; 

    // getters and setters 
} 

Zielhaupt bean:

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

    // getters and setters   
} 

Ziel geschachtelt bean:

public class TargetNestedBean { 
    private String nestedBeanField; 

    // getters and setters 
} 


Verwendung von z.B. Spring BeanUtils.copyProperites() Ich könnte eine flache Kopie von SourceBean zu TargetBean mit einer Zeile Code erstellen, aber es wird nicht verschachtelte Bohnen kopieren. Gibt es ein ausgereiftes Dienstprogramm (nicht notwendigerweise Spring Framework), das es erlauben würde, die tiefe Kopie zu machen, während Schreiben mindestens so eigenen Code wie möglich (so ziemlich wie BeanUtils.copyProperties())?

+0

Verwenden Sie * Serialisierung * zu tun * tiefe Kopie * – TheLostMind

+1

@TheLostMind Ich denke, das funktioniert nur, wenn sie der gleichen Klasse sind. – RealSkeptic

+0

@ M.Deinum nicht ganz.Die Frage, die du erwähnst, ist eine generische (Beans Mapping), während was ich brauche ist das Klonen 'nach archivierten Namen' in einer sehr einfachen Art und Weise mit der geringsten Menge an Setup-Code möglich –

Antwort

11

Eine Möglichkeit, es zu tun mit Jackson ObjectMapper ist, über die convertValue() method:

ObjectMapper mapper = new ObjectMapper(); 
SourceBean source = ...; 
TargetBean target = mapper.convertValue(source, TargetBean.class); 

Beachten Sie, dass convertValue() auch mit generischen Typen überlastet zu arbeiten. Beachten Sie auch, dass convertValue() unter bestimmten Umständen den von Ihnen angegebenen Wert zurückgibt, z. B. wenn SourceBean TargetBean zuweisbar ist.

Als Jackson eine JSON-Serialisierung/Deserialisierung Bibliothek ist, was convertValue() tut, ist source im Speicher zu JSON serialisiert und dann Deserialisieren dieses JSON in eine Instanz von TargetBean. So hohe Leistung ist nicht zu erwarten. Die Konvertierung wird jedoch mit einer einzelnen Codezeile ausgeführt.

Wenn Sie Leistung benötigen, sollten Sie das Mapping manuell durchführen. Nichts wird besser sein.

Wenn Sie Einfachheit benötigen, verwenden Sie Jackson wie oben beschrieben.

Ein guter Kompromiss ist Orika, ein Hochleistungs-Mapper mit fast keiner Konfiguration, die keine Reflexion verwendet.

+0

Ich nehme an, dass könnte als Antwort akzeptiert werden, obwohl ich noch nicht sicher bin, ob ich es in der Produktion wegen möglicher Leistungsprobleme verwenden werde. –

+0

@SergeyPauk die einzige Sache, die ich antworten kann, ist, dass Sie einige Benchmark ausführen sollten und sehen, ob Zeiten für Sie angemessen sind. –

0

Wenn Sie Deep Copy in Java verwenden möchten, sollten Sie ObjectOutputStream und ObjectInputStream verwenden und alle Klassen, die Sie kopieren müssen, sollten Serializable implementieren.

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(); 
} 
+0

Quelle ant Zielobjekte sind von verschiedenen Klassen –

-1

Verwenden Sie SerializationUtils von Apache Commons-lang. Und machen Sie Ihr Objekt serialisierbar.

+0

Quelle ant Zielobjekte sind von verschiedenen Klassen –

2

Sie können Dozer Mapper verwenden, um tief zu kopieren. Siehe http://dozer.sourceforge.net/documentation/deepmapping.html

+0

Ist es möglich, Dozer w/o XML-Konfiguration zu verwenden und ist es möglich, eine Map-by-Name-Strategie zu definieren, weil ich nicht will bestimmte Zuordnungen manuell definieren? –

+0

Sie können stattdessen API-Mappings verwenden: http://dozer.sourceforge.net/documentation/apimappings.html. Ich denke, es wird nicht schwer sein, eine gemeinsame Hilfsmethode zu schreiben, um Ihre Objekte zu kopieren. –

+0

Ja, dieser verwendet nicht XML, aber ich muss immer noch die Felder definieren, die kopiert werden sollen, also nehme ich an, dass Dutzende von Beans keine Option sind. –

Verwandte Themen