SpringMVC的启动过程
前言
下面是一个SpringMVC应用的配置文件,需要注意两个地方,一个是ContextLoaderListener,一个是dispatcherServlet。web容器正是通过这两个配置才和spring管理起来。ContextLoaderListener与web容器的ServletContext关联,为Spring的IOC容器提供了一个宿主环境。在建立起IOC容器体系之后,把DispatcherServlet作为SpringMVC处理web请求的转发器建立起来,完成响应http请求的准备。
SpringMVC启动过程大致分为两个阶段:
第一阶段.ContextLoaderListener初始化,实例化IOC容器,并将此容器注册到ServletContext中。
第二阶段DispatcherServlet初始化,建立自己的上下文,也注册到ServletContext中。
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"> <display-name>ota</display-name>
<description>ota web application</description> <!-- 系统组件加载顺序:context-param -> listener -> filter -> servlet -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/applicationContext.xml</param-value>
</context-param> <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- GZip -->
<filter>
<filter-name>gzipFilter</filter-name>
<filter-class>com.travelsky.ibeplus.compress.Compress2WayFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gzipFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <!-- Servlet that dispatches request to registered handlers (Controller implementations). -->
<servlet>
<servlet-name>ota</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/mvc-core-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet> <!-- 需要定义在对应的servlet之后 -->
<servlet-mapping>
<servlet-name>ota</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> </web-app>
1、Spring IOC容器的启动
Spring IOC容器的启动在我博客中这一篇博文“Spring是怎样启动的” 有详细介绍,这里再简单概述下。
ContextLoaderListener实现ServletContextListener,这个接口里面的方法会结合web容器的生命周期被调用。因为ServletContextListener是ServletContext的监听者,如果ServletContext发生变化,会触发相应的事件,而监听者一直对这些事件进行监听,如果接受到了监听的事件,就会作于相应处理。例如在服务器启动,ServletContext被创建的时候,ServletContextListener的contextInitialized()方法被调用,从而拉开了初始化Spring IOC容器的序幕
2、DispatcherServlet的启动 (HttpServletBean * FrameworkServlet * DispatcherServlet)
DispatchServlet本质上是一个Servlet,web容器启动的时候,servlet也会初始化,其init方法被调用,开启初始化之旅。
DispatchServlet会建立自己的上下文来持有Spring MVC特殊的bean对象,在建立这个自己持有的Ioc容器的时候,会从ServletContext中得到根上下文作为DispatchServlet上下文的parent上下文。有了这个根上下文,再对自己持有的上下文进行初始化,最后把自己持有的这个上下文保存到ServletContext中,供以后检索和使用。
下面来详细解释下:

- DispatchServlet名如其义,它的本质上是一个Servlet,子类不断的对HttpServlet父类进行方法扩展
- HttpServlet有两大核心方法:init()和service()方法。HttpServletBean重写了
init()方法,在这部分,我们可以看到其实现思路:公共的部分统一来实现,变化的部分统一来抽象,交给其子类来实现,故用了abstract class来修饰类名。此外,HttpServletBean提供了一个HttpServlet的抽象实现,使的Servlet不再关心init-param部分的赋值,让servlet更关注于自身Bean初始化的实现 - FrameworkServlet提供了整合web javabean和spring application context的整合方案。在源码中可以看到通过执行
initWebApplicationContext()方法和initFrameworkServlet()方法实现 - DispatchServlet是HTTP请求的中央调度处理器,它将web请求转发给controller层处理,它提供了敏捷的映射和异常处理机制,DispatchServlet转发请求的核心代码在doService()方法中实现
2.1 HttpServletBean


上图是抽象类HttpServletBean的实现,我们知道HttpServlet有两大核心方法:init()和service()方法。HttpServletBean重写了init()方法,在这部分,我们可以看到其实现思路:公共的部分统一来实现,变化的部分统一来抽象,交给其子类来实现,故用了abstract class来修饰类名。此外,HttpServletBean提供了一个HttpServlet的抽象实现,使的Servlet不再关心init-param部分的赋值,让servlet更关注于自身Bean初始化的实现。
2.2 FrameworkServlet
在HttpServletBean中有一方法initServletBean()需要子类去实现,因此 FrameworkServlet需要实现initServletBean()方法



2.3 DispatcherServlet
在FrameworkServlet中有一方法onRefresh()需要子类去实现,因此DispatcherServlet需要去实现onRefresh()方法。


另外一些MVC的特性初始化时在initStrategies()中实现的,包括支持国际化的LocalResolver、支持Request映射的HandlerMappings,以及视图生成的ViewResolver等等。
比如初始化HandlerMappings,在SpringMVC中,HandlerMappings的作用是为Http请求找到对应的Controller控制器,来进一步处理请求。
注意:
在web.xml配置文件中,DispatcherServlet中有一配置<load-on-startup>1</load-on-startup>,表示在容器启动的时候就加载该servlet。
当<load-on-startup>值为0或者大于0时,表示容器在应用启动时就加载这个servlet(实例化并调用其init()方法)。
当是一个负数时或者没有指定时,则表示第一次请求该servlet才加载。
正数的值越小,启动该servlet的优先级越高。
3. DispatcherServlet类和ContextLoaderListener类的关系图:

