Let's go into detail step by step
DispatcherServlet uses Handlers to decide "which controller" to serve
that request
The DispatcherServlet
maintains an ordered List
of HandlerMapping
beans (which it loaded from the WebApplicationContext
). A HandlerMapping
is
Interface to be implemented by objects that define a mapping between
requests and handler objects.
When the DispatcherServlet
receives a request, it iterates over this list until it finds a matching handler object for the request in question. For simplicity, let's consider only RequestMappingHandlerMapping
.
A bean of this type stores a mapping of @RequestMapping
annotated methods (the actual Method
object retrieved with reflection) stored as a HandlerMethod
instances and wrapped in RequestMappingInfo
objects that hold mapping data for matching the request, ie. URL, headers, and request parameters.
The DispatcherServlet
retrieves the best matching HandlerMethod
from these and any corresponding HandlerInterceptor
instances which you may have registered. It retrieves these as a HandlerExecutionChain
object. It will first apply any pre-handling by HandlerInterceptor
s. It will then try to invoke your HandlerMethod
. This will typically (but not always) be a @RequestMapping
annotated method inside a @Controller
annotated class. This produces what Spring calls a dispatch result. The DispatcherServlet
then applies post-handling by the HandlerInterceptor
s. It finally processes the dispatch result depending on what it is. You can see the supported return types for an idea of what that can be.
The controllers are/should be "light-weighted"-- should be decoupled
from the service processes at back end as a good design practice--
they hold references to the service(s) and invoke the right one(s).
Their "mission" is to control the service process(es) for building the
model and handing it back to the dispatcher for the next step.
In an MVC application, the controller controls operations by making changes to the model. You can do this directly in your controller or you can decouple it by implementing and providing service and business classes for that purpose. The controller depends on these, but not the other way around. Check out multilayered architectures.
The controller then builds the model (Model
) which the DispatcherServlet
possibly makes available to the view. I say possibly because the controller can produce a response directly without any view (think jsp
) involved.
The View component in itself has 2 parts: first the ViewResolver picks
the right type of look for View to put the model into the final format
for the user.
In the typical case where the Controller handler method would return a Model
, View
, ModelAndView
, String
(and some others) object, then a ViewResolver
would handle finding the correct View
. The DispatcherServlet
then tries to render that view by first merging the model as you said. This usually means taking all Model
attributes and putting them into the HttpServletRequest
attributes. The rendering step can involve rendering a jsp
, generating XML, or anything at all really.
From the developer's angle-- the DispatcherServlet is a
behind-the-scenes thing. All i do is to define, and configure it, if
necessary, in web.xml. As the developer, I instantiate an
ApplicationContext (there are many ApplicationContext types-- i pick
one depending on what i need, typically the WebApplicationContext(?)
).
You don't actually need to instantiate it. The DispatcherServlet
will do that itself (or use the ContextLoaderListener
's) when the Servlet
container calls init()
on it. It will generate its own WebApplicationContext
. What you can do is decide which subclass of WebApplicationContext
to use. This is an important choice if you want to load your context from XML or from a Java configuration. You can do this by providing an <init-param>
.
AplicationContext is the factory that creates all the servlets/beans
including the DispatcherServlet, using their descriptions in the .xml
files. The DispatcherServlet then runs behind the scenes and manages
the entire process-- goes&gets the controllers, using the annotations
or the their .xml descriptions, views, handlers, validators etc.
The ApplicationContext
is also known as the Inversion of Control Container. It does not include the DispatcherServlet
. The DispatcherServlet
is managed by the Servlet
container and not by Spring. However, it does primarily take its configuration from Spring's ApplicationContext
(WebApplicationContext
). It registers a number of special beans it finds in the context. You can declare these yourself or let Spring do it for you with this little bit of XML
<mvc:annotation-driven>
This will (mostly) take care of doing what you describe, ie. registering handlers, validators, views, etc.
I am wondering whether this description is holds-- valid&complete, and
whether there are big missing pieces in it.
Don't forget that a Spring MVC web application is a Servlet
web application. The lifecycle of the application is therefore tied to the Servlet
container.