一:springMvc启动流程:

    1.1 容器一启动或者关闭,会触发监听器:ServletContextListener 的事件(实现 EventListener接口),ServletContextListener接口含有两个方法:

contextInitialized()以及 contextDestroyed() 分别是容器(tomcat)启动以及销毁时调用。其他实现了ServletContextListener接口的,都能监听到此事件。如 ShutdownListener:专门监听关闭事件以及 ContextLoadListener : springMvc的web.xml中需要配置该监听器,
<!-- Spring配置文件开始  -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath:spring/applicationContext.xml
    </param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring配置文件结束 -->

主要是用于监听spring配置文件初始化情况

  1.2  DispatcherServlet启动时,加载配置:

protected void initStrategies(ApplicationContext context) {
    this.initMultipartResolver(context);
    this.initLocaleResolver(context);
    this.initThemeResolver(context);
    this.initHandlerMappings(context);
    this.initHandlerAdapters(context);
    this.initHandlerExceptionResolvers(context);
    this.initRequestToViewNameTranslator(context);
    this.initViewResolvers(context);
    this.initFlashMapManager(context);
}

    里面的 initThemeResolver 初始化主题解析:后台代码:

<!--theme-->
    <bean id="themeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource">
        <!--加载资源-->
        <property name="basenamePrefix" value="theme."/>
    </bean>
    <!-- 【可选】 -->
    <!-- 默认情况下,使用的是 FixedThemeResolver 来确定主题名字,默认名字为 theme -->
    <!-- 可以根据实际情况配置为 SessionThemeResovler/CookieThemeResolver -->
    <bean id="themeResolver" class="org.springframework.web.servlet.theme.SessionThemeResolver">
        <!--默认主题文件的名字是 "xxxx",如果不设置,名为 theme-->
        <property name="defaultThemeName" value="default"/>
    </bean>

 

 

 

package com.oukele.web;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ThemeResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
public class ThemeController {

    //将theme注入容器中
    @Autowired
    private ThemeResolver themeResolver;

    /**
     * 返回一个页面
     * */
    @GetMapping(path = "/th")
    public  String getPage(){
        return "theme1";
    }

    /**
     *请求方式:GET
     * 参数:theme
     * 请求url:/th/对应主题的文件
    */
    @RequestMapping(path = "th/{theme}",method = RequestMethod.GET)
    public String theme1(@PathVariable("theme") String themeStr,HttpServletRequest request,HttpServletResponse response){
        themeResolver.setThemeName(request,response, themeStr);
        return "redirect:/th";
    }

}

二:解析 initHandlerMappings(路径映射)

       2.1 通过 context 获取 DispatcherServlet 的属性 private List<HandlerMapping> handlerMappings;

             其中 handlerMappings 初始化后类型有四个:RequestMappingHandlerMapping、BeanNameUrlHandlerMapping、SimpleUrlHandlerMapping(0,1),应该是用于初始化 handlerMapping的策略

三:解析 initHandlerAdapters 

       3.1 通过 context 转化的 beanFactory 中获取 DispatcherServlet 的属性 private List<HandlerAdapter> handlerAdapters;

          其中 handlerAdapters 初始化后的类型(策略)有:RequestMappingHandlerAdapter、HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter 

四:解析 initHandlerExceptionResolvers

       4.1 通过 context 转化的 beanFactory 中获取 DispatcherServlet 的属性 private List<HandlerExceptionResolver> handlerExceptionResolvers;

          其中 handlerExceptionResolvers初始化后的类型(策略)有:ExceptionHandlerExceptionResolvers、ResponseStatusExceptionResolvers、DefaultHandlerExceptionResolvers、SimpleMappingExceptionResolvers

五:解析 initViewResolvers

      属性为:private List<ViewResolver> viewResolvers;

      其中 viewResolver初始化后的类型(策略)有:

      默认viewResolver 解析后 ,会包含设置的前后缀:

springmvc有启动类配置 springmvc启动过程_springmvc有启动类配置

其中的前后缀是通过配置:

<bean id="defaultViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:order="1">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    <property name="contentType" value="text/html"/>
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
</bean>

来获取到的,默认加载此实现类。

所有请求都是先到达 DispatcherServlet,(调用其父类 FrameworkServlet 的service方法,从而)调用其 doDispatch()方法来进行处理
        try {
            this.doService(request, response);
        } catch (ServletException var17) {

然后获取 HandlerExecutionChain 对象:
    mappedHandler = this.getHandler(processedRequest);
                    if (mappedHandler == null || mappedHandler.getHandler() == null) {
                        this.noHandlerFound(processedRequest, response);
                        return;
                    }
在这个过程中,先通过 httpServletReqest 对象获取 HandlerMethod 对象 :形式:
public java.util.Map com.bestpay.bigdata.ops.web.controller.IndexController.getPermAndBtList()
该handlerMethod包含该类所在的controller以及方法,并从beanFactory中通过类名获取实例:handler
初始化过程:
  private HandlerMethod(HandlerMethod handlerMethod, Object handler) {
        Assert.notNull(handlerMethod, "HandlerMethod is required");
        Assert.notNull(handler, "Handler object is required");
        this.bean = handler;
        this.beanFactory = handlerMethod.beanFactory;
        this.method = handlerMethod.method;
        this.bridgedMethod = handlerMethod.bridgedMethod;
        this.parameters = handlerMethod.parameters;
    }
也就是说 handlerMethod对象中的属性 this.bean就是上面解析出来的handler, this.method 就是通过request获取
的方法,以及parameters等等
代码:
public HandlerMethod createWithResolvedBean() {
        Object handler = this.bean;
        if (this.bean instanceof String) {
            String beanName = (String)this.bean;
            handler = this.beanFactory.getBean(beanName);
        }
this.bean 就是当前请求(request)获取的类,如:indexController
此时下面 的handler就是上面返回的 handlerMethod对象
            return this.getHandlerExecutionChain(handler, request);
该方法内部:
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
        HandlerExecutionChain chain = handler instanceof HandlerExecutionChain ? (HandlerExecutionChain)handler : new HandlerExecutionChain(handler);
        chain.addInterceptors(this.getAdaptedInterceptors());
        String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
通过new HandlerExecutionChain(hanler)构造包装
 public HandlerExecutionChain(Object handler, HandlerInterceptor[] interceptors) {
        this.interceptorIndex = -1;
        if (handler instanceof HandlerExecutionChain) {
            HandlerExecutionChain originalChain = (HandlerExecutionChain)handler;
            this.handler = originalChain.getHandler();
把原先的 handlerMethod对象,封装成自身的一个属性 handler(包装在handlerExecutionChain对象在,也叫handler)
然后通过方法:
 HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
获取 handlerAdapter 对象,过程:循环 上述三种类型的 handlerAdapter,然后通过下面代码:
 Iterator var2 = this.handlerAdapters.iterator();
        HandlerAdapter ha;
               this.logger.trace("Testing handler adapter [" + ha + "]");
            }
        } while(!ha.supports(handler));

public boolean supports(Object handler) {
        return handler instanceof HttpRequestHandler;
    }
     return handler instanceof Servlet;
    }
     return handler instanceof Controller
    }
也就是循环判断三种类型,当前的 handler(也就是上面的 handlerMethod)是哪种类型的handler,获取对应类型
的 handlerAdapter