【参考文章】:SpringMvc 启动原理源码分析

【参考文章】:【Spring】DispatcherServlet的启动和初始化

【参考文章】:servlet 百度百科

1. servlet 生命周期  

  一个客户端的请求到达 Server;

  Server 创建一个请求对象,处理客户端请求;

  Server 创建一个响应对象,响应客户端请求;

  Server 加载 Servlet 并调用其 init() 进行初始化;

  Server 激活 Servlet 的 service() 方法,传递请求和响应对象作为参数;

  service() 方法获得关于请求对象的信息,处理请求,访问其他资源,获得需要的信息;

  service() 方法使用响应对象的方法,将响应传回Server,最终到达客户端;

  一般 Servlet 只初始化一次(只有一个对象),当 Server 不再需要 Servlet 时(一般当 Server 关闭时),Server 调用 Servlet 的 destroy() 方法。

  Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法;

  Spring  MVC 中由一个单例的 DispatcherServlet  处理所有请求。

2. DispatcherServlet  的创建  

  DispatcherServlet就是一个前端控制器,集中提供请求处理机制。将url映射到指定的Controller处理,Controller处理完毕后将ModelAndView返回给DispatcherServlet,DispatcherServlet通过viewResovler进行视图解析,然后将model填充到view,响应给用户

2.1 构造方法

  先调用父类 FrameworkServlet 的构造方法,再调用自己的构造方法;

public class DispatcherServlet extends FrameworkServlet {    

    public DispatcherServlet() {
super();
setDispatchOptionsRequest(true);
}
} public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware { public FrameworkServlet() {
}
}

2.2 init()  

  DispatcherServlet 调用基类 HttpServletBean 的 init(),

  主要获取 servletContext ,servletConfig 对象

@Override
public final void init() throws ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Initializing servlet '" + getServletName() + "'");
} // Set bean properties from init parameters.
try {
        // 获取servletConfig
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
        // 将dispatcherServlet对象封装到BeanWrapper类里
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
        // 获取servletContext
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
        // 空的方法
initBeanWrapper(bw);
bw.setPropertyValues(pvs, true);
}
catch (BeansException ex) {
logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
throw ex;
} // Let subclasses do whatever initialization they like.
     //这个方法由FrameworkServlet提供实现
initServletBean(); if (logger.isDebugEnabled()) {
logger.debug("Servlet '" + getServletName() + "' configured successfully");
}
}

  

  HttpServletBean 的 init() 又会调用  FrameworkServlet 的 initServletBean();

  主要初始化 Spring 的 webApplicationContext  对象

    @Override
protected final void initServletBean() throws ServletException {
getServletContext().log("Initializing Spring " + getClass().getSimpleName() + " '" + getServletName() + "'");
if (logger.isInfoEnabled()) {
logger.info("Initializing Servlet '" + getServletName() + "'");
}
long startTime = System.currentTimeMillis(); try {
// 真正有效的方法
this.webApplicationContext = initWebApplicationContext();
initFrameworkServlet();
}
catch (ServletException | RuntimeException ex) {
logger.error("Context initialization failed", ex);
throw ex;
} if (logger.isDebugEnabled()) {
String value = this.enableLoggingRequestDetails ?
"shown which may lead to unsafe logging of potentially sensitive data" :
"masked to prevent unsafe logging of potentially sensitive data";
logger.debug("enableLoggingRequestDetails='" + this.enableLoggingRequestDetails +
"': request parameters and headers will be " + value);
} if (logger.isInfoEnabled()) {
logger.info("Completed initialization in " + (System.currentTimeMillis() - startTime) + " ms");
}
}

  

  初始化 WebApplicationContext后,调用 DispatcherServlet中 的 onRefresh();

    protected WebApplicationContext initWebApplicationContext() {
WebApplicationContext rootContext =
WebApplicationContextUtils.getWebApplicationContext(getServletContext());
WebApplicationContext wac = null; if (this.webApplicationContext != null) {
wac = this.webApplicationContext;
if (wac instanceof ConfigurableWebApplicationContext) {
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
if (!cwac.isActive()) {
if (cwac.getParent() == null) {
cwac.setParent(rootContext);
}
configureAndRefreshWebApplicationContext(cwac);
}
}
}
if (wac == null) {
wac = findWebApplicationContext();
}
if (wac == null) {
wac = createWebApplicationContext(rootContext);
}
if (!this.refreshEventReceived) {
synchronized (this.onRefreshMonitor) {
// 初始化 Spring MVC 的基本组件
onRefresh(wac);
}
}
if (this.publishContext) {
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);
} return wac;
}

  

  onRefresh() 直接调用 initStrategies() ;

    @Override
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}

   initStrategies() 初始化基本组件,启动整个 Spring MVC 框架

protected void initStrategies(ApplicationContext context) {
     //初始化上传文件解析器
initMultipartResolver(context);
     //初始化本地解析器
initLocaleResolver(context);
     //主题处理器
initThemeResolver(context);
     //映射处理器
initHandlerMappings(context);
     //处理适配器
initHandlerAdapters(context);
     //异常处理器
initHandlerExceptionResolvers(context);
     //请求到视图名的翻译器
initRequestToViewNameTranslator(context);
     //视图解析器
initViewResolvers(context);
     //初始化FlashManager
initFlashMapManager(context);
}

