在web.xml中配置
<servlet>
<servlet-name>citic</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/frm-servlet.xml,/WEB-INF/app-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
先看继承关系:
public class DispatcherServlet extends FrameworkServlet
public abstract class FrameworkServlet extends HttpServletBean
public abstract class HttpServletBean extends HttpServlet
知道最终继承的是javax.servlet.http.HttpServlet类,大家都知道在初始化一个Servlet的时候会默认调用定义的int()方法,所有肯定我们要在这个方法上做文章,这个方法在HttpServletBean 中重写。
类中的重要代码如下:
@Override
public final void init() throws ServletException {
// 交给子类FrameworkServlet 实现
initServletBean();
到FrameworkServlet 中initServletBean内部代码:
this.webApplicationContext = initWebApplicationContext();
initFrameworkServlet();
protected WebApplicationContext initWebApplicationContext() {
onRefresh(wac);
}
好了,onRefresh是最终要在我们接触到的类DispatcherServlet中实现的方法,直接定位DispatcherServlet类的内部代码。
@Override
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
/**
* Initialize the strategy objects that this servlet uses.
* <p>May be overridden in subclasses in order to initialize further strategy objects.
* <p>这是最终执行的方法刷新,,它是在WebApplicationContext已经存在的情况下进行的,也就意味着在初始化它的时候,
* IOC容器应该已经工作了,这也是我们在web.xml中配置Spring的时候,需要把DispatcherServlet的 load-on-startup的属性配置为2的原因。
*/
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
初始化Handler映射,例如@RequestMapping(value = "/something", method = RequestMethod.PUT)
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
哦了,看到这么多初始化我们就放心了,因为这里的每一个方法都是Spring的大牛之处,其中不乏大量的使用注解的声明方式(注解的分享在Spring注解一文说明)
下面我们来一个一个的分享下上面的一系列init操作。
&& initMultipartResolver(context)
作用:初始化Spring的文件上传解析器。
private void initMultipartResolver(ApplicationContext context) {
this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
只是简单的从ApplicationContext (相当于bean工厂)得到需要类型的对象。
&&initLocaleResolver(context)
web应用程序支持国际化,必须识别每个用户的首选区域,并根据这个区域显示内容。
在Spring MVC应用程序中,用户的区域是通过区域解析器来识别的,它必须实现LocaleResolver接口(在Spring-LocaleResolver中详细讲解)。
private void initLocaleResolver(ApplicationContext context) {
this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);
…………
catch (NoSuchBeanDefinitionException ex) {
// We need to use the default.
this.localeResolver = getDefaultStrategy(context, LocaleResolver.class);
这里注意如果没有会得到默认的localeResolver ,定义实在属性文件DispatcherServlet.properties中org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
就是AcceptHeaderLocaleResolver类
&&ThemeResolver主题解析
初始化过程和上面的LocaleResolver方式是一样的,如果没有定义会得到默认配置的org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
&&initHandlerMappings
作用:初始化与用户请求相关联的控制器
// 这里找到所有在上下文中定义的HandlerMapping,同时把他们排序
// 因为在同一个上下文中可以有不止一个handlerMapping,所以我们把他们都载入到一个链里进行维护和管理
Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
很简单,就是从bean工厂得到给定类型的所有的bean。Spring中默认定义的为BeanNameUrlHandlerMapping和DefaultAnnotationHandlerMapping
*Spring是怎样加载用户定义的HandlerMapping将在《Spring MVC-HandlerMapping》中分享,点击这里前往Spring MVC-HandlerMapping
&&initHandlerAdapters
作用:处理用户的请求。
HandlerMappings是找到用户的请求对应的处理类和函数,HandlerAdapter任务是执行找到的函数,在执行之前有一系列的初始化操作。
Spring中默认定义的为HandlerAdapter为HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、AnnotationMethodHandlerAdapter
*Spring是怎样加载用户定义的HandlerAdapter将在《Spring MVC-HandlerAdapter》中分享,点击网址前往Spring MVC-HandlerAdapter
&& initHandlerExceptionResolvers
作用:初始化异常解析器,就是在handle请求的时候对于产生的异常如何处理,其实就是对response对象的设置,还有就是返回ModelAndView对象。
*Spring是怎样加载用户定义的HandlerAdapter将在《Spring MVC-HandlerExceptionResolver》中分享,点击网址前往Spring MVC-HandlerExceptionResolver
&& initRequestToViewNameTranslator
作用:将请求转换为对应的视图名称
Spring中默认定义的为HandlerAdapter为AnnotationMethodHandlerExceptionResolver、ResponseStatusExceptionResolver和DefaultHandlerExceptionResolver。
Spring是怎样加载用户定义的HandlerAdapter将在《Spring MVC-RequestToViewNameTranslator》中分享
&&initViewResolvers(context)
作用:视图解析
Spring中默认定义的为ViewResolver为InternalResourceViewResolver
Spring是怎样加载用户定义的HandlerAdapter将在《Spring MVC-ViewResolver》中分享