![](/img/trans.png)
[英]How to modify properties resolved by Spring before their injection into beans
[英]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.xml
中codebase
的定義,並添加兩個值,即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容器實例化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>
是。 bean定義可以具有引用父bean定義的“父”屬性。 新的“子”定義繼承了父級的大多數屬性,並且可以覆蓋任何這些屬性。
請參見Bean定義繼承
您還可以使用Collection Merging從父bean和子bean定義合並列表屬性定義。 這樣,您可以在父bean定義中指定一些列表項,並在子bean定義中向其添加更多項。
3種方法:
簡單:有兩個列表defaultSourceCodeLocations和additionalSourceCodeLocations,並讓您的訪問者方法檢查這兩個(或組合它們)。 我已經在一些框架中看到了這一點 - 填充了一個默認的處理程序列表,然后添加了其他用戶創建的處理程序...
更復雜但保持原始類清潔:然后您可以創建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.