12

springframework (バージョン 2.5.x) の Bean を定義する 2 つの xml ファイルがあります。

containerBase.xml:
<beans>
    <bean id="codebase" class="com.example.CodeBase">
        <property name="sourceCodeLocations">
            <list>
                <value>src/handmade/productive</value>
            </list>
        </property>
    </bean>
</beans>

... と

containerSpecial.xml:
<beans>
    <import resource="containerBase.xml" />
</beans>

sourceCodeLocations今私は Beancodebase内のプロパティを調整したいと思いますcontainerSpecial.xml。2 番目の値を追加する必要がありますsrc/generated/productive

簡単な方法codebaseは、 inの定義をオーバーライドして、元の値と新しいcontainerSpecial.xml値の両方の値を追加することです。containerBase.xml

containerSpecial.xml:
<beans>
    <import resource="containerBase.xml" />

    <bean id="codebase" class="com.example.CodeBase">
        <property name="sourceCodeLocations">
            <list>
                <value>src/handmade/productive</value>
                <value>src/generated/productive</value>
            </list>
        </property>
    </bean>
</beans>

Bean を再定義せずにリストを拡張する方法はありますか?

編集 2009-10-06:

containerBaseこれの目的は、多くの異なるプロジェクトで使用される共有標準コンテナーを持つことです。各プロジェクトは、そのプロジェクトに固有のいくつかのプロパティを独自の でオーバーライド/拡張​​できますcontainerSpecial。プロジェクトがオーバーライドされない場合は、 で定義されたデフォルトが使用されcontainerBaseます。

4

5 に答える 5

10

Spring コンテナーが CodeBase Bean をインスタンス化する前に、 BeanFactoryPostProcessorを使用して Bean のメタデータを変更できます。例えば:

public class CodebaseOverrider implements BeanFactoryPostProcessor {

    private List<String> sourceCodeLocations;

    public void postProcessBeanFactory(
            ConfigurableListableBeanFactory beanFactory) throws BeansException {        
        CodeBase codebase = (CodeBase)beanFactory.getBean("codebase");
        if (sourceCodeLocations != null)
        {
            codebase.setSourceCodeLocations(sourceCodeLocations);
        }
    }

    public void setSourceCodeLocations(List<String> sourceCodeLocations) {
        this.sourceCodeLocations = sourceCodeLocations;
    }

}

次に contextSpecial.xml で:

<beans>
    <import resource="context1.xml" />

    <bean class="com.example.CodebaseOverrider">
        <property name="sourceCodeLocations">
            <list>
                <value>src/handmade/productive</value>
                <value>src/generated/productive</value>
            </list>
        </property>
    </bean>
</beans>
于 2009-10-10T13:01:51.140 に答える
3

はい。Bean定義には、親Bean定義を参照する「親」属性を含めることができます。新しい「子」定義は、親のほとんどのプロパティを継承し、それらのプロパティのいずれかをオーバーライドできます。

Bean定義の継承を参照してください

また、コレクションのマージを使用して、親および子Bean定義からリストプロパティ定義をマージできます。このようにして、親Bean定義でいくつかのリスト項目を指定し、子Bean定義でさらに項目を追加することができます。

于 2009-09-28T12:41:24.703 に答える
1

事前にプロパティまたはその他の構成でリストを定義する方法はありますか?

アプリの構成と配線が密接に結びついているようです。私の経験から、Spring で何かを行うのが難しい場合は、別の簡単な方法がある可能性があります。

于 2009-10-08T01:54:58.693 に答える
1

3 つのアプローチ:

  1. シンプル: defaultSourceCodeLocations と additionalSourceCodeLocations の 2 つのリストを用意し、アクセサー メソッドでこれらの両方をチェックします (または組み合わせます)。一部のフレームワークでこれが行われているのを見てきました-ハンドラーのデフォルトリストが作成され、ユーザーが作成したハンドラーが追加されます...

  2. より複雑ですが、元のクラスをクリーンに保ちます。次に、CodeBaseModifier クラスを作成できます。これには、注入された Bean のインスタンスを変更するための init-method があります。

    <bean id="codebaseModifier" class="com.example.CodeBase" init-method="populateCodeBase">
        <property name="sourceCodeLocations" ref="codebase"/>
        <property name="additionalSourceCodeLocations">
        <list>
            <value>src/handmade/productive</value>
        </list>
        </property>
    </bean>
    

これを本当に一般的なものにしたい場合は、リフレクションによってこれを行う Bean モディファイアを作成できます。このアプローチを使用する場合は、順序に注意してください。CodeBase の依存 Bean は、このクラスが最初にインスタンス化されていることを確認する必要があります (依存あり)。

3 2 のバリエーション... CodeBase クラスを直接作成する代わりに、入力された Bean を返すファクトリを作成します。このファクトリは、Spring で 2 と同様の方法で構成できます。

多くの拡張可能なプロパティが必要でない限り、オプション 1 を使用します。

于 2009-10-06T12:52:54.497 に答える
1

Spring 3.0 では、'list' タグに merge="true" を指定できます。詳細については、 http://forum.springsource.org/archive/index.php/t-97501.htmlを参照してください。

于 2011-08-12T02:59:01.573 に答える