2012-06-19 24 views
9

我有一堆什麼本質上是相同的性質使用不同的屬性名稱的第三方Java類:進行規範化的Java bean屬性名

public class Foo { 
    public String getReferenceID(); 
    public void setReferenceID(String id); 
    public String getFilename(); 
    public void setFilename(String fileName); 
} 

public class Bar { 
    public String getRefID(); 
    public void setRefID(String id); 
    public String getFileName(); 
    public void setFileName(String fileName); 
} 

我希望能夠在解決這些規範化的形式,這樣我就可以多態對待他們,這樣我就可以與Apache的BeanUtils做的東西,如:

PropertyUtils.copyProperties(object1,object2); 

顯然,這將是微不足道的編寫爲每個類的適配器...

public class CanonicalizedBar implements CanonicalizedBazBean { 
    public String getReferenceID() { 
     return this.delegate.getRefID(); 
    } 
    // etc. 
} 

但我不知道是有什麼在那裏更廣義的和動態的?某些需要屬性名稱等價的一對多映射和委託類的東西,並生成適配器?

回答

6

我從來沒有使用過它,但我認爲你正在尋找Dozer

推土機是一個Java Bean爲Java Bean映射器,循環地將數據從 一個對象到另一個。通常,這些Java Bean將會是不同複雜類型的 。

推土機支持簡單的屬性映射,複雜類型映射, 雙向映射,隱式顯式映射以及 遞歸映射。這包括映射集合屬性, 也需要在元素級別映射。

推土機不僅支持屬性名稱之間的映射,也 類型之間自動轉換。大部分轉換方案是 支持開箱即用,但也推土機允許你指定通過XML定製 轉換。

+0

謝謝。似乎做了沒有不需要的中間階段的確切工作。 – slim

4
  1. 第一個選項是Dozer

  2. 第二個選項是Smooks框架 與調整。使用Smook的圖形映射器將是有益的。

  3. 另一種選擇是XStream自定義映射。

2

也許類似的東西:

public class CanonicalizedBar implements CanonicalizedBazBean { 
public String getReferenceID() { 
    Method m = this.delegate.getClass().getDeclaredMethod("getReferenceID"); 
    if(m == null) 
     m = this.delegate.getClass().getDeclaredMethod("getRefID"); 
    ... 
    return m.invoke(); 
} 
// etc. 
} 
2

雖然,我個人從來沒有使用過它。我注意到一個叫orika項目被標註爲具有最佳的性能和自動明白了許多這種映射的能力。 無論如何它還支持自定義映射並使用生成的代碼來隱式定義適配器。

您也可以定義自定義映射,也就是說,如果你知道如何推崇成員名稱,你可以用這些知識來建立一個映射,它是所有的對象也是如此。例如:

DefaultFieldMapper myDefaultMapper = new DefaultFieldMapper() { 
    public String suggestMapping(String propertyName, Type<?> fromPropertyType) { 
     // split word according to camel case (apache commons lang) 
     String[] words= StringUtils.splitByCharacterTypeCamelCase(propertyName); 
     if(words[0].length() > 6) { 
     // trim first camel-cased word of propery name to 3 letters 
     words[0]= words[0].substring(0,2); 
     return StringUtils.join(words); 
     } else { 
     // remains unchanged 
     return propertyName; 
     } 
    } 
} 

mapperFactory.registerDefaultFieldMapper(myDefaultMapper); 
1

我沒有做多少吧,但你可以使用Aspect Oriented Programming做到這一點。

你應該能夠做什麼我認爲是添加一個方法到內部調用真正的方法的每個類。大約半路下來看到這個article它討論mixin。

AspectJ可能是最流行的實現。