了解一个项目启动如何实现是了解一个框架底层实现的一个必不可少的环节。从使用步骤来看,我们一般是引入包之后,配置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. 59.加载Viewcontroller的几种方法(添加导航,解决xib里面空间不显示问题)

    // 一.根据StoryboardID(需要在Storyboard设置),通过ViewController所在的Storyboard来加载: UIStoryboard *storyboard = [U ...

  2. 爬虫之mongodb数据库

    一 mongodb的介绍 1.易用性:mongodb是一款强大.灵活并且易扩展的数据库.他面向于文档的数据库,而不是关系性数据库.不采用关系型主要是为了获得更好的扩展性.还有一个好处就是面向文档的数据 ...

  3. 2019.01.24 bzoj3125: CITY(轮廓线dp)

    传送门 题意简述:给一个n∗mn*mn∗m的网格图,有的格子不能走,有的格子只能竖着走,有的格子只能横着走,问用一条回路覆盖所有能走的格子的方案数. 思路: 就是简单的轮廓线dpdpdp加了一点限制而 ...

  4. java 判断对象是否是某个类的类型两种方法

    第一种: instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例.instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例. 用法: resul ...

  5. 程序员面试50题—sizeof的用法(6)

    以下为Windows下的32 位C++程序,请计算sizeof 的值void Func ( char str[100] ){sizeof( str ) = ?}void *p = malloc( 10 ...

  6. nigos core 安装配置

    系统环境      Apache        PHP        GCC compiler        GD development libraries 环境安装     yum install ...

  7. R语言的文件写入

    R语言的文件写入 官方文档介绍如下: write.table(x, file = "", append = FALSE, quote = TRUE, sep = " &q ...

  8. 安卓 build/core/Makefile 以及main.mk

    android make 系统总共分为四层 arch board device product 在各个字android.mk文件中引用的定义都存放在./build/core/下!比如android.m ...

  9. .net 导出Excel

    CreateExcel(ExcelDs, ", f); void CreateExcel(DataSet ds, string typeid, string FileName) { Http ...

  10. 如何更改linux文件的拥有者及用户组(chown和chgrp)

    http://blog.csdn.net/hudashi/article/details/7797393 一.基本知识   在Linux中,创建一个文件时,该文件的拥有者都是创建该文件的用户.该文件用 ...