[ACCEPTED]-How to modify beans defined in a spring container-ioc-container
You could use a BeanFactoryPostProcessor to change the bean's metadata 3 before the Spring container instantiates 2 the CodeBase bean. For example:
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;
}
}
Then in 1 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>
Yes. A bean definition can have a "parent" attribute 10 that references a parent bean definition. The 9 new "child" definition inherits 8 most of the properties of the parent and 7 any of those properties can be overridden.
See 6 Bean Definition Inheritance
Also you can use Collection Merging to merge the list property 5 definition from the parent and child bean 4 definitions. This way you can specify some 3 list items in the parent bean definition 2 and add more items to it in the child bean 1 definition.
3 approaches:
Simple: have two lists defaultSourceCodeLocations 23 and additionalSourceCodeLocations and have 22 your accessor methods check both of these 21 (or combine them). I've seen this done in 20 some frameworks - a default list of handlers 19 is populated then additional user created 18 ones are added...
More complicated but keeps 17 the original class clean: You could then 16 create a CodeBaseModifier class. This would 15 have a init-method to alter an injected 14 instance of the 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>
If you wanted to make 13 this really generic you could make a bean 12 modifier that would do this by reflection. Be 11 careful of the ordering if use this approach. Dependent 10 beans of CodeBase would have to make sure 9 this class was instantiated first (with 8 depends on)
3 A variation on 2... Instead 7 of directly creating a CodeBase class instead 6 create a factory that returns a populated 5 bean. This factory could then be configured 4 with Spring in a similar fashion to 2. Have 3 a defaultSourceCodeLocations and additionalSourceCodeLocations 2
Unless you need a lot of extensible properties 1 I would go with option 1.
Is there a way to define the list in a properties 5 or other configuration before hand?
It 4 seems like the app configuration and wiring 3 are tightly coupled. From my experience, if 2 it is hard to do something in Spring, likely 1 there is a different easier way to do it.
In Spring 3.0, you can specify merge="true" on 1 the 'list' tag. See http://forum.springsource.org/archive/index.php/t-97501.html for details.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.