Spring Web Application Context Visibility

spring framework logoWhile developing a Web App using Spring little things can take a lot of time to resolve. At the end they may appear to be very simple, and you may ask your self “how could I not think of it before – it is so obvious!”. Well, yea, it is obvious, but you just have to know it! One of the places that helps you to solve the “obvious” (and not so obvious), so you do not have to spin your wheels is, with no doubts, the spring forum. However you need to know the right search criteria to find what you need.

Here I just want to share something small but important about the visibility of Spring Contexts in a Web App.

Looking at org.springframework.web.servlet.DispatcherServlet API notice this:

“A web application can define any number of DispatcherServlets. Each servlet will operate in its own namespace, loading its own application context with mappings, handlers, etc. Only the root application context as loaded by ContextLoaderListener, if any, will be shared.”

This brings an interesting point – in a Spring Web App you have one root application context which is private, and many dispatcher servlet application contexts which are children of the root application context:

<context-param>
<param-name>contextConfigLocation</param-name>
   <param-value>
      /WEB-INF/classes/applicationContext.xml
      /WEB-INF/classes/otherContext.xml
   </param-value>
 </context-param>
 
...
 
 <servlet>
  <servlet-name>context</servlet-name>
  <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
 
...
 
 <servlet>
  <servlet-name>dispatcher-servlet-number-x</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>2</load-on-startup>
 </servlet>

In the above, everything that is defined in “contextConfigLocation” is your root application context. Every “dispatcher-servlet-number-x” (“dispatcher-servlet-number-1″, “dispatcher-servlet-number-2″, etc..) would represent a child application context which will see (have the visibility to) all the beans from the parent (root) context, but will not see any of the beans defined by its siblings – another dispatcher servlet contexts.

The only gotcha in the above visibility is BeanFactoryPostProcessor / BeanPostProcessor (s) – like “PropertyPlaceholderConfigurer” for example. These guys apply ONLY to beans in its own context. For example, if you have PropertyPlaceholderConfigurer defined in the root application context, none of root’s children will be able to use it (see) the ${properties}.

Here is the semi-official version “why” from Juergen (Spring Lead Developer):

“PropertyPlaceholderConfigurer is an implementation of the BeanFactoryPostProcessor interface: This interface and its sibling BeanPostProcessor just apply to the BeanFactory that defines them, that is, to the application context that defines them.

If you combine multiple config files into a single contextConfigLocation, a PropertyPlaceholderConfigurer defined in any of the files will apply to all of the files, because they are loaded into a single application context.

However, a DispatcherServlet has its own application context, just using the root web application context as parent. Therefore, it needs to define its own BeanFactoryPostProcessors and/or BeanPostProcessors, in this case its own PropertyPlaceholderConfigurer.”

Happy Springing!

10 comments

  1. that is nice to know…. I actually was stuck on the “properties” part for about an hour(!) before stumbled upon your blog – nice job!

    thank you

  2. Had the same problem here. Many thanks.

  3. Really struggled to find a concise explanation of why this was the case with the PPC. This explains it well. Thank you.

  4. This info was really useful. But, if I want to use dependency injection between the controller (defined in webapplication context) and the root context, how do I do it? I am using PPC in my root context to load properties in beans. Kind of stuck here.

  5. Well, I actually found a way around my problem mentioned above by using a filter and loading the root context in the filter, setting it as request attribute and then using beans from there. If anyone needs help, write to me at gautamgd at gmail

  6. I have spent a few days to resolve the problem you are talking about on a web application using transaction annotations.
    Your tip helped me to solve it, I have just copied my annotation declaration in my -servlet.xml and the transactions works.
    The problem is that I have two different spring contexts working. And as I had declared my services also with annotations @Service and @Component I had to declare also in my -servlet.xml the configuration

    So finally I got two instances of my services, This is quite disturbing when you are supposed to have singleton.
    Have you got another tip to solve that. Is this what Oskar is talking about when he reinjects the application context in the request? How Can I do It?

  7. Very helpful! It saved me from hours of going nowhere.

  8. Big thanks, good explanation.

  9. I’m using multiple application context file as mentioned in the above xml. but my dispatcher servlet is pointing the first application context file always not another one. please suggest me on this.

  10. Patryk Kałużny

    Than you! That really helps me :)

tell me something...
  1. (required)
  2. (valid email - optional)
  3. Captcha
  4. (required)