1.      概述

对于Web开发者,MVC模型是大家再熟悉不过的了,SpringMVC中,满足条件的请求进入到负责请求分发的DispatcherServlet,DispatcherServlet根据请求url到控制器的映射(HandlerMapping中保存),HandlerMapping最终返回HandlerExecutionChain,其中包含了具体的处理对象handler(也即我们编程时写的controller)以及一系列的拦截器interceptors,此时DispatcherServlet会根据返回的HandlerExecutionChain中的handler找到支持这一处理器类型的适配器(handlerAdapter),在处理器适配器中最终会去调用控制器的请求响应方法并返回结果视图(ModelAndView),得到结果视图后,通过render方法完成结果的显示。

HanderMapping的继承体系:

HandlerAdapter的继承体系:

同样的视图解析器ViewResolver针对不同的输出格式也有一系列的实现类,具体可自己看。

2.    实现分析

以我自己的一个web项目中spring mvc的配置为例:

  1. <context:component-scan base-package="cn.ds.log" />
  2. <bean id="defaultHandlerMapping"
  3. class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
  4. <bean
  5. class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
  6. </bean>
  7. <bean
  8. class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
  9. </bean>
  10. <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter">
  11. </bean>
  12. <bean id="viewResolver"
  13. class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  14. <property name="prefix">
  15. <value>/WEB-INF/jsp/</value>
  16. </property>
  17. <property name="suffix">
  18. <value>.jsp</value>
  19. </property>
  20. </bean>

这里因为是采用全注解的方式,所以先通过context:component-scan配置让spring自定扫描的包路径,接着配置handlerMapping、handlerAdapter及ViewResolver,几乎包含了SpringMVC的配置中需要涉及的所有元素。后面需要涉及具体的HanderMapping等的实现时,将以这里配置中的实现为例进行分析,其它的大家“同理可解”。⊙﹏⊙b汗

2.1  Spring MVC初始化流程

DispatcherServlet的继承体系如:

看到它们继承自HttpServlet,你就知道初始化过程应该是从init方法开始了,整个初始化的流程为:

很简单是么?我也觉得是,至少从上面的时序图看来是这样,不过前提是你已经很了解Spring IOC的实现原理了。上面的时序图中,在5的initStragegies()中除了调用6,7的函数外,还有几个类似的初始化函数,因为这里主要是为了理解整个的流程,所以我都省略了。上面流程可能需要分析的地方就在于3,4步,我们看看initWebApplicationContext函数的实现:

  1. protected WebApplicationContext initWebApplicationContext() {
  2. WebApplicationContext rootContext =
  3. WebApplicationContextUtils.getWebApplicationContext(getServletContext());
  4. WebApplicationContext wac = null;
  5. if (this.webApplicationContext != null) {
  6. // A context instance was injected at construction time -&gt; use it
  7. wac = this.webApplicationContext;
  8. if (wac instanceof ConfigurableWebApplicationContext) {
  9. ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
  10. if (!cwac.isActive()) {
  11. ……
  12. configureAndRefreshWebApplicationContext(cwac);
  13. }
  14. }
  15. }
  16. if (wac == null) {
  17. wac = findWebApplicationContext();
  18. }
  19. if (wac == null) {
  20. // No context instance is defined for this servlet -&gt; create a local one
  21. wac = createWebApplicationContext(rootContext);
  22. }
  23. if (!this.refreshEventReceived) {
  24. // Either the context is not a ConfigurableApplicationContext with refresh
  25. // support or the context injected at construction time had already been
  26. // refreshed -&gt; trigger initial onRefresh manually here.
  27. onRefresh(wac);
  28. }
  29. if (this.publishContext) {
  30. ……
  31. }
  32. return wac;
  33. }

看起来貌似有点复杂,其实理解了IOC容器的实现原理(可以看下“spring ioc源码分析”一文,⊙﹏⊙多年前弄的,这次暑假实习时又以读书报告的形式写了,感觉当年肿么可以写得这么乱……也是一种成长,不打算修改)就很简单,函数一开始会去获取WebApplicationContext对象,这个对象在ContextLoaderListener初始化IOC容器时就已经把它set到ServletContext的属性中,而且它也正是ConfigurableWebApplicationContext的实例,第一个if语句其实就是如果此时SpringIOC容器没有初始化的话就在这里启动IOC容器的初始化过程,因为看“省略(1)”中的代码你就知道,它会在这里调用refresh函数,“世人”都知道这就是IOC容器启动的入口,这里会解析配置文件springmvc-servlet.xml。

这里最终要执行onRefresh(),而这个就是SpringMVC初始化的入口。

(注:其实这里也可以配置log4j,通过其打印的info信息来看IOC与MVC的初始化顺序)

