In searching Google for “Spring ApplicationContextAware“, you come across a lot of recommendations and I also see a lot of folks continuing to complain saying that their setApplicationContext method does not get invoked. So to help clarify, I’m blogging a few notes in hope that it helps clarify a few things.
Two Ways to Get Application Context:
Method #1: In your class you implement ApplicationContextAware class like this:
public class MyClass implements ApplicationContextAware {
static final long serialVersionUID = 02L;
ApplicationContext applicationContext = null;
public void doSomething(){
if (applicationContext != null && applicationContext.containsBean("accessKeys")){
MyBean beanA = (MyBean) applicationContext.getBean("mybean");
//Do something with this AccessBean
}
return null;
}
@Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
System.out.println("setting context");
this.applicationContext = applicationContext;
}
}
Method #2: If you are in a Java Servlet, you can do the following:
public class gzservlet extends HttpServlet {
static final long serialVersionUID = 02L;
ApplicationContext applicationContext = null;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
if (applicationContext == null){
System.out.println("setting context in get");
applicationContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
}
if (applicationContext != null && applicationContext.containsBean("accessKeys")){
AccessBean thisAccessBean = (AccessBean) applicationContext.getBean("accessKeys");
req.setAttribute("keys", thisAccessBean.toString());
System.out.println("setting keys");
}
req.getRequestDispatcher("/index2.jsp").include(req,resp);
}
}
So the question one would ask is when to use what? And the answer is. Depends on how you are invoking Spring.
What works for Method #1: when you invoke Spring you are using the DispatcherServlet link this. Then Method #1 will resolve the implementation of ApplicationContextAware and call the setApplicationContext() method to set the context.
In web.xml. <servlet> <servlet-name>dispatchservlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatchservlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
If you are not using the DispatcherServlet and you are initializing Spring using a Listener and you have your own Servlet that’s driving the RequestResponse scope then use Method #2. Below is an example of how the web.xml will look like in this case.
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>MyOwnServlet</servlet-name> <servlet-class>com.something.myservlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>MyOwnServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
I hope this clarifies why sometimes even though you have implemented the ApplicationContextAware interface, your setter does not get invoked.
[09/12/2010] Here is a third way to get your context:
Create the following class with a static method to get your context:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class ApplicationContextProvider implements ApplicationContextAware{
private static ApplicationContext ctx = null;
public static ApplicationContext getApplicationContext() {
return ctx;
}
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
this.ctx = ctx;
}
}
and in your spring bean configuration xml file add the following:
<bean id="applicationContextProvider" class="ApplicationContextProvider"></bean>
And now in your classes, you can do the following:
ApplicationContext ctx = ApplicationContextProvider.getApplicationContext();
That’s it!!!
Cheers.
If you find this article useful, consider signing up for my RSS feed or Email Newsletter. See links on the right side.

I tried out 3rd one.
ApplicationContext ctx = ApplicationContextProvider.getApplicationContext(); // This always returns null.
What am i missing out?
Pingback: Spring 3.0配置多个DispatcherServlet的方法及注意事项 « 谢邵虎的 Blog
Pingback: How to publish and subscribe to events with Spring ? « Vishwanath Krishnamurthi's blog
Thanks, that’s a very clear explanation.. !
Thank you, method #1 was very helpful.
Method #3 works find. Was very helful for the non-web application.
Hi,
I have a spring web application and want to use application context in a batch program.
Idea is: Web Application server will be started (So the Application context is up), I will have a normal java program with main method. And when I run this java program I need spring application context here. Can I do that using above method #3 ? If yes then how?
I have tried the above method but thats not working for me
You can try something like this to initialize the context in your main method of your batch program.
—
import org.springframework.context.ApplicationContext;
private static ApplicationContext ctx;
public static void main(String[] args)
{
try
{
ctx = new FileSystemXmlApplicationContext(“c:/MyPathToFile/spring1.xml”);
if (applicationContext != null && applicationContext.containsBean(“accessKeys”))
{
MyBean beanA = (MyBean) applicationContext.getBean(“mybean”);
//Do something with this AccessBean
}
} catch (Exception e) {
System.exit(1);
}
}
—
Thank you Venkatt for your reply, but my problem is, I have around 70 jobs. So for each job I have to initialize the context, which is very time consuming. So I want to get rid of initializing the context in every job.
I hope you got my problem.
Thanks,
Jigar
Jigar - are all your 70+ jobs pointing to the same “xml” file? or does each one have it’s own respective xml file for the Spring Context? Example Job #1 has “Job1.xml” and so on. Either way, why not include a common utility library that has a static method where you pass the name of the XML file that you wish to invoke?
public static ApplicationContext initializeContext(String fileName) { … }
If you are using Java 6 and above, the other option you have is to create a ServiceLoader (see java.util.ServiceLoader) to auto-wire a singleton “java” class that can then hold the Application Context.
Good Luck
No - All my 70+ jobs are pointing to the same application context XML file. We are using Java 1.5, not sure when will we migrate to Java 6.
Even If I use a static method to initialize the context, my each job will load the context. Since each batch job is like a Java program (starts with a call to main method).
I have tried something like this:
1) I have created a RMI server, this server loads the application context upon startup.
2) I have one service method in the RMI server which will trigger the batch job service
3) My each batch job will call this service method passing all the required args (in my case I have only one argument - the name of the batch job service)
4) After the last job is executed, I will stop the RMI server (I am struggling with this now)
Thank you for your help and suggestions Venkatt. Really appreciate that.
Jigar
Pingback: Hongtium » Spring 3.0配置的两个相关文章
Pingback: Check here