美文网首页
1. DispatcherServlet

1. DispatcherServlet

作者: banalite | 来源:发表于2017-10-16 18:09 被阅读0次

    1.1 DispatcherServlet与WebApplicationContext

    • DispatcherServlet基于Servlet实现,用于映射请求,并分发请求到指定的模块进行处理。
    • WebApplicationContext通过扩展ApplicationContext实现,用于DispatcherServlet的配置。
    • WebApplicationContext关联了ServletContext和Servlet ,可以利用RequestContextUtils中的静态方法查找WebApplicationContext。

    1.2 WebApplicationContext的层次结构

    • 对于多数应用来说,拥有一个单独的WebApplicationContext已经足够。但是也可以在多个DispatcherServlet实例之间分享一个根WebApplicationContext,同时每个DispatcherServlet拥有自己的子WebApplicationContext。
    • 根WebApplicationContext包含了基础性的beans,可以在多个Servlet实例中分享。如下图所示,展示了这种层次结构(图片来至Spring官网):


      mvc-context-hierarchy.png

    1.3 DispatcherServlet的请求处理过程

    处理过程在介绍DispatcherServlet的处理过程前,先介绍一下DispatcherServlet处理过程中用到的几个bean:

    bean类型 说明
    HandlerMapping 将请求映射到处理器以及一系列的HandlerInterceptor拦截器,在拦截器中包含了pre-和post-等处理,具体可以查看对应接口定义。同时,映射规则基于HandlerMapping 的具体实现类来定义。
    HandlerAdapter 帮助DispatcherServlet调用请求所映射的处理器,这样做的目的是为了对DispatcherServlet隐藏调用处理器的具体实现过程,而DispatcherServlet只需要通过HandlerAdapter来实现调用即可。
    HandlerExceptionResolver 解决异常的策略,可以将异常映射到处理器,或者返回错误页面等
    ViewResolver 根据处理器返回的视图名称对应到具体的视图(页面),并返回。
    LocalResolver & LocalContextResolver 解决时区以及国际化问题。
    ThemeResolver 提供了网页应用主题的切换
    MultipartResolver 提供了文件上传等类型服务
    FlashMapManager 提供输入输出的FlashMap的数据存储与检索,FlashMap用于在不同的请求之间传递属性值,例如重定向的时候

    下面是DispatcherServlet的处理过程:

    1. 搜索WebApplicationContext并将其作为一个属性绑定到request上,属性的key:DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE,因此在controller中或者后续的处理过程中可以通过request获取到WebApplicationContext。
    2. LocalResolver绑定到request, 用于后续国际化的处理,当然,这不是必须的。
    3. 绑定ThemeResolver到request,用于判断主题的使用,这也不是必须的。。
    4. 如果指定了multipart文件解析器,则会检查request中的multipart数据,如果发现数据,request会被包装成MultipartHttpServletRequest以进行进一步的处理。
    5. 执行处理,处理过程在一条处理链(preprocessors, postprocessors, and controllers)中完成
    6. 完成处理后返回视图或者数据,也可能在拦截器中直接返回。

    1.4 在web.cml中配置DispatcherServlet

    <web-app>
    <!--  用于装配ApplicationContext的配置信息  -->
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
    <!--  配置文件路径,提供给ContextLoaderListener使用,默认会去/WEB-INF/下加载applicationContext.xml  -->
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/root-context.xml</param-value>
      </context-param>
    <!--  配置DispatcherServlet,并制定其配置文件路径  -->
      <servlet>
        <servlet-name>app1</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/app1-context.xml</param-value>
        </init-param>
        <!--  应用启动即初始化这个servlet,大于0且越小则越优先,小于等于0则不自动启动  -->
        <load-on-startup>1</load-on-startup>
      </servlet>
      <!--  将请求路径与servlet做映射  -->
      <servlet-mapping>
        <servlet-name>app1</servlet-name>
        <url-pattern>/app1/*</url-pattern>
      </servlet-mapping>
    
    </web-app>
    

    1.5 在代码中配置DispatcherServlet

    先说一下DispatcherServlet 初始化值得三个参数:

    参数 说明
    contextClass 实现了WebApplicationContext接口,默认实现为XmlWebApplicationContext
    contextConfigLocation 配置文件路径,如果有多个利用逗号隔开,如果路径重复,则选用最后一个路径
    namespace WebApplicationContext的命名空间,默认为[servlet-name]-servlet

    在Servlet3及以上版本,可以使用代码配置Servlet,如下例注册了一个DispatcherServlet:

    import org.springframework.web.WebApplicationInitializer;
    
    public class MyWebApplicationInitializer implements WebApplicationInitializer {
            @Override
            public void onStartup(ServletContext container) {
                    //WebApplicationContext的默认实现类
                    XmlWebApplicationContext appContext = new XmlWebApplicationContext();
                    //设置配置文件地址
                    appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
                    //注册
                    ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet(appContext));
                    registration.setLoadOnStartup(1);
                    registration.addMapping("/");
            }
    }
    

    WebApplicationInitializer 是由Spring MVC提供的接口,Spring MVC会自动检测用户的实现类,并执行初始化。如果要使用代码执行DispatcherServlet初始化,利用AbstractDispatcherServletInitializer 这个抽象类更简单,如下:

    public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {
    
            @Override
            protected WebApplicationContext createRootApplicationContext() {
                    return null;
            }
    
            @Override
            protected WebApplicationContext createServletApplicationContext() {
                    XmlWebApplicationContext cxt = new XmlWebApplicationContext();
                    cxt.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
                    return cxt;
            }
    
            @Override
            protected String[] getServletMappings() {
                    return new String[] { "/" };
            }
            //还可以直接添加Filter
            @Override
            protected Filter[] getServletFilters() {
                    return new Filter[] { new HiddenHttpMethodFilter(), new CharacterEncodingFilter() };
            }
    
    }
    

    相关文章

      网友评论

          本文标题:1. DispatcherServlet

          本文链接:https://www.haomeiwen.com/subject/xlwkuxtx.html