As I understand, a Spring based web application is initialized as below:
Step 1: Servlet container (e.g. Tomcat)
locates the implementation of ServletContainerInitializer
, which is SpringServletContainerInitializer
.
Step 2: SpringServletContainerInitializer
creates DispatcherServlet
and ContextLoaderListener
Step 3: DispatcherServlet
creates servlet application context
. And ContextLoaderListener
creates root application context
.
Step 1 is defined by Servlet 3.0 spec. Step 2, 3 are totally defined by Spring.
I can see the rational of putting web
beans in servlet context and non-web
beans in root context. But why do we have to create these 2 contexts in different places, i.e. DispatcherServlet
and ContextLoaderListener
?
If all we want is just to prepare everything necessary, why not just create both contexts in ContextLoaderListener
since it can be seen as the main()
method of the whole web application. I think that's more logic and current approach only complicates things up.
ADD 1
Based on @Shailendra's reply, I draw this:
My understanding is, Spring introduced the application context
concepts and store them in the Servlet Context
. Servlet Context is a concept introduced by java servlet technolgoy.
I guess the DispatcherServlet
implementation should have a member variable to hold the key
to its servlet application context
in the servlet context
. So it can access it's own context. Maybe the key is the servlet name.
And the root application context
should have a well-known key so everyone can access it.
ADD 2
The well-known key for root application context
is this:
(in org.springframework.web.context.WebApplicationContext
)
String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
ADD 3
The DispatcherServlet
does have a reference to its WebApplicationContext
. It inherits the following memeber from FrameworkServlet
:
/** WebApplicationContext for this servlet */
private WebApplicationContext webApplicationContext;
And
public FrameworkServlet(WebApplicationContext webApplicationContext) {
this.webApplicationContext = webApplicationContext;
}
non-web
beans? If your application is running in a servlet container the only context should be the servlet one, AFAIK. Spring also lets you create as many context as you want, but this only will make things more complicated. – Xtreme Bikernon-web
beans, I mean those for back-end operations. – smwikipediaDispatcherServlet
creates its own context, you can have multipleDispatcherServlet
s how should theContextLoaderListener
know how many servlets there are and how to configure the context for those. It is not the task / responsibility of each of them. Also it isn't required to have aContextLoaderListener
you can do perfectly without it, so how would you bootstrap your application then? Also the differentApplicationContext
instances are all stored in theServletContext
under well known names, as that is also how theDispatcherServlet
detects the (optional) root context. – M. DeinumContextLoaderListener
to load the child contexts. Also there are more types of servlets constructing anApplicationContext
like theMessageDispatcherServlet
for Spring WebServices. – M. Deinum