簡體   English   中英

如何修改spring容器中定義的bean

[英]How to modify beans defined in a spring container

我有兩個xml文件定義springframework(版本2.5.x)的bean:

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>

現在我想在containerSpecial.xml調整bean codebase的屬性sourceCodeLocations 我需要添加第二個值src/generated/productive

一個簡單的方法是覆蓋containerSpecial.xmlcodebase的定義,並添加兩個值,即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定義的默認值。

在Spring容器實例化Code​​Base 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>

是。 bean定義可以具有引用父bean定義的“父”屬性。 新的“子”定義繼承了父級的大多數屬性,並且可以覆蓋任何這些屬性。

請參見Bean定義繼承

您還可以使用Collection Merging從父bean和子bean定義合並列表屬性定義。 這樣,您可以在父bean定義中指定一些列表項,並在子bean定義中向其添加更多項。

3種方法:

  1. 簡單:有兩個列表defaultSourceCodeLocations和additionalSourceCodeLocations,並讓您的訪問者方法檢查這兩個(或組合它們)。 我已經在一些框架中看到了這一點 - 填充了一個默認的處理程序列表,然后添加了其他用戶創建的處理程序...

  2. 更復雜但保持原始類清潔:然后您可以創建CodeBaseModifier類。 這將有一個init方法來改變注入的bean實例。

     <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的工廠。 然后可以以類似於2的方式使用Spring配置此工廠。具有defaultSourceCodeLocations和additionalSourceCodeLocations

除非你需要很多可擴展的屬性,否則我會選擇1。

有沒有辦法在事先定義屬性或其他配置中的列表?

看起來應用配置和布線緊密耦合。 根據我的經驗,如果在Spring中很難做某事,可能會有一種更簡單的方法。

在Spring 3.0中,您可以在'list'標記上指定merge =“true”。 有關詳細信息,請參見http://forum.springsource.org/archive/index.php/t-97501.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM