springmvc web.xml配置之 -- DispatcherServlet

springMVC servlet配置与启动

看一下springmvc的web.xml常见配置:

    <servlet>
        <!-- 配置DispatcherServlet -->
      <servlet-name>springMvc</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <!-- 指定spring mvc配置文件位置 不指定使用默认情况 -->
      <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:spring/spring-mvc.xml</param-value>
      </init-param>
      <!-- 设置启动顺序 -->
      <load-on-startup>1</load-on-startup>
  </servlet>

  <!-- ServLet 匹配映射 -->
  <servlet-mapping>
      <servlet-name>springMvc</servlet-name>
      <url-pattern>/</url-pattern>
  </servlet-mapping>

DispatcherServlet是一个特殊的Servlet,因此本文首先看看常规servlet的特性。

1. servlet特性

1.1 Servlet 启动过程

Servlet的启动过程如何? 难道和springmvc Ioc容器一样随web容器启动的时候就启动吗?

其实仔细想一想,可以猜出来Servlet并不一定是随web容器启动而创建,我们知道一个web容器中可能有非常多的Servlet,如果有百千个servlet,那服务器启动的时候就要实例化那么多个类,显然对于内存而言负载量相当的大。其实在web.xml的<servlet>标签中可以通过<load-on-startup>来控制Servlet的是否随web容器启动而初始化以及多个Servlet同时创建时的初始化顺序。

loadOnStartup设置分为三种情况:

  • loadOnStartup < 0 web容器启动的时候不实例化处理,servlet首次被调用时才被实例化 ,loadOnStartupm默认是这种(即没有配置时)。
  • loadOnStartup > 0 web容器启动的时候做实例化处理,顺序是由小到大,正整数小的先被实例化。
  • loadOnStartup = 0 web容器启动的时候做实例化处理,相当于是最大整数,因此web容器启动时,最后被实例化。

另外,<servlet-mapping>会拦截请求,然后对应的servlet处理这个请求。上述配置<url-pattern>/</url-pattern>表示拦截除了jsp以外的所有url,DispatchServlet将会处理这些请求。

1.2 Servlet 生命周期
  • Servlet 通过调用 init () 方法进行初始化。
  • Servlet 调用 service() 方法来处理客户端的请求。
  • Servlet 通过调用 destroy() 方法终止(结束)。
  • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

下图展示了一个典型的Servlet生命周期方案:

servlet初始化时由容器调用servlet的init()方法,调用servlet的ini()方法时会将ServletConfig对象传递给servlet,当用户发出HTTP请求后,会被委派到web容器(Servlet容器),多个请求同时发起时交由Servlet 容器线程池处理,线程池中分配多个线程处理任务,每个线程执行一个单一的 Servlet 实例的 service() 方法。

2. DispatcherServlet

DispatcherServlet本质上也是一个Servlet,从继承关系上看,它继承了HttpServletBean,HttpServletBean中实现了init()方法,因为在Web容器启动时将调用它的init方法,该方法的作用:

  1. 将Servlet初始化参数(init-param)设置到该组件上,主要ServletConfig对象传递给servlet。
  2. 提供给子类初始化扩展点,initServletBean()
2.1 Servlet 加载配置文件

(略)

2.1 初始化ServletBean

FrameworkServlet继承了HttpServletBean,它通过initServletBean()进行Web上下文初始化。

@Override
protected final void initServletBean() throws ServletException {
    try {
        // 1.初始化web上下文
        this.webApplicationContext = initWebApplicationContext();
        // 2. 提供给子类初始化的扩展点
        initFrameworkServlet();
    }catch
    ...
   }
}

initWebApplicationContext初始化WebApplicationContext:

protected WebApplicationContext initWebApplicationContext() {
        // 查找父容器,也就是web容器加载时ContextLoaderListener触发执行得到的IOC容器
        WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
        WebApplicationContext wac = null;
        if(this.webApplicationContext != null) {
          // 1.创建DispatherServlet自己的容器
            wac = this.webApplicationContext;
            if(wac instanceof ConfigurableWebApplicationContext) {
                ConfigurableWebApplicationContext attrName = (ConfigurableWebApplicationContext)wac;
                if(!attrName.isActive()) {
                    if(attrName.getParent() == null) {
                        // 1.1 指定父容器,即ContextLoaderListener过程加载的IOC容器
                        attrName.setParent(rootContext);
                    }
                    // 1.2 执行wac.refresh(),也就是容器初始化
                    this.configureAndRefreshWebApplicationContext(attrName);
                }
            }
        }

        if(wac == null) {
          // 2.查找已经绑定的上下文
           wac = this.findWebApplicationContext();
        }

        if(wac == null) {
            // 3.如果没有找到相应的上下文,并指定父亲为ContextLoaderListener
            wac = this.createWebApplicationContext(rootContext);
        }

        if(!this.refreshEventReceived) {
           // 4.刷新上下文(执行一些初始化)
            this.onRefresh(wac);
        }

        if(this.publishContext) {
            String attrName1 = this.getServletContextAttributeName();
            this.getServletContext().setAttribute(attrName1, wac);
            if(this.logger.isDebugEnabled()) {
                this.logger.debug("Published WebApplicationContext of servlet \‘" + this.getServletName() + "\‘ as ServletContext attribute with name [" + attrName1 + "]");
            }
        }

        return wac;
    }

