vrm
vrm

Reputation: 1412

Spring set abstract bean property value

I need to chance spring bean property values on runtime. Currently I'm doing it this way

Object bean = context.getBean(beanName);
BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(bean);
wrapper.setPropertyValue(propertyName, newValue);

But some beans are configured as abstract

<bean id="abstractFoo" abstract="true" class="com.Foo" />

<bean id="bar" class="com.Bar">
    <constructor-arg><bean parent="abstractFoo" /></constructor-arg>
</bean>

and in that case context.getBean("abstractFoo") throws BeanIsAbstractException

This is really simplified example, but I hope you get the idea.

Any idea how to change property value of abstract bean (in this case 'abstractFoo')? We're using spring 2.5.4

Edit

Changed a XML example to be more specific. abstractFoo is declared abstract because of security reasons.

Upvotes: 0

Views: 5175

Answers (2)

Joeri Hendrickx
Joeri Hendrickx

Reputation: 17435

Disclaimer: this is untested; off the top of my head. Not sure if it will work after the init phase.

You need to get in instance of a ConfigurableListableBeanFactory. Your appcontext probably is one, so you can probably cast it.

From there, get the bean definition and change the property.

   ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory)context;
   BeanDefinition fooDefinition = clbf.getBeanDefinition("abstractFoo");
   MutablePropertyValues pv = fooDefinition.getPropertyValues();
   pv.add(propertyName, newValue);

Maybe you need to re-register your beandefinition with the ConfigurableListableBeanFactory after that. I'm not 100% sure; you'll have to test that.

Keep in mind that if it works, it will only work for beans that are instantiated after the change.

Upvotes: 0

axtavt
axtavt

Reputation: 242686

Spring application context contains bean definitions, and Spring instantiates bean objects defined by these definitions.

Your current code obtains an object that was created from the named bean definition, and changes its property. However, abstract beans are never instantiated as objects, they exist only in the form of definitions which are inherited by definitions of concrete beans.

So, if you want to change properties of abstract beans, you need to change their definitions, that can be done using BeanFactoryPostProcessor. Note, however, that post-processors are applied during container startup, so if you want it to be actually "runtime", you this approach is not applicable.

Upvotes: 2

Related Questions