protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
Manages WebApplicationContext instance per servlet
Highly customizable supporting installation of different adapter classes
Central dispatcher for HTTP request handlers/controllers
Publishes events on request processing
package javax.servlet;
import java.util.EventListener;
public interface ServletContextListener extends EventListener {
public void contextInitialized(ServletContextEvent sce);
public void contextDestroyed(ServletContextEvent sce);
}
Notified of context initialization before any filters or servlets in the web application are initialized
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
WEB-INF/web.xml
org.springframework.web.context.ContextLoaderListener
public void contextInitialized(ServletContextEvent event) {
this.contextLoader = createContextLoader();
if (this.contextLoader == null) {
this.contextLoader = this;
}
this.contextLoader.initWebApplicationContext(event.getServletContext());
//org.springframework.web.context.ContextLoader#initWebApplicationContext
}
contextClass
contextConfigLocation
Configuration:
Context Loader Performs the actual initialization work for the root application context
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.XmlWebApplicationContext</param-value>
</context-param>
i. xml based configuration
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
@EnableWebMvc
ii. annotation based configuration
contextClass configuration
contextConfigLocation configuration
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext1.xml, WEB-INF/applicationContext2.xml</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/*Context.xml,WEB-INF/spring*.xml</param-value>
</context-param>
i.
ii.
iii.
iv.
/** Default config location for the root context */
public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
Loading the xml document
- org.springframework.beans.factory.xml.DefaultDocumentLoader
Default: javax.xml.parsers.DocumentBuilder
java -Djavax.xml.parsers.DocumentBuilderFactory=oracle.xml.jaxp.JXDocumentBuilderFactory
BeanDefinitionRegistry
Interface for registries that hold bean definitions
org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition
private boolean allowBeanDefinitionOverriding = true;
Responsibility
public interface Ordered {
int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
int getOrder();
}
//DispatcherServlet.properties
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
BeanNameUrlHandlerMapping
beans with names that start with a slash ("/")
<bean id="/oldHome" class="net.therap.controller.OldProjectController"></bean>
<bean id="/oldHome.html" class="net.therap.controller.OldProjectController"></bean>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/project.htm">oldProjectController</prop>
<prop key="/oldProject*">oldProjectController</prop>
<prop key="/pilotProject">oldProjectController</prop>
</props>
</property>
</bean>
<bean name="oldProjectController" class="net.therap.controller.OldProjectController"/>
SimpleUrlHandlerMapping
Request Resolving
org.springframework.web.servlet.DispatcherServlet#getHandler(javax.servlet.http.HttpServletRequest)
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
for (HandlerMapping hm : this.handlerMappings) {
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
return null;
}
For annotated request mapping
1. DefaultAnnotationHandlerMapping (@deprecated in spring mvc 3.2) in favor of
2. RequestMappingHandlerMapping (From spring mvc 3.1)
What's new
- preHandle()
after: HandlerMapping determined handler object
before: HandlerAdapter invokes the handler
- postHandle()
after: HandlerAdapter actually invoked the handler
before: DispatcherServlet renders the view
- afterCompletion()
after: rendering the view
invoked in reverse order, so the first interceptor will be the last to be invoked.
<mvc:interceptors>
<bean id="webContentInterceptor" class="org.springframework.web.servlet.mvc.WebContentInterceptor">
<property name="cacheSeconds" value="0"/>
<property name="useExpiresHeader" value="true"/>
<property name="useCacheControlHeader" value="true"/>
<property name="useCacheControlNoStore" value="true"/>
</bean>
</mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/resources/**"/>
<bean class="net.therap.interceptor.ProfilerInterceptor"/>
</mvc:interceptor>
ProfilerInterceptor extends HandlerInterceptorAdapter
public interface HandlerMapping {
...
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}
public class HandlerExecutionChain {
private final Object handler;
private HandlerInterceptor[] interceptors;
private List<HandlerInterceptor> interceptorList;
}
org.springframework.web.servlet.DispatcherServlet#doDispatch
#1 Determining HanlderMapping for current request
public interface HandlerAdapter {
boolean supports(Object handler);
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
long getLastModified(HttpServletRequest request, Object handler);
}
#2 Determining HanlderAdapter
1. mappedHandler.applyPreHandle(processedRequest, response) // HandlerExecutionChain
Invoke preHandle() of all registered interceptors
3. Determines viewName, if not provided - viewNameTranslator.getViewName(request)
2. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
4. Invoke postHandle() of all registered interceptors in reverse order
5. Render view
1. Map<Class<?>, ServletHandlerMethodResolver> methodResolverCache
2. AnnotationUtils.findAnnotation(method, RequestMapping.class)
First Step
Second Step
#2 Determining HanlderAdapter