Using STS in eclipse to create an mvc project I notice that the servlet-context.xml seems to be written to be used in both the root context and the dispatcherservlet Context. I say this because I notice that the context:component-scan is in it, which is often loaded into the root context, but it is loaded into the dispatcherservlet context. I also noticed a sample spring mvc/jpa project - http://duckranger.com/2012/04/spring-mvc-3-x-with-sts-tutorial-part-iii-add-some-jpa/ - that specifically loads the servlet-context.xml into both contexts. I thought the idea was to keep a clean separation between the contexts. Can someone explain this to me?
2
votes
1 Answers
6
votes
The following configuration is plain wrong
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:META-INF\root-context.xml
classpath:META-INF\servlet-context.xml
classpath:META-INF\datasource.xml
</param-value>
</context-param>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:META-INF\servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
- Your root and servlet context should NEVER import the same files, as the beans from the root context will already be available in the servlet context because of the context hierarchy in Spring. There is no point to create copies of them in the different contexts(especially because the beans in the root context will be shadowed by the ones in the servlet context, for example if you declare
<tx:annotation-driven>
only in the root context it will not affect the behavior of the servlet context beans, which will force you to tangle configuration even more) . - It's very illogical to put
<jpa:repositories>
into the servlet context, because it's VERY likely that you will use the repositories from the service layer. - Typically you should not put anything but the MVC configuration to the servlet context. It's the root web app context where the services should live. Servlet context provides separation of the controllers from the services, so when you test your services with Spring Test Context framework you don't have to create the controllers(if you want to test the mappings you should use Spring MVC Test framework) and test the application services directly. To be clear, if we examine the figure from the Hexagonal Architecture article
the the servlet context should contain only user-side API related things but not the application. It is arguable whether you should divide the configuration of the root web app context and put data-side-api into separate configuration file but the question was about servlet/root contexts.
Just to be less abstract here's some informal diagram of what I typically keep in mind(in terms of Spring contexts and bean configuration files) when configure a Spring application(of course it's all subjective, it's not a super solution and actually is a bit over complicated - it's unlikely that I will need so many servlets and configuration files)