Tuesday, March 24, 2009

Create Spring beans dynamically

Spring XML declared beans can be wired building your business structure. The problem with this approach is that these beans are loaded on the start up, when the Spring Context is created, which does not leave much of playground to modify or change beans at run time. How ever Spring offers opportunity to load beans in the Spring context on run time when beans are needed, and populate them at need.
For doing this, we need the Spring Application context. For this to accomplish, one can declare one dedicated Spring context bean, which will implement the ApplicationContextAware and BeanFactoryPostProcessor interfaces. This should look something like this:


public class MyContextWrapper implements ApplicationContextAware,
BeanFactoryPostProcessor {

private ApplicationContext appContext;
private ConfigurableListableBeanFactory factory;

public void postProcessBeanFactory(ConfigurableListableBeanFactory factory)
throws BeansException {
this.factory = factory;
}
public void setApplicationContext(ApplicationContext c)
throws BeansException {
this.appContext = c;
}

//setters and getters

}



The postProcessBeanFactory will be executed after reading the configuration files of the spring context. Here one can do other configurations and bean loading, or save the factory for later use.
The Spring application context can be used for later dynamic bean retrieval or other purposes.

For this approach to work, one should let spring load this bean in to it's context by declaring the bean in the XML configuration file as follow:






Now this bean can be loaded in any other bean of the application via referencing it:








Now that we have the grip of the Spring context and it's factory, we can create beans dynamically. For this purpose, we can use the GenericBeanDefinition which allows to load bean definitions as follows:

BeanDefinitionRegistry registry = ((BeanDefinitionRegistry )factory);

GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(MyBeanClass.class);
beanDefinition.setLazyInit(false);
beanDefinition.setAbstract(false);
beanDefinition.setAutowireCandidate(true);
beanDefinition.setScope("session");

registry.registerBeanDefinition("dynamicBean",beanDefinition);


As one can see, this bean is created in the session scope and will be stored in the session of the user. The property auto wire candidate tells spring if dependency's of the bean such as setter's or getter's or constructor argument's should be handled automatically by Spring. The property lay init tells Spring if this bean should be instantiated when needed.

To get a handle of Spring bean, one can use the Spring application context as follows:

Object bean=
getApplicationContext().getBean("dynamicBean");
if(bean instanceof MyBeanClass){
MyBeanClass myBean = (MyBeanClass) bean;

// do with the bean what ever you have to do.
}


As you can see, the dynamic bean creation in Spring is no big deal.It is easy to use, an certainly handy in many situations.