Issue
My issue is how to implement selectively loading spring beans at the start of an web application.
Background Our application is based on J2EE and Spring. We run the same web application on different managed servers. On some of these managed servers, we only run web service but on others, we also need to run services such as reporting, scheduler and etc. All these services are configured as spring bean in spring configuration xml files. So we'd like to disable some unused beans when start servers with web service.
Problems,
I tried to override method of customizeContext
in org.springframework.web.context.ContextLoaderListener
to remove those unused beans from context. (I know this is not a good idea to remove loaded beans instead of stopping them being loaded at the first place. that's because I couldn't figure out how to implement that as well) However, I got java.lang.IllegalStateException: BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext
.
After some investigation, I get that BeanFactory
can't be used here but I'm kind of stuck and don't know how to implement this function. Can anyone help me out of this please? Either stopping loading beans into Spring at start time or removing beans from Spring when it is just started would work for me.
The following is my code to override Method customizeContext
.
@Override
protected void customizeContext(ServletContext servletContext, ConfigurableWebApplicationContext applicationContext) {
super.customizeContext(servletContext, applicationContext);
ConfigurableListableBeanFactory configurableListableBeanFactory = applicationContext.getBeanFactory();
BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) configurableListableBeanFactory;
beanDefinitionRegistry.removeBeanDefinition("testBean");
}
Solution
Thanks for the suggestions from Serge and other guys. We are currently using 3.0.5, so can't really use the 3.1 profiles feature in our project.
We figured out a way to do it by adding a BeanFactoryPostProcessor
to the ConfigurableWebApplicationContext
in the method customizeContext()
. It seems solved our problems.
Code changes are:
protected void customizeContext(ServletContext servletContext, ConfigurableWebApplicationContext applicationContext) {
super.customizeContext(servletContext, applicationContext);
applicationContext.addBeanFactoryPostProcessor(new BootProcessor());
}
class BootProcessor implements BeanFactoryPostProcessor{
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory clbf) throws BeansException {
BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) clbf;
beanDefinitionRegistry.removeBeanDefinition("testerBean");
}
}
Answered By - Mingyi Yang
Answer Checked By - Katrina (JavaFixing Volunteer)