9

基本的に同じプロパティに対して異なるプロパティ名を使用するサードパーティのJavaクラスがたくさんあります。

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.
}

しかし、もっと一般化された動的なものがあるのだろうか? プロパティ名の等価性の 1 対多のマップとデリゲート クラスを取り、アダプターを生成するものはありますか?

4

5 に答える 5

6

私は使ったことがありませんが、あなたはDozerを探していると思います:

Dozer は、あるオブジェクトから別のオブジェクトにデータを再帰的にコピーする Java Bean から Java Bean へのマッパーです。通常、これらの Java Bean は異なる複合型になります。

Dozer は、単純なプロパティ マッピング、複雑な型マッピング、双方向マッピング、暗黙的/明示的マッピング、および再帰的マッピングをサポートしています。これには、要素レベルでのマッピングも必要なコレクション属性のマッピングが含まれます。

Dozer は、属性名間のマッピングをサポートするだけでなく、タイプ間の自動変換もサポートします。ほとんどの変換シナリオは標準でサポートされていますが、Dozer では XML を介してカスタム変換を指定することもできます。

于 2012-06-21T10:01:36.467 に答える
4
  1. 最初のオプションはドーザーです。

  2. 2 番目のオプションは、微調整を加えたSmooksフレームワークです。Smook のグラフィカル マッパーを使用すると便利です。

  3. 別のオプションは、カスタム Mapper を使用したXStreamです。

于 2012-06-23T19:29:19.237 に答える
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 );
于 2012-06-27T03:04:03.477 に答える
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.
}
于 2012-06-27T00:31:31.730 に答える
1

私はそれをあまり使っていませんが、アスペクト指向プログラミングを使用してこれを行うことができるかもしれません。

あなたができるはずのことは、実際のメソッドを内部的に呼び出す各クラスにメソッドを追加することだと思います。ミックスインについて説明している途中のこの記事を参照してください。

AspectJはおそらく最も人気のある実装です。

于 2012-06-27T05:36:38.457 に答える