2016-09-27 18 views
0

beanの@Beanタイプ定義を使用している間、SpringのBean継承を使用したいと思います。具体的には、@Beanアノテーションを使用して子Beanを設定する方法

public class Serwis { 
    Integer a; 
    Integer b; 
    Map<Integer, Integer> m = new HashMap<>(); 
} 

をしましょうとXMLベースの構成は次のようになりますと仮定します。豆absSerwisのディープコピーを含む豆defSerwisを作成し

<bean id="absSerwis" class="service.Serwis" 
     p:a="11"> 
    <property name="m"> 
     <map> 
      <entry key="111" value="111"></entry> 
     </map> 
    </property> 
</bean> 

<bean id="defSerwis" parent="absSerwis" 
     p:b="12" 
    /> 

。特にmの内容がコピーされます。今、私はそれを行うための適切な方法は何か

@Autowired 
@Qualifier("absSerwis") 
private Serwis absSerwis; 

@Bean 
public Serwis cccSerwis() { 
    Serwis s = new Serwis(); 
    BeanUtils.copyProperties(absSerwis, s); //wrong; does shallow copy 
    return s; 
} 

のように、@Beanアノテーションを使用してdefSerwisのような豆を定義したいと思いますか?その後、

+1

親が何であるかを理解するのはちょっとです。それは単純に両方のBean定義をマージし、その後にBean定義をマージします。それは深く/新鮮なコピーを作成しません、そのようなものはありません。 'absSerwis'(' @ Bean'でアノテーションを付けないでメモ!)を作成するメソッドを作成してください。次に、2つの '@ Bean'メソッドを作成します.1は元の' absSerwis'を公開し、もう1つはいくつかのプロパティを追加します。 –

+0

@ M.Deinumは「少し離れています。 xmlの 'parent ='がどのように動作するかを少し詳しく説明する場所を指摘してください。 –

+0

私の答え(およびSpringリファレンスガイドへのリンク)を参照してください。 –

答えて

1

。ディープコピーや何か他のものが作られていることはありません。 beanがparentのBeanを使用しているとき、Springが何をするかを最初に調べることができます。 (また、それは約bean定義の継承であることに注意してください。クラス継承!);ご使用の構成

<bean id="absSerwis" class="service.Serwis" 
     p:a="11"> 
    <property name="m"> 
     <map> 
      <entry key="111" value="111"></entry> 
     </map> 
    </property> 
</bean> 

<bean id="defSerwis" parent="absSerwis" 
     p:b="12" 
    /> 

考える

は何が起こるかというとdefSerwis定義のために、それは親absSerwisの構成をとり、自身とフルBean定義にこれをマージするということです。したがって、深いコピーや豆のコピーなどはありません。結局

<bean id="absSerwis" class="service.Serwis" 
     p:a="11"> 
    <property name="m"> 
     <map> 
      <entry key="111" value="111"></entry> 
     </map> 
    </property> 
</bean> 

<bean id="defSerwis" class="service.Serwis" 
     p:a="11" p:b="12" 
     <property name="m"> 
     <map> 
      <entry key="111" value="111"></entry> 
     </map> 
    </property> 
    /> 

を見てどのような春

this sectionリファレンスガイドのを参照してください。

最も簡単な方法は、親を構築しそこから追加するメソッドを作成することです。この方法は、ではなく@Beanと注釈を付ける必要があります。

@Configuration 
public class MyConfiguration { 

    private Serwis baseSerwis() { 
     Serwis base = new Serwis(); 
     base.setA(11); 
     Map map = new HashMap(); 
     map.put(111, 111); 
     base.setM(map); 
     return base; 
    } 

    @Bean 
    public Serwis absSerwis() { 
     return baseSerwis(); 
    } 

    @Bean 
    public Serwis defSerwis() { 
     Serwis defSerwis = baseSerwis(); 
     defSerwis.setB(12); 
     return defSerwis; 
    } 
} 

これは多かれ少なかれxmlの部分に相当します。

+0

cool;細かいことをありがとう! –

0

あなたがオブジェクトのディープコピーを作成したい場合、あなたができます。そうする

1)プログラムそれ自身。

2)これを行うには、javaシリアル化を使用します(シリアライズとデシリアライズはディープコピーを作成できます)が、これはデータ構造内のすべてのオブジェクトがシリアル化可能なインターフェイスを実装するためです。そのために使用できる他の自由(例えばxStream)もあります。

3)デフォルトでSpringは特定のBean(別名Singleton)のインスタンスを1つしか作成しません。@Prototypeで注釈を付けて、必要なときに新しいオブジェクトを取得したいとSpringに知らせることができます。このようビルダー+コピー方法

public class Serwis { 
    Integer a; 
    Integer b; 
    Map<Integer, Integer> m = new HashMap<>(); 

    private Serwis(Builder builder) { 
     a = builder.a; 
     b = builder.b; 
     m = builder.m; 
    } 

    public static Builder builder() { 
     return new Builder(); 
    } 

    public Builder copy(Serwis copy) { 
     return builder() 
      .a(a) 
      .b(b) 
      .m(m); 
    } 

    public static final class Builder { 
     private Integer a; 
     private Integer b; 
     private Map<Integer, Integer> m = new HashMap<>(); 

     private Builder() { 
     } 

     public Builder a(Integer val) { 
      a = val; 
      return this; 
     } 

     public Builder b(Integer val) { 
      b = val; 
      return this; 
     } 

     public Builder m(Map<Integer, Integer> val) { 
      m.putAll(val); 
      return this; 
     } 

     public Serwis build() { 
      return new Serwis(this); 
     } 
    } 
} 

と構成クラスを使用することにより

0

:あなたが実際に何が起こるかではない記述何手始めに

@Autowired 
@Qualifier("absSerwis") 
private Serwis absSerwis; 

@Bean 
public Serwis cccSerwis() { 
    return absSerwis.copy().build(); 
} 
+0

私は何百もの豆にこれを使用していますが、多くの利点のために@Beanに切り替えることを検討しています。カスタムビルダ/ディープコピーを書くのではなく、XMLベースの設定をそのまま使うことができます。 ''のようなものです。 –

関連する問題