从上看出DispatcherServlet会维持一个自己的WebApplicationContext,ContextLoaderListener中创建ApplicationContext作为rootContext,传入DispatcherServlet的容器中,然后初始化自己的Ioc容器。

这两个容器的区别:

  1. ContextLoaderListener创建的WebApplicationContext是共享于整个Web应用程序的。
  2. DispatcherServlet创建的ApplicationContext主要用于和该Servlet相关的一些组件,比如Controller、ViewResovler等。

另外一点,上述代码中的this.onRefresh(wac)过程会触发DispatchServlet初始话方法onRefresh(wac):

protected void onRefresh(ApplicationContext context) {
    this.initStrategies(context);
}

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);
}

这个过程就是Spring Web MVC框架初始化默认的使用的九大策略,这九大策略参考下篇文章。

原文地址:https://www.cnblogs.com/chenjunjie12321/p/9357580.html

时间: 2024-10-11 17:39:07

springmvc web.xml配置之 -- DispatcherServlet的相关文章

springmvc web.xml配置之SpringMVC IOC容器初始化

SpringMVC IOC容器初始化 首先强调一下SpringMVC IOC容器初始化有些特别,在SpringMVC中除了生成一个全局的spring Ioc容器外,还会为DispatcherServlet生成一个容器,具体的下一篇有讲述. 我们知道spring中单纯使用main函数就可以生成一个容器,如下: public class MainTest { public static void main(String[] args){ ApplicationContext appContext =

SpringMVC: web.xml中声明DispatcherServlet时一定要添加load-on-startup标签

游历SpringMVC源码后发现,在web.xml中注册的ContextLoaderListener监听器只是初始化了一个根上下文,仅仅完成了组件扫描和与容器初始化相关的一些工作,并没有探测到具体每个URL应当map到哪个Controller, 哪个方法上.而剩一下的这些复杂工作都是由DispatcherServet来完成的,即应用服务器加载DispatcherServlet调用init()方法时才能触发这项工作.所以,如果在web.xml中配置DispatcherServlet时不设置 <lo

SpringMVC: web.xml中声明DispatcherServlet时一定要加入load-on-startup标签

游历SpringMVC源代码后发现,在web.xml中注冊的ContextLoaderListener监听器不过初始化了一个根上下文,只完毕了组件扫描和与容器初始化相关的一些工作,并没有探測到详细每一个URL应当map到哪个Controller, 哪个方法上.而剩一下的这些复杂工作都是由DispatcherServet来完毕的,即应用server载入DispatcherServlet调用init()方法时才干触发这项工作.所以,假设在web.xml中配置DispatcherServlet时不设置

springmvc web.xml配置之ContextLoaderListener

首先回归一下web.xml的常用配置,看一个示例: <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring/applicationcontext-*.xml</param-value> </context-param> <listener> <listener-class>org.

Java web.xml 配置技巧—动态欢迎页地址--欺骗tomcat

我们的Java Web项目在配置web.xml 欢迎页地址默认是index.html .index.jsp ,不知道有人注意过没有,如果我要配置成/index/user.action  或者 /userList.do 什么的怎么办呢?你可能觉得直接配置就OK了,我告诉你不行.如果可以,你可以忽略本方法.下面讲讲如果不能配置动态地址,怎么办. 配置如下: <welcome-file-list> <welcome-file>/user/index.shtml</welcome-f

maven工程web层的web.xml配置文档内容

下面是web层,web.xml配置文档里面需要配置的东西: 1.lo4j配置 2.读取spring文件配置 3.设计路径变量值 4.spring字符集过滤器 5.登陆过滤器 6.springMVC核心配置 7.session过期时间 8.错误页面跳转 以下是实例: <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSch

基于注解的Spring MVC(所需jar包,web.xml配置,Spring文件配置,@Controller,@RequestMapping,@RequestParam,model填參,EL取值)

1.加入jar 2.web.xml配置: <?xml version="1.0" encoding="UTF-8"? > <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocati

Web.XML 配置学习

web.xml的作用(参考资料):https://www.cnblogs.com/yqskj/articles/2233061.html 每个javaEE工程中都有web.xml文件,那么它的作用是什么呢?它是每个web.xml工程都必须的吗? 一个web中可以没有web.xml文件,也就是说,web.xml文件并不是web工程必须的. web.xml文件是用来初始化配置信息:比如Welcome页面.servlet.servlet-mapping.filter.listener.启动加载级别等.

Spring MVC的web.xml配置详解(转)

出处http://blog.csdn.net/u010796790 1.spring 框架解决字符串编码问题:过滤器 CharacterEncodingFilter(filter-name) 2.在web.xml配置监听器ContextLoaderListener(listener-class) ContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext的配置信息.因为它实现了ServletContextListener这个接口,在web.