MyThinkPond

On Java, Python, Groovy, Grails, Spring, Node.js, Linux, Arduino, ARM, Embedded Devices & Web

Spring 3.0 – Application Context – three ways to get the context

Posted by Venkatt Guhesan on March 22, 2010

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 Request\Response 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.

Advertisements

31 Responses to “Spring 3.0 – Application Context – three ways to get the context”

  1. Dkumar said

    I tried out 3rd one.
    ApplicationContext ctx = ApplicationContextProvider.getApplicationContext(); // This always returns null.

    What am i missing out?

  2. […] DispatcherServlet间互相访问的问题。 这个问题直接参考Application Context – three ways to get the context的第一种方法解决。实现ApplicationContextAware接口即可。 […]

  3. […] Get access to the context object and then use context.publish(event) method […]

  4. Thanks, that’s a very clear explanation.. !

  5. Fred said

    Thank you, method #1 was very helpful.

  6. Sergey said

    Method #3 works find. Was very helful for the non-web application.

  7. Jigar said

    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);
      }

      }

      • Jigar said

        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

      • Venkatt Guhesan said

        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

      • Jigar said

        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

  8. […] Spring 3.0 – Application Context – three ways to get the context […]

  9. Check here said

    Check here…

    […]Spring 3.0 – Application Context – three ways to get the context « MyThinkPond[…]…

  10. […] view source […]

  11. tfforums said

    Number 3 will cause the app context to be stored forever = memory leak?

  12. […] https://mythinkpond.wordpress.com/2010/03/22/spring-application-context/ […]

  13. Glen said

    Method #3 worked for me.

    As a novice Spring user I had to figure out that this line:

    needs to have the fully qualified class name:

    I also had to put the annotations into your code:

    @Component
    public class ApplicationContextProvider implements ApplicationContextAware {
    @Autowired
    private static ApplicationContext ctx = null;

    ……..

    Finally, to find the name of the application URL inside the Spring 3 application, I called your ApplicationContextProvider class as so:

    ApplicationContext ctx = ApplicationContextProvider.getApplicationContext();
    WebApplicationContext webContext = (WebApplicationContext)ctx;
    System.out.println(“The application name is: “+webContext.getServletContext().getContextPath());

    Thanks for a great article 🙂

  14. […] the good person over at MyThinkPond, here is how I deployed the same WAR file, into the same webapps directory of Tomcat, but had it […]

  15. For most up-to-date news you have to visit
    web and on web I found this website as a finest web site for latest
    updates.

  16. I’ve been exploring for a little for any high quality articles or weblog posts on this kind of house . Exploring in Yahoo I ultimately stumbled upon this site. Reading this information So i am glad to convey that I’ve a very good
    uncanny feeling I discovered just what I needed.
    I so much definitely will make sure to don?t put out of your mind this website and provides it a look regularly.

  17. http://vacaturearnhem.wordpress.com said

    Greetings! Very useful advice within this article!
    It’s the little changes that produce the most significant changes. Thanks for sharing!

  18. Hi, everything is going perfectly here and ofcourse
    every one is sharing data, that’s really fine, keep up writing.

  19. e said

    Everything composed made a great deal of sense.
    But, think abkut this, what if you were to write a killer post title?

    I mean, I don’t want to tell you how to run your website, however suppose you added something to possibly grab people’s attention?
    I mean Spring 3.0 – Application Context – three ways
    to get the context MyThinkPond is kinda boring.

    You should look at Yahoo’s front page and note how they write post headlines to get
    viewers to open the links. You might add a video or a picture or two to get people excited about everything’ve got to say.
    Just my opinion, it might bring your posts a little bit more interesting.

  20. ashika said

    Awesome!

  21. ashika said

    hi,
    could you also answer for this:

    Number 3 will cause the app context to be stored forever = memory leak?

    How to close this ctx created or is it that ApplicationContextAware will take care to close the context.?

  22. Great article.

  23. JM said

    Thank you! #3 very helpful.

  24. Good post! We will be linking to this great article on our
    site. Keep up the good writing.

  25. HLVG said

    Thank you. Number 1 worked for me.

  26. […] Spring 3.0 – Application Context – three ways to get … – Spring 3.0 – Application Context – two ways to get the context. MyThinkPond On Java, Python, … and in your spring bean configuration xml file add the following: […]

  27. […] Spring 3.0 – Application Context – three ways to get … – … ("setting context in get"); applicationContext = WebApplicationContextUtils … I have a spring web application and want to use application context in a … […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: