Difference between applicationContext.xml and spring-servlet.xml in Spring Framework
Spring lets you define multiple contexts in a parent-child hierarchy.
The applicationContext.xml
defines the beans for the "root webapp context", i.e. the context associated with the webapp.
The spring-servlet.xml
(or whatever else you call it) defines the beans for one servlet's app context. There can be many of these in a webapp, one per Spring servlet (e.g. spring1-servlet.xml
for servlet spring1
, spring2-servlet.xml
for servlet spring2
).
Beans in spring-servlet.xml
can reference beans in applicationContext.xml
, but not vice versa.
All Spring MVC controllers must go in the spring-servlet.xml
context.
In most simple cases, the applicationContext.xml
context is unnecessary. It is generally used to contain beans that are shared between all servlets in a webapp. If you only have one servlet, then there's not really much point, unless you have a specific use for it.
Scenario 1
In client application (application is not web application, e.g may be swing app)
private static ApplicationContext context = new ClassPathXmlApplicationContext("test-client.xml");
context.getBean(name);
No need of web.xml. ApplicationContext as container for getting bean service. No need for web server container. In test-client.xml there can be Simple bean with no remoting, bean with remoting.
Conclusion: In Scenario 1 applicationContext and DispatcherServlet
are not related.
Scenario 2
In a server application (application deployed in server e.g Tomcat). Accessed service via remoting from client program (e.g Swing app)
Define listener in web.xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
At server startup ContextLoaderListener
instantiates beans defined in applicationContext.xml.
Assuming you have defined the following in applicationContext.xml:
<import resource="test1.xml" />
<import resource="test2.xml" />
<import resource="test3.xml" />
<import resource="test4.xml" />
The beans are instantiated from all four configuration files test1.xml, test2.xml, test3.xml, test4.xml.
Conclusion: In Scenario 2 applicationContext and DispatcherServlet
are not related.
Scenario 3
In a web application with spring MVC.
In web.xml define:
<servlet>
<servlet-name>springweb</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springweb</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
When Tomcat starts, beans defined in springweb-servlet.xml are instantiated.
DispatcherServlet
extends FrameworkServlet
. In FrameworkServlet
bean instantiation takes place for springweb . In our case springweb is FrameworkServlet.
Conclusion: In Scenario 3 applicationContext and DispatcherServlet
are not related.
Scenario 4
In web application with spring MVC. springweb-servlet.xml for servlet and applicationContext.xml for accessing the business service within the server program or for accessing DB service in another server program.
In web.xml the following are defined:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>springweb</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springweb</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
At server startup, ContextLoaderListener
instantiates beans defined in applicationContext.xml; assuming you have declared herein:
<import resource="test1.xml" />
<import resource="test2.xml" />
<import resource="test3.xml" />
<import resource="test4.xml" />
The beans are all instantiated from all four test1.xml, test2.xml, test3.xml, test4.xml. After the completion of bean instantiation defined in applicationContext.xml, beans defined in springweb-servlet.xml are instantiated.
So the instantiation order is: the root (application context), then FrameworkServlet.
Now it should be clear why they are important in which scenario.
One more point I want to add. In spring-servlet.xml
we include component scan for Controller package.
In following example we include filter annotation for controller package.
<!-- Scans for annotated @Controllers in the classpath -->
<context:component-scan base-package="org.test.web" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
In applicationcontext.xml
we add filter for remaining package excluding controller.
<context:component-scan base-package="org.test">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>