Add Bean Programmatically to Spring Web App Context

Add Bean Programmatically to Spring Web App Context

In Spring 3.0 you can make your bean implement BeanDefinitionRegistryPostProcessor and add new beans via BeanDefinitionRegistry.

In previous versions of Spring you can do the same thing in BeanFactoryPostProcessor (though you need to cast BeanFactory to BeanDefinitionRegistry, which may fail).

How to add bean instance at runtime in spring WebApplicationContext?

You can make use of BeanDefinitionRegistry (look here for API) to remove or register the beans dynamically.

So, in your SpringUtil class, you can add the below method to remove the existing bean definition using removeBeanDefinition() and then add a new bean definition by using registerBeanDefinition().

public void removeExistingAndAddNewBean(String beanId) {

AutowireCapableBeanFactory factory =
applicationContext.getAutowireCapableBeanFactory();
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) factory;
registry.removeBeanDefinition(beanId);

//create newBeanObj through GenericBeanDefinition

registry.registerBeanDefinition(beanId, newBeanObj);
}

How to programatically add an @Bean definition to Spring context?

You should autowire the bean factory, and use a @PostConstruct to register your bean. That way, you guarantee that all dependencies has been injected (the bean factory is injected by the container, no setup is needed).

@Service
public class MyPortRegistrar {

@Autowired
private ConfigurableBeanFactory beanFactory;

@Autowired
private SpringBus bus;

@PostConstruct
public void createPort() {
Port port = new WebservicePort(bus);
beanFactory.registerSingleton("myDynamicPortName", port);
}
}

Why is programmatically created bean not available in the application context

AutowireCapableBeanFactory#initializeBean(Object, String) doesn't add a bean to a context or bean factory. The javadoc states

Initialize the given raw bean, applying factory callbacks such as
setBeanName and setBeanFactory, also applying all bean post processors
(including ones which might wrap the given raw bean).

It basically just processes the object you pass to it as if it was a bean initialized as part of the ApplicationContext. Notice that the method returns an Object, the result of the initialization.

Returns:
the bean instance to use, either the original or a wrapped one

Spring adding beans at runtime

See AutowireCapableBeanFactory.initializeBean(beanName).

You need to make sure the bean's not used between registration and initialization.

Also, be aware that registering singletons after the context is initialized wasn't really thread-safe until recently (4.2.2, I think). It could cause ConcurrentModificationExceptions if other code is iterating over the beans in the factory.

However, in this case, it might be too late to get the HTTP paths registered, you might need more code to do that.

retrieve Bean programmatically

Here an Example

public class MyFancyBean implements ApplicationContextAware {

private ApplicationContext applicationContext;

void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}

public void businessMethod() {
//use applicationContext somehow
}

}

However you rarely need to access ApplicationContext directly. Typically you start it once and let beans populate themselves automatically.

Here you go:

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

Note that you don't have to mention files already included in applicationContext.xml. Now you can simply fetch one bean by name or type:

ctx.getBean("someName")

Note that there are tons of ways to start Spring - using ContextLoaderListener, @Configuration class, etc.



Related Topics



Leave a reply



Submit