Among the different customers I worked for, I noticed a widespread misunderstanding regarding the use of Spring contexts in Spring MVC.
Basically, you have contexts, in a parent-child relationship:
- The main context is where service beans are hosted. By convention, it is spawned from the
/WEB-INF/applicationContext.xmlfile but this location can be changed by using the
contextConfigLocationcontext parameter. Alternatively, one can use the
AbstractAnnotationConfigDispatcherServletInitializerand in this case, configuration classes should be parts of the array returned by the
- Web context(s) is where Spring MVC dispatcher servlet configuration beans and controllers can be found. It is spawned from
<servlet-name>-servlet.xmlor, if using the JavaConfig above, comes from classes returned by the
As in every parent-child relationship, there’s a catch:
|Beans from the child contexts can access beans from the parent context, but not the opposite.|
That makes sense if you picture this: I want my controllers to be injected with services, but not the other way around (it would be a funny idea to inject controllers in services). Besides, you could have multiple Spring servlets with its own web context, each sharing the same main context for parent. When it goes beyond controllers and services, one should decide in which context a bean should go. For some, that’s pretty evident: view resolvers, message sources and such go into the web context; for others, one would have to spend some time thinking about it.
A good rule of thumb to decide in which context which bean should go is the following: IF you had multiple servlets (even if you do not), what would you like to share and what not.
|This way of thinking should not be tied to your application itself, as otherwise you’d probably end up sharing message sources in the main application context, which is a (really) bad idea.|
This modularization let you put the right bean at the right place, promoting bean reusability.