Having used this class in various projects, I thought that I’d figure out what it does under the hood.
// Load the ContextSingleton
BeanFactoryLocator factoryLocator = ContextSingletonBeanFactoryLocator
.getInstance("classpath:beanRefContext.xml");
// Get hold of the factory to use
BeanFactoryReference ref = factoryLocator
.useBeanFactory("timerControlServiceBeanFactory");
BeanFactory factory = ref.getFactory();
// Get a bean from the factory
WineService instance = factory.getBean(WineService.class);
System.out.println("Loaded WineService: " + instance);
The first point to note is that you obtain a ContextSingletonBeanFactoryLocator using a getInstance() factory method underlining that this is a singleton class. By default, this loads any file named beanRefContext.xml that’s on your classpath, but you can use alternatively named XML files.
A beanRefContext can contain multiple ApplicationContext or factory instances, which can are referred to by their id.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean id="timerControlServiceBeanFactory" class="org.springframework.context.support.ClassPathXmlApplicationContext"> <constructor-arg> <list> <value>classpath:spring-timer-service.xml</value> <value>classpath:spring-service.xml</value> <value>classpath:spring-transaction.xml</value> </list> </constructor-arg> </bean> <bean id="flowControlServiceBeanFactory" class="org.springframework.context.support.ClassPathXmlApplicationContext"> <constructor-arg> <list> <value>classpath:spring-flow-control-service.xml</value> <value>classpath:spring-service.xml</value> <value>classpath:spring-transaction.xml</value> </list> </constructor-arg> </bean> </beans>Setting the factory name to null means that the useBeanFactory() will load any bean factory by type rather than by name / id and in this case, your beanrefcontext.xml file can contain only one ApplicationContext or factory instance.
// Get hold of the factory to use
BeanFactoryReference ref = factoryLocator.useBeanFactory(null);
A beanRefContext.xml that loads by type:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- This context is loaded by type and not by name --> <bean class="org.springframework.context.support.ClassPathXmlApplicationContext"> <constructor-arg value="classpath:appConfig.xml" /> </bean> </beans>Having got hold of the singleton factory, you can then access its beans in the usual way.
1 comment:
Thank you very much for your post, it works!
I tried with the annontation @Interceptors(SpringBeanAutowiringInterceptor.class) but it didn't work.
It was to inject a Spring Service in a EJB class.
Post a comment