Getting Spring Application Context
Is there a way to statically/globally request a copy of the ApplicationContext in a Spring application?
Assuming the main class starts up and initializes the application context, does it need to pass that down through the call stack to any classes that need it, or is there a way for a class to ask for the previously created context? (Which I assume has to be a singleton?)
If the object that needs access to the container is a bean in the container, just implement the BeanFactoryAware or ApplicationContextAware interfaces.
If an object outside the container needs access to the container, I've used a standard GoF singleton pattern for the spring container. That way, you only have one singleton in your application, the rest are all singleton beans in the container.
You can implement ApplicationContextAware
or just use @Autowired
:
public class SpringBean {
@Autowired
private ApplicationContext appContext;
}
SpringBean
will have ApplicationContext
injected, within which this bean is instantiated. For example if you have web application with a pretty standard contexts hierarchy:
main application context <- (child) MVC context
and SpringBean
is declared within main context, it will have main context injected;
otherwise, if it's declared within MVC context, it will have MVC context injected.
Here's a nice way (not mine, the original reference is here: http://sujitpal.blogspot.com/2007/03/accessing-spring-beans-from-legacy-code.html
I've used this approach and it works fine. Basically it's a simple bean that holds a (static) reference to the application context. By referencing it in the spring config it's initialized.
Take a look at the original ref, it's very clear.
I believe you could use SingletonBeanFactoryLocator. The beanRefFactory.xml file would hold the actual applicationContext, It would go something like this:
<bean id="mainContext" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<list>
<value>../applicationContext.xml</value>
</list>
</constructor-arg>
</bean>
And the code to get a bean from the applicationcontext from whereever would be something like this:
BeanFactoryLocator bfl = SingletonBeanFactoryLocator.getInstance();
BeanFactoryReference bf = bfl.useBeanFactory("mainContext");
SomeService someService = (SomeService) bf.getFactory().getBean("someService");
The Spring team discourage the use of this class and yadayada, but it has suited me well where I have used it.