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