了解一个项目启动如何实现是了解一个框架底层实现的一个必不可少的环节。从使用步骤来看,我们一般是引入包之后,配置web.xml文件。官方文档示例的配置如下:

<web-app>
<servlet>
<servlet-name>example</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet> <servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>/example/*</url-pattern>
</servlet-mapping> </web-app>

其实就是把请求引到DispatcherServlet类中去执行。而DispatcherServlet类其实是一个Servlet类的子类,他的继承结构如下:

我们都知道当项目启动时,servlet会执行init方法,在HttpServletBean中覆写了这个init方法。代码如下

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

initServletBean();方法由FrameworkServlet类来实现的,而这个方法是初始化SpringMvc的上下文环境。从启动的打印日志我们来分析:(这里读取了springmvc.xml还解析了匹配到的类和方法)

信息: Loading XML bean definitions from class path resource [springmvc.xml]
三月 26, 2018 11:19:38 上午 org.springframework.web.servlet.handler.AbstractUrlHandlerMapping registerHandler
信息: Mapped URL path [/**] onto handler 'org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler#0'
三月 26, 2018 11:19:38 上午 org.springframework.web.servlet.handler.AbstractHandlerMethodMapping registerHandlerMethod
信息: Mapped "{[/testExcel],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView com.mmc.excel.TestExcelView.testExcel() throws java.io.UnsupportedEncodingException
三月 26, 2018 11:19:38 上午 org.springframework.web.servlet.handler.AbstractHandlerMethodMapping registerHandlerMethod
信息: Mapped "{[/myHandleMethod],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.mmc.hanlemethod.TestHandleMethod.myHandleMethod(org.springframework.web.context.request.WebRequest,org.springframework.ui.Model)
三月 26, 2018 11:19:38 上午 org.springframework.web.servlet.handler.AbstractHandlerMethodMapping registerHandlerMethod
信息: Mapped "{[/pets/{petId}],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public void com.mmc.helloworld.HelloMatrixVariable.findPet2(java.lang.String,int)
三月 26, 2018 11:19:38 上午 org.springframework.web.servlet.handler.AbstractHandlerMethodMapping registerHandlerMethod

HttpServletBean类的init方法内执行到initServletBean方法,这个方法被FrameworkServlet类覆写。这个方法里其实就一个有效的方法,即initWebApplicationContext();方法。这个方法会调用DispatcherServlet中的onRefresh()方法。然后会执行下面一段内容:

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

我理解的简单流程:servlet机制先会去获取web.xml配置文件,获取到servletConfig和servletContext,(关于servletConfig和context的博文)然后创建webApplicationContext,读取springmvc.xml,然后初始化适配器,解析器等。

另外还有一篇博文是讲SpringMvc源码解析的,写的很好,很详细。推荐去看

SpringMvc 启动原理源码分析的更多相关文章

  1. Spring Boot自动装配原理源码分析

    1.环境准备 使用IDEA Spring Initializr快速创建一个Spring Boot项目 添加一个Controller类 @RestController public class Hell ...

  2. Java HashMap底层实现原理源码分析Jdk8

    在JDK1.6,JDK1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里.但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依 ...

  3. jQuery1.9.1--结构及$方法的工作原理源码分析

    jQuery的$方法使用起来非常的多样式,接口实在太灵活了,有点违反设计模式的原则职责单一.但是用户却非常喜欢这种方式,因为不用记那么多名称,我只要记住一个$就可以实现许多功能,这个$简直就像个万能的 ...

  4. Java中HashMap底层原理源码分析

    在介绍HashMap的同时,我会把它和HashTable以及ConcurrentHashMap的区别也说一下,不过本文主要是介绍HashMap,其实它们的原理差不多,都是数组加链表的形式存储数据,另外 ...

  5. java 1.8 动态代理源码分析

    JDK8动态代理源码分析 动态代理的基本使用就不详细介绍了: 例子: class proxyed implements pro{ @Override public void text() { Syst ...

  6. worker启动executor源码分析-executor.clj

    在"supervisor启动worker源码分析-worker.clj"一文中,我们详细讲解了worker是如何初始化的.主要通过调用mk-worker函数实现的.在启动worke ...

  7. Android系统默认Home应用程序(Launcher)的启动过程源码分析

    在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还须要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应 ...

  8. Android Content Provider的启动过程源码分析

    本文參考Android应用程序组件Content Provider的启动过程源码分析http://blog.csdn.net/luoshengyang/article/details/6963418和 ...

  9. 涨姿势:Spring Boot 2.x 启动全过程源码分析

    目录 SpringApplication 实例 run 方法运行过程 总结 上篇<Spring Boot 2.x 启动全过程源码分析(一)入口类剖析>我们分析了 Spring Boot 入 ...

随机推荐

  1. 前端之html的常用标签2和css基本使用

    一 列表标签 ul标签:无序列表 ol标签:有序列表 li标签:写在ul和ol标签里面的 dl标签:定义列表 dt标签和dd标签:都写在dl里面的 <!DOCTYPE html> < ...

  2. QT5中无法包含Qtgui头文件的问题。

    今天新学QT是,从一个ppt中边看边抄边学.前几页还能理解,但到了用纯源码写空白QT工程时,便遇到了一个问题.头文件里包含 #include  <QtGui> 但是编译时总是出现下面图一中 ...

  3. Echarts饼图显示模板

    图表类型,必要参数!如为空或不支持类型,则该系列数据不被显示.可选为: 'line'(折线图) | 'bar'(柱状图) | 'scatter'(散点图) | 'k'(K线图) 'pie'(饼图) | ...

  4. IntelliJ IDEA 2017版 spring-boot2.0.4+mybatis反向工程;mybatis+springboot逆向工程

    一.搭建环境 采用IDE自动建立项目方式 然后,next next,配置导入依赖包 项目就生成了,在项目下导入配置文件GeneratorMapper.xml(项目结构如图所示) 配置文档,建立数据库和 ...

  5. Day1-python基础-变量常量

    不积跬步无以至千里 补充上一节字符串的内容: 字符串格式化输出: name = input("name>>") print("My name is %s&qu ...

  6. BT656与BT1120的区别

      从ITU-R BT1120文档上可知,BT1120支持的是1080p: 文档定义一帧为1 125 总行数和1 080 有效行:每行有效像素为1920图像频率60. 50. 30. 25 和 24H ...

  7. ==和equals的比较

    一 : == 的特点: a == b ; 1.如果A和B是基本数据类型    ==   比较的是两个变量的值 2.如果A和B是引用数据类型    == 比较的是两个变量的内存地址 二:重写的equal ...

  8. codehouse

    1 # 整数部分十进制转二进制 2 3 num = int(raw_input(">>>")) 4 5 if num < 0: 6 isNeg = True ...

  9. python基础之列表list元组tuple

    作者:tongqingliu 转载请注明出处:http://www.cnblogs.com/liutongqing/p/7041763.html python基础之列表list元组tuple 列表li ...

  10. C(m,n)算法

    排列组合:C(m,n),m为给定数列,n为要从数列m中取元素的数量,GetResult()获取所有不重复的组合. public class MathCombination<T> { Lis ...