現在有個復雜對象bean需要在賦值后在另一個地方用,想通過復制的方式拿到這個對象。首選是深度克隆,雖然發現該對象的父類已經實現了Cloneable接口,但父類是通過jar包引入的,而且在clone方法中對該bean一個map<String, Object>屬性的處理有問題:獲取到map的value時,直接強制轉型為某一具體bean,而子類這個map在put時並非該具體bean的類型,因此克隆時報轉型失敗錯誤。考慮方案二,通過java序列化方式克隆,父類也已經實現了Serializable接口,但寫對象和度對象方法都是空實現,本地重新實現后也報錯了。使用json序列化倒是可以,就是性能不高。最后決定采用Dozer框架,Dozer底層也是apache的beanUtils方式復制bean,但更易用,可以直接用xml文件或者注解映射兩個類,類可以是不同類型,字段也可以是不同類型、不同名稱。
使用前需要導入5個jar包:
commons-beanutils-1.9.3.jar
commons-lang3-3.5.jar
commons-logging-1.2.jar
dozer-5.4.0.jar
slf4j-api-1.7.25.jar
這里通過注解來實現一個例子,具體使用參見下面代碼:
package com.wulinfeng.dozer; import java.util.Date; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; public class CopyComponent { private String name; private int age; private Date date; private Map<String, String> internalMap; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public Map<String, String> getInternalMap() { return internalMap; } public void setInternalMap(Map<String, String> internalMap) { this.internalMap = internalMap; } @Override public String toString() { StringBuilder names = new StringBuilder(); if (null != internalMap && internalMap.entrySet() != null) { Iterator<Entry<String, String>> iter = internalMap.entrySet().iterator(); while (iter.hasNext()) { Entry<String, String> c = iter.next(); names.append("key: "); names.append(c.getKey()); names.append("value: "); names.append(c.getValue()); } } return "name: " + name + ", age: " + age + ", date: " + date + ", list : " + names.toString(); } }
package com.wulinfeng.dozer; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.dozer.DozerBeanMapper; import org.dozer.Mapping; public class Component { @Mapping("age") private String desc; @Mapping("name") private Integer price; private Date date; @Mapping("internalMap") private Map<String, String> externalAttrMap; public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public Map<String, String> getExternalAttrMap() { return externalAttrMap; } public void setExternalAttrMap(Map<String, String> externalAttrMap) { this.externalAttrMap = externalAttrMap; } public static void main(String[] args) { Component component = new Component(); // String -> int component.setDesc("9999"); // int -> String component.setPrice(30); // date -> date component.setDate(new Date()); // Map -> List Component componentpage = new Component(); componentpage.setDesc("hello"); Map<String, String> ext = new HashMap<String, String>(); ext.put("name", "fengjiangtao"); component.setExternalAttrMap(ext); DozerBeanMapper dozerBeanMapper = new DozerBeanMapper(); CopyComponent copy = dozerBeanMapper.map(component, CopyComponent.class); System.out.println(copy); } }
運行結果:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. name: 30, age: 9999, date: Sun Apr 23 23:06:02 CST 2017, list : key: namevalue: fengjiangtao