DispatcherServlet 的创建过程的更多相关文章

  1. SpringMVC——DispatcherServlet的IoC容器(Web应用的IoC容器的子容器)创建过程

    在上一篇<Spring--Web应用中的IoC容器创建(WebApplicationContext根应用上下文的创建过程)>中说到了Web应用中的IoC容器创建过程.这一篇主要讲Sprin ...

  2. Spring MVC 学习 -- 创建过程

    Spring MVC 学习 -- 创建过程 Spring MVC我们使用的时候会在web.xml中配置 <servlet> <servlet-name>SpringMVC< ...

  3. Spring MVC 原理探秘 - 容器的创建过程

    1.简介 在上一篇文章中,我向大家介绍了 Spring MVC 是如何处理 HTTP 请求的.Spring MVC 可对外提供服务时,说明其已经处于了就绪状态.再次之前,Spring MVC 需要进行 ...

  4. Spring框架系列(13) - SpringMVC实现原理之DispatcherServlet的初始化过程

    前文我们有了IOC的源码基础以及SpringMVC的基础,我们便可以进一步深入理解SpringMVC主要实现原理,包含DispatcherServlet的初始化过程和DispatcherServlet ...

  5. ASP.NET Web API 控制器创建过程(二)

    ASP.NET Web API 控制器创建过程(二) 前言 本来这篇随笔应该是在上周就该写出来发布的,由于身体跟不上节奏感冒发烧有心无力,这种天气感冒发烧生不如死,也真正的体会到了什么叫病来如山倒,病 ...

  6. ASP.NET Web API 控制器创建过程(一)

    ASP.NET Web API 控制器创建过程(一) 前言 在前面对管道.路由有了基础的了解过后,本篇将带大家一起学习一下在ASP.NET Web API中控制器的创建过程,这过程分为几个部分下面的内 ...

  7. Web APi之过滤器创建过程原理解析【一】(十)

    前言 Web API的简单流程就是从请求到执行到Action并最终作出响应,但是在这个过程有一把[筛子],那就是过滤器Filter,在从请求到Action这整个流程中使用Filter来进行相应的处理从 ...

  8. .NET/ASP.NET MVC Controller 控制器(IController控制器的创建过程)

    阅读目录: 1.开篇介绍 2.ASP.NETMVC IControllerFactory 控制器工厂接口 3.ASP.NETMVC DefaultControllerFactory 默认控制器工厂 4 ...

  9. 图解JAVA对象的创建过程

    前面几篇博文分别介绍了JAVA的Class文件格式.JVM的类加载机制和JVM的内存模型,这里就索性把java对象的创建过程一并说完,这样java对象的整个创建过程就基本上说明白了(当然你要有基础才能 ...

随机推荐

  1. 初试Python语法小试牛刀之冒泡排序

    Python很火,心里很慌,没吃过猪肉,也要见见猪走路. 看了几天Python的语法,大概初步了解了一点点,https://www.liaoxuefeng.com/wiki/0014316089557 ...

  2. opencv setTo()

    转载至 作者:跬步达千里 opencv的setTo函数是将图像设置为某个值; 例如: 1.有一个Mat src,想将他的值全部设置成0,则可以src.setTo(0) 2.setTo还有更为高级的用法 ...

  3. python学习笔记(三)- 字典、集合

    字典:key-value形式 1)取数据方便   #字典里面没有重复的key 2)查询速度快 #字典是无序的 一.定义一个字典 infos = { 'name':'王小明', 'sex':'male' ...

  4. 单点登录(SSO)解决方案之 CAS 入门案例

    单点登录: 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. ...

  5. NTFS(Windows)、ext4(RHEL6)和xfs(RHEL7)文件系统的误删除恢复和备份

    前言 对于误删除文件的设备,要马上停止任何写的操作,防止删除的文件被覆盖,导致数据丢失! 恢复NTFS文件系统下误删的文件 以Windows为例,市面上能恢复的工具不少,例如EasyRecovery. ...

  6. NSLog无法使用

    iOS/macos 中 #import<foundation/foundation.h> nslog不能用 如果项目中包含c/c++程序代码 将其后缀修改成.m .mm 将项目的build ...

  7. Shell中read命令--学习

    read命令 -p(提示语句) -n(字符个数) -t(等待时间) -s(不回显) 1.基本读取read命令接收标准输入(键盘)的输入,或其他文件描述符的输入(后面在说).得到输入后,read命令将数 ...

  8. [leetcode]36. Valid Sudoku验证数独

    Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to th ...

  9. spring mvc+mybatis 构建 cms + 实现UC浏览器文章功能

    最近公司在模拟UC浏览器做一个简单的cms系统,主要针对于企业内部的文章浏览需求,这边考虑用户大多用mobile浏览文章内容,故使用原生的ios和android进行开发,后面也会集成html5. 1. ...

  10. C++ 提取网页内容系列之一

    标 题: C++ 提取网页内容系列作 者: itdef链 接: http://www.cnblogs.com/itdef/p/4171179.html 欢迎转帖 请保持文本完整并注明出处 首先分析网页 ...