springmvc源码解析-初始化的更多相关文章

  1. SpringMVC源码解析- HandlerAdapter - ModelFactory(转)

    ModelFactory主要是两个职责: 1. 初始化model 2. 处理器执行后将modle中相应参数设置到SessionAttributes中 我们来看看具体的处理逻辑(直接充当分析目录): 1 ...

  2. SpringMVC源码解析- HandlerAdapter - ModelFactory

    ModelFactory主要是两个职责: 1. 初始化model 2. 处理器执行后将modle中相应参数设置到SessionAttributes中 我们来看看具体的处理逻辑(直接充当分析目录): 1 ...

  3. springMVC源码解析--ViewResolver视图解析器执行(三)

    之前两篇博客springMVC源码分析--ViewResolver视图解析器(一)和springMVC源码解析--ViewResolverComposite视图解析器集合(二)中我们已经简单介绍了一些 ...

  4. SpringMVC源码解析- HandlerAdapter初始化

    HandlerAdapter初始化时,主要是进行注解解析器初始化注册;返回值处理类初始化;全局注解@ControllerAdvice内容读取并缓存. 目录: 注解解析器初始化注册:@ModelAttr ...

  5. springMVC源码解析--ViewResolverComposite视图解析器集合(二)

    上一篇博客springMVC源码分析--ViewResolver视图解析器(一)中我们介绍了一些springMVC提供的很多视图解析器ViewResolver,在开发的一套springMVC系统中是可 ...

  6. SpringMVC源码解析

    一:springmvc运行过程: 1. dispatcherServlet 通过 HandlerMapping 找到controller2. controller经过后台逻辑处理得到结果集modela ...

  7. 深入了解SpringMVC源码解析

    Spring MVC源码解析 Spring MVC的使用原理其实是通过配置一个Servlet来接管所有的请求,所有的请求由这个Servlet来进行分发处理. 我们可以从web.xml里面看出这一点 & ...

  8. springMVC源码解析--HandlerMethodArgumentResolverComposite参数解析器集合(二)

    上一篇博客springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)中我们已经介绍了参数解析相关的东西,并且也提到了HandlerMethodArgume ...

  9. springmvc源码解析MvcNamespaceHandler之<mvc:view-resolvers>

    说在前面 本次主要介绍springmvc配置解析. springmvc配置解析 本次介绍MvcNamespaceHandler. 进入到这个方法org.springframework.web.serv ...

随机推荐

  1. Hadoop1.x集群安装部署(VMware)

    一.hadoop版本介绍 不收费的Hadoop版本主要有三个(均是国外厂商),分别是:Apache(最原始的版本,所有发行版均基于这个版本进行改进).Cloudera版本(Cloudera’s Dis ...

  2. [转]你真的了解 console 吗

    原文:https://segmentfault.com/a/1190000000481884 对于前端开发者来说,在开发过程中需要监控某些表达式或变量的值的时候,用 debugger 会显得过于笨重, ...

  3. 【数组】Product of Array Except Self

    题目: iven an array of n integers where n > 1, nums, return an array output such that output[i] is ...

  4. Types方法之upperBound-lowerBound-isUnbounded-containsType

    1.upperBound(Type t)方法 /** * The "rvalue conversion". * The upper bound of most types is t ...

  5. R语言中常用包(二)

    数据导入 以下R包主要用于数据导入和保存数据 feather:一种快速,轻量级的文件格式.在R和python上都可使用readr:实现表格数据的快速导入.中文介绍可参考这里readxl:读取Micro ...

  6. Go pprof和火焰图

    Profiling 在计算机性能调试领域里,profiling 就是对应用的画像,这里画像就是应用使用 CPU 和内存的情况.也就是说应用使用了多少 CPU 资源?都是哪些部分在使用?每个函数使用的比 ...

  7. Linux系统资源管理 之 硬件信息

    1. CPU lscpu : 一般不加参数,直接使用该命令. cat /proc/cpuinfo: 该文件中列出了CPU的详细信息,类似于'lscpu'命令 lscpu [niesh @niesh D ...

  8. 用Shell编写项目发布脚本

    1.首先在github上创建一个测试用的仓库 2.本地编写一个可以运行的测试项目,上传至github 3.链接服务器,编写脚本如下:注意:编写前需要在服务器上安装git和maven 执行build_c ...

  9. [转]EntityFramework的多种记录日志方式,记录错误并分析执行时间过长原因(系列4)

    本文转自:https://www.cnblogs.com/GuZhenYin/p/5556732.html Entity Framework 延伸系列目录 今天我们来聊聊EF的日志记录. 一个好的数据 ...

  10. Ionic3 UI组件之 ImageViewer

    组件特性: 轻触图片可全屏查看 手势上下滑动可关闭全屏查看 点击导航箭头可关闭视图 双击查看全图,并可放大 参考地址:https://github.com/Riron/ionic-img-viewer ...