码迷,mamicode.com
首页 > 编程语言 > 详细

spring mvc之启动过程源码分析

时间:2018-01-25 16:43:17      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:产生   启动过程   ping   igp   了解   信息   ogg   调用   图片   

  • 简介

这两个星期都在看spring mvc源码,看来看去还是还是很多细节没了解清楚,在这里把看明白的记录下,欢迎在评论中一起讨论。

一、铺垫

spring mvc是基于servlet的,在正式分析之前,我们来看一下servlet的知识。servlet的生命周期通过三个方法init、service、destory来构建的。

  • init():

在Servlet的生命周期中,仅执行一次init()方法。它是在服务器装入Servlet时执行的,负责初始化Servlet对象。可以配置服务器,以在启动服务器或客户机首次访问Servlet时装入Servlet。无论有多少客户机访问Servlet,都不会重复执行init()。

  • service():

它是Servlet的核心,负责响应客户的请求。每当一个客户请求一个HttpServlet对象,该对象的Service()方法就要调用,而且传递给这个方法一个“请求”(ServletRequest)对象和一个“响应”(ServletResponse)对象作为参数。在HttpServlet中已存在Service()方法。默认的服务功能是调用与HTTP请求的方法相应的do功能。

  • destroy():

仅执行一次,在服务器端停止且卸载Servlet时执行该方法。当Servlet对象退出生命周期时,负责释放占用的资源。一个Servlet在运行service()方法时可能会产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成。

二、spring mvc启动过程

spring mcv的入口是DispatcherServlet,顾名思义就是调度servlet是服务请求调度,它的继承结构如下:

 

 技术分享图片

在整合spring mvc时,web.xml有这样配置,相信用过的都知道

<servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:mvc-dispatcher.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

那根据servlet的知识,在服务器启动,创建dispatcherServlet对象,会执行init方法,根据DispaterServlet的继承关系,找到init方法在HttpServletBean中,下面我们来看一下这个

方法

public final void init() throws ServletException {
        if (logger.isDebugEnabled()) {
            logger.debug("Initializing servlet ‘" + getServletName() + "‘");
        }

        // Set bean properties from init parameters.
        try {
            /*PropertyValuesz是封装在web.xml配置servlet参数信息
             * <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:mvc-dispatcher.xml</param-value>
              </init-param>
            */
            PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(),                     this.requiredProperties);
            BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
            ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
            bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
            
            initBeanWrapper(bw);
            //将配置的初始化值设置到DispatcherServlet
            bw.setPropertyValues(pvs, true);
        }
        catch (BeansException ex) {
            logger.error("Failed to set bean properties on servlet ‘" + getServletName() + "‘", ex);
            throw ex;
        }

        //初始化spring mvc容器方法webApplicationContext,由子类的FrameworkServlet来实现
        initServletBean();

        if (logger.isDebugEnabled()) {
            logger.debug("Servlet ‘" + getServletName() + "‘ configured successfully");
        }
        }

接下来看FrameworkServlet的initServletBean(),主要调了initWebApplicationContext()方法

protected final void initServletBean() throws ServletException {
        getServletContext().log("Initializing Spring FrameworkServlet ‘" + getServletName() + "‘");
        if (this.logger.isInfoEnabled()) {
            this.logger.info("FrameworkServlet ‘" + getServletName() + "‘: initialization started");
        }
        long startTime = System.currentTimeMillis();

        try {
            //初始化spring mcv容器
            this.webApplicationContext = initWebApplicationContext();
            initFrameworkServlet();
        }
        catch (ServletException ex) {
            this.logger.error("Context initialization failed", ex);
            throw ex;
        }
        catch (RuntimeException ex) {
            this.logger.error("Context initialization failed", ex);
            throw ex;
        }

        if (this.logger.isInfoEnabled()) {
            long elapsedTime = System.currentTimeMillis() - startTime;
            this.logger.info("FrameworkServlet ‘" + getServletName() + "‘: initialization completed in " +
                    elapsedTime + " ms");
        }
    }
initWebApplicationContext方法
 protected WebApplicationContext initWebApplicationContext() {
        /*
          在spring启动过程中,ContextLoaderListener回监听到,实例化IoC容器,并将此容器实例注册到ServletContext中,现在把IOC容器取出来
         */
        WebApplicationContext rootContext =
                WebApplicationContextUtils.getWebApplicationContext(getServletContext());
        WebApplicationContext wac = null;

        if (wac == null) {
            //把IOC容器传进去,创建spring mvc自己的容器
            wac = createWebApplicationContext(rootContext);
        }
        return wac;
        if (this.publishContext) {
            
            String attrName = getServletContextAttributeName();
            //把创建好的spring mcv自己的容器设置到ServletContext容器中
            getServletContext().setAttribute(attrName, wac);
            
        }
    }
createWebApplicationContext方法
 protected WebApplicationContext createWebApplicationContext(ApplicationContext parent) {
        /*根据web.xml中的配置决定使用何种WebApplicationContext。默认情况下使用XmlWebApplicationContext
           web.xml中相关的配置context-param的名称“contextClass” */
        Class<?> contextClass = getContextClass();
        //获得spring mvc自己容器
        ConfigurableWebApplicationContext wac =
                (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);

        wac.setEnvironment(getEnvironment());
        //指定父容器为IOC容器
        wac.setParent(parent);
        //指定spring mcv 核心配置文件的位置classpath:mvc-dispatcher.xml
        wac.setConfigLocation(getContextConfigLocation());
        //spring mcv 容器继续初始化
        configureAndRefreshWebApplicationContext(wac);

        return wac;
    }

 

 

spring mvc之启动过程源码分析

标签:产生   启动过程   ping   igp   了解   信息   ogg   调用   图片   

原文地址:https://www.cnblogs.com/520playboy/p/8351696.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!