Dynamically change spring beans

How can I dynamically change bean properties at runtime using java spring? I have a bean mainView that should use either class "class1" or "class2" as the property. This decision should be made based on the properties file, where the "withSmartcard" property is "Y" or "N".

ApplicationContext:

<bean id="mainView" class="mainView"> <property name="angebotsClient" ref="angebotsClient" /> <property name="class" ref="class1" /> </bean> <bean id="class1" class="class1"> <constructor-arg ref="mainView" /> </bean> <bean id="class2" class="class2"> <constructor-arg ref="mainView" /> </bean> 

PropertyFile:

withSmartcard = Y

+6
java spring javabeans
source share
5 answers

Use PropertyPlaceHolder to manage your properties file.

 <bean id="myPropertyPlaceHolder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <description>The service properties file</description> <property name="location" value="classpath:/some.where.MyApp.properties" /> </bean> 

and change the ref attribute as follows:

 <bean id="mainView" class="mainView"> <property name="angebotsClient" ref="angebotsClient" /> <property name="class" ref="${withSmartCardClassImplementation}" /> </bean> 

In your some.where.MyApp.properties properties file, add a key named SmartCardClassImplementation that will have class1 or class2 (you select) for the value.

 withSmartCardClassImplementation=class1 
+10
source share

You want PropertyPlaceholderConfigurer . This section of the manual demonstrates this better than I could locally.

In your example, you need to either change the value of the property to class1 or class2 (the name of the desired bean in the context of spring).

Alternatively, your configuration could be:

 <bean id="mainView" class="mainView"> <property name="angebotsClient" ref="angebotsClient" /> <property name="class"> <bean class="${classToUse}"> <constructor-arg ref="mainView"/> </bean> </property> </bean> 

with a configuration file containing: classToUse = fully.qualified.name.of.some.Class

Using a bean or class names would not be acceptable in a user-editable configuration file, and you really need to use "Y" and "N" as the values ​​for the configuration parameter. In this case, you just need to do it in Java, spring is not meant to be completed.

mainView can directly access the application context:

 if (this.withSmartCards) { this.class_ = context.getBean("class1"); } else { this.class_ = context.getBean("class2"); } 

A cleaner solution would be to encapsulate user configuration processing in its own class, which would do it higher in order to reduce the number of classes that should be ApplicationContextAware and, if necessary, introduce them into its other classes.

Using BeanFactoryPostProcessor , you can register a class property definition programmatically. Using FactoryBean , you can dynamically create a bean. Both are somewhat advanced ways to use Spring.

Aside: I'm not sure if your config example is legal, given the circular dependency between mainView and class1 / class2.

+4
source share

Use the factory class. which can return an instance based on your property.

+1
source share

I believe that you can write a class that implements BeanFactoryPostProcessor . If a bean of this class exists in the XML configuration file (along with other beans), Spring will automatically call it postProcessBeanFactory (ConfigurableListableBeanFactory) . The ConfigurableListableBeanFactory object passed to this method can be used to modify any bean definitions before Spring gets to work by initializing them.

+1
source share

Agree with @Olivier above.

There are many ways to do this.

  • Use PropertyPlaceHolderConfigurer ..
  • Use BeanPostProcessor ..
  • Use Spring AOP, create tips and process them.

I would recommend item no: 1 above.

+1
source share

All Articles