小结:首先,用ContextLoaderListener初始化上下文,接着使用DispatchServlet来初始化WebMVC的上下文。
SpringMVC的启动过程的更多相关文章
- 关于启动过程及log
1.tomcat的启动过程及log 2.webapp的启动过程及log 3.spring的启动过程及log 4.springmvc的启动过程及log 5.web.xml的启动过程及log
- SpringMVC启动过程详解(li)
通过对SpringMVC启动过程的深入研究,期望掌握Java Web容器启动过程:掌握SpringMVC启动过程:了解SpringMVC的配置文件如何配置,为什么要这样配置:掌握SpringMVC是如 ...
- SpringMVC 原理 - 设计原理、启动过程、请求处理详细解读
SpringMVC 原理 - 设计原理.启动过程.请求处理详细解读 目录 一. 设计原理 二. 启动过程 三. 请求处理 一. 设计原理 Servlet 规范 SpringMVC 是基于 Servle ...
- springMvc 启动过程
转载自https://www.jianshu.com/p/dc64d02e49ac 这里给出一个简洁的文字描述版SpringMVC启动过程: tomcat web容器启动时会去读取web.xml这样的 ...
- 转:spring的启动过程-spring和springMVC父子容器的原理
要想很好理解这三个上下文的关系,需要先熟悉spring是怎样在web容器中启动起来的.spring的启动过程其实就是其IoC容器的启动过程,对于web程序,IoC容器启动过程即是建立上下文的过程. s ...
- Spring MVC的启动过程
一.概述 下面一个基本的运用springMVC的的web.xml的配置,这里要注意两个地方,一个是ContextLoadListener,一个是DispatcherServlet.web容器正是通过这 ...
- spring mvc 启动过程及源码分析
由于公司开源框架选用的spring+spring mvc + mybatis.使用这些框架,网上都有现成的案例:需要那些配置文件.每种类型的配置文件的节点该如何书写等等.如果只是需要项目能够跑起来,只 ...
- Tomcat架构解析(二)-----Connector、Tomcat启动过程以及Server的创建过程
Connector用于跟客户端建立连接,获取客户端的Socket,交由Container处理.需要解决的问题有监听.协议以及处理器映射等等. 一.Connector设计 Connector要实现的 ...
- SpringBoot启动过程原理
最近这两年springboot突然火起来了,那么我们就来看看springboot的运行原理. 一.springboot的三种启动方式: 1.运行带有main方法的2.通过命令 Java -jar命令3 ...
随机推荐
- hadoop源码编译--maven安装
一 下载maven bin包并解压 $ wget http://mirror.bit.edu.cn/apache/maven/maven-3/3.3.9/binaries/apache-maven-3 ...
- PHP 开发环境搭建
1. PHP (1) download PHP and extra the zip file to the folder “C:\tools\php” (2) add the path “;C:\to ...
- spring的AOP动态代理--JDK代理和CGLIB代理区分以及注意事项
大家都知道AOP使用了代理模式,本文主要介绍两个代理模式怎么设置以及区别,对原文一些内容进行了引用后加入了自己的理解和更深入的阐述: 一.JDK代理和CGLIB代理的底层实现区别* JDK代理只能 ...
- ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2018) Syria, Lattakia, Tishreen University, April, 30, 2018
ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2018) Syr ...
- 绘制三角形(sass)
绘制三角形 /// draw triangle/// @param {type} $type [''] - triangleUp triangleDown triangleLeft triangleR ...
- 创建CMD启动环境
我们可以用一个cmd文件,通过doskey命令模拟linux下的alias,指定一些我们习惯的命令名,比如: env.cmd @echo off doskey alias=doskey /macros ...
- C#和Java接口对比
C#和java的接口有很多类似之处,对于编程约束和设计模式的实现有重要作用.这里记录几个知识点. 1. C#的接口中不能有字段,但Java的接口中允许有static final修饰的字段/域(fiel ...
- input预览上传图片
html代码 <input type="file" name="file" id="file" > <img src=&q ...
- 远程登录MySQL
mysql 远程连接数据库的二种方法 一.连接远程数据库: 1.显示密码 如:MySQL 连接远程数据库(192.168.5.116),端口“3306”,用户名为“root”,密码“123456” ...
- win7 无法链接到手机热点
作为一个对电脑不太懂的小白来说,链接个热点都是问题,来看看我怎么解决的吧. 之前连上过这个手机的热点,隔了有段时间了,今天连不上了,这是啥问题? 另外一台没连过这个手机热点的电脑是可以链接成功了,纳尼 ...