1: DispatcherServlet 的初始化流程(调用的init方法)

a) 初始化spring高级容器,WebApplicationContext(容器初始化12个步骤)

Servlet类的init方法----GenericServlet类的init()---HttpServletBean类的init()--initServletBean()这个方法是FrameworkServlet类实现的---initWebApplicationContext()初始化wbc容器方法--

a.1) this.configureAndRefreshWebApplicationContext(cwac); 配置并刷新容器方法---wac.refresh();----AbstractAoolicationContext类的 refresh()方法, 该方法中有12个步骤,具体看 https://blog.csdn.net/u011151359/article/details/98496427

经过这12个步骤之后, 容器创建完成

a.2) this.onRefresh(wac);---DispatcherServlet类的onRefresh()--this.initStrategies(context);这里是模板方法模式,有一些策略集合方法供子类实现

b) 初始化DispatcherServlet类需要的一些策略集合(比如: 初始化多部件解析器,初始化国际化解析器,初始化主题解析器,初始化处理器映射器,初始化处理器适配器,初始化异常解析器,初始化视图解析器..), 这里只关注 处理器映射器,处理器适配器. 初始化处理器映射器代码中, 先从所有祖宗容器中获取所有的HandlerMapping, 如果获取不到,当前容器中根据"handlerMapping" 来获取HandlerMapping, 并返回完成初始化, 如果这二步都没有获取到处理器映射器(HandlerMapping), 此时有一个兜底代码: 获取默认的处理器映射器(即: 从默认的配置文件:DispatcherServlet.properties 中读取处理器映射器), 同理, 初始化处理器适配器的代码中,先从所有祖宗容器中获取所有handlerAdapter, 没有, 从当前容器中根据"handlerAdapter"获取处理器适配器, 有就返回,如果没有,也是一个兜底的代码, 从默认的DispatcherServlet.properties 中获取处理器适配器

这里有个面试题: springmvc 如果没有在springmvc.xml中配置处理器映射器和处理器适配器,是否可以正常处理请求??

这里需要知道springmvc处理请求的11个步骤,并且没有处理器映射器, 处理器适配器,是不行的, 还要知道springmvc有一个兜底策略,从默认的配置文件中加载默认的处理器适配器, 处理器映射器

2: DispatcherServlet的处理请求的流程(调用的 service方法)

a) 从Servlet类的service方法,---到doGet/doPost方法--到FrameworkServlet类的processRequest()方法--到doService()方法-- 到DispatcherServlet的doService方法--doDispatch()方法

b) DispatcherServlet类的核心方法就是doDispatch()

上面说到DispatcherServlet初始化时候, 会有一个兜底的策略, 从默认配置文件 DispatcherServlet.properties,加载处理器映射器(RequestMappingHandlerMapping),处理器适配器(RequestMappingHandlerAdapter), 接下来看看这二个处理器的初始化方法...

RequestMappingHandlerMapping的初始化方法: 1: 看xml文件中的是否有标签 2: 看该对象是否有实现InitializingBean接口,有的话,afterPropertiesSet() 这个方法就是对象的初始化方法.

而RequestMappingHandlerMapping 是实现了InitializingBean接口, afterPropertiesSet()---initHandlerMethods();---processCandidateBean(beanName);---detectHandlerMethods(beanName);---getMappingForMethod(method, userType);这个方法是将Controller类上的 RequestMapping注解和方法上的注解拼接起来,url. registerHandlerMethod(handler, invocableMethod, mapping);这二个方法是组装了二个map

在该方法中,组装了二个map: mappingLookup(key:RequestMappingInfo , value:handlerMethod) urlLookup(key:url, value:RequestMappingInfo 这里是一个url对应多个映射关系, 这里是基于rest风格的请求, 一个url因为 请求的method(get,post..)不同,从而访问不同的Controller方法)

如图所示:





处理器映射器的目的是能够根据 url找到对应的Controller方法, 这就需要以上二个map来实现精准匹配,, 这里的映射关系映射好了后,接下来就是处理

RequestMappingHandlerMapping的处理流程: 在DispatcherServlet类中doDispatch()方法中, 有mappedHandler = this.getHandler(processedRequest);----mapping.getHandler(request);这个方法返回的是一个处理器执行器调用链HandlerExecutionChain(里面包含一个Handler 和多个interceptors)----之后根据这个Handler找到对应的处理器适配器HandlerAdapter,---ha.handle() 这个方法返回了ModelAndView---this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException); 这个方法是处理DispatcherServlet的结果

RequestMappingHandlerAdapter, 可以看到这个类也实现了InitializingBean接口, 所以初始化,直接看 afterPropertiesSet()实现即可 ,

用户向服务器发送请求,请求会到DispatcherServlet,DispatcherServlet 对请求URL进行解析,得到请求资源标识符(URI),然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括一个Handler处理器对象、多个HandlerInterceptor拦截器对象),最后以HandlerExecutionChain对象的形式返回。

  DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:

HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息

数据转换:对请求消息进行数据转换。如String转换成Integer、Double等

数据格式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等

数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中

  Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;根据返回的ModelAndView,选择一个适合的ViewResolver返回给DispatcherServlet;ViewResolver 结合Model和View,来渲染视图,最后将渲染结果返回给客户端。

==========================================================================

SpringMVC容器的初始化过程: 首先我们从web.xml中开始, 在web.xml中配置contextLoaderListener, 他的作用是启动web容器时候,自动装配ApplicationContext的配置信息, 因为ContextLoaderListener实现了ServletContextListener接口,所以容器启动的时候,会自动执行ContextInitialized()方法, 这样就能够在客户群请求之前想 ServletContext中添加任意对象,

contextLoaderListener初始化核心逻辑就是,执行ServletContextListener的 contextInitialized()方法 ----contextInitialized(),该方法中判断context是否为null, 为null就创建context容器 ---createWebApplicationContext()---this.determineContextClass(sc)中,先根据传进来的容器servletContext(这里的servletContext, tomcat启动时候回创建ServletContext上下文环境对象,之后读取web.xml,首先读取和这二个标签, 也就是说优先从web.xml中获取配置的"contextClass"对应的全限定类名),获取全限定类名使用反射,创建容器, 如果创建为null, 这里也有一个兜底的代码,从默认的defaultStrategies中获取全限定类名,之后反射创建容器对象. defaultStrategies这个就是默认的配置文件映射成的对象, 在静态代码块中有读取配置文件ContextLoader.properties而来, 也就是不管你赔不配置,最终都会有默认的容器生成

创建了容器之后,有一个配置刷新Web容器的方法--this.configureAndRefreshWebApplicationContext(cwac, servletContext); --这个方法中先是配置容器属性, 之后又个刷新方法--wac.refresh()

关于refresh()的解析

https://blog.csdn.net/u011151359/article/details/98496427

经过这12个步骤之后, 容器创建完成

refresh()中obtainFreshBeanFactory()方法解析: 这个方法是refresh()的核心之一: 该方法中做了二件事: 1, refreshBeanFactory():将xml转换为BeanDefinition,存入BeanFactory中, 创建beanFactory、指定序列化Id、定制beanFactory、加载bean定义

2, getBeanFactory():返回beanFactory实例

总结:

1: DispatcherServlet 前端控制器,作用:接受请求,然后分发请求给对应的处理组件

2: HandlerMapping , 处理器映射器, 作用是将请求,和Controller方法 建立映射关系, 并返回 处理执行调用链对象(一个Handler, 多个HandlerInterceptor)

3: HandlerAdapter , 根据这个Handler获取对应的 处理这个请求的Controller, Controller处理完请求后,返回ModelAndView

4: ViewResolver ,视图解析器, 解析ModelAndView,返回对应的视图给前端

SpringMVC, 先从DispatcherServlet的初始化流程(init), 之后是DispatcherService的处理请求流程(service)

先从DispatcherServlet的初始化流程(init):

DispatcherServlet这个类,

FrameworkServlet, 这个类作用有2个: 1,创建WebApplicationContext容器, 2, 初始化一些策略集合(比如,文件解析器, 初始化多部件解析器,初始化国际化解析器,初始化主题解析器,初始化处理器映射器,初始化处理器适配器,初始化异常解析器,初始化视图解析器..) 初始化策略集合的实现 是在DispatcherServlet中完成的

AbstractApplicationContext: 这个类作用是 配置和刷新容器(12个步骤)

DispatcherService的处理请求流程(service方法):

HttpServlet类: 作用是 处理请求(里面有 doGet() , doPost() )

FrameworkServlet类: 处理请求, doService()

DispatcherServlet类; doDispatch() 找到请求对应的Controller,分发给他处理请求,返回ModelAndView

springMVC源码解读笔记的更多相关文章

  1. SpringMVC源码解读 - HandlerMapping

    SpringMVC在请求到handler处理器的分发这步是通过HandlerMapping模块解决的.handlerMapping 还处理拦截器. 先看看HandlerMapping的继承树吧 可以大 ...

  2. SpringMVC源码解读 - RequestMapping注解实现解读 - RequestMappingInfo

    使用@RequestMapping注解时,配置的信息最后都设置到了RequestMappingInfo中. RequestMappingInfo封装了PatternsRequestCondition, ...

  3. SpringMVC源码解读 - RequestMapping注解实现解读 - RequestCondition体系

    一般我们开发时,使用最多的还是@RequestMapping注解方式. @RequestMapping(value = "/", param = "role=guest& ...

  4. SpringMVC源码解读 - RequestMapping注解实现解读

    SpringMVC源码解读 - RequestMapping注解实现解读 - RequestCondition体系  https://www.cnblogs.com/leftthen/p/520840 ...

  5. spring-mvc源码阅读笔记

    简要的做一些spring-mvc部分的源码学习笔记 Spring-mvc做的工作主要是俩大方面吧:一个是初始化一个ioc容器,一个是mvc部分的控制和视图模块的实现. 先说下ioc容器的初始化部分:i ...

  6. js便签笔记(10) - 分享:json2.js源码解读笔记

    1. 如何理解“json” 首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西.它不是js对象,也不是字符串,它只是一种格式,一种规定而已. 这个格式规定了如何将js对象转 ...

  7. js便签笔记(10) - 分享:json.js源码解读笔记

    1. 如何理解“json” 首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西.它不是js对象,也不是字符串,它只是一种格式,一种规定而已. 这个格式规定了如何将js对象转 ...

  8. SpringMVC 源码解析笔记

    作者笔记仓库:https://github.com/seazean/javanotes 欢迎各位关注我的笔记仓库,clone 仓库到本地后使用 Typora 阅读效果更好. 一.调度函数 请求进入原生 ...

  9. springMVC 源码解读系列(一)初始化

    先看看DispatcherServlet的类机构: 初始化时序图: servlet初始化会调用 init 方法,换句话说就是springMVC进行初始化的时候首先会去执行HttpServletBean ...

随机推荐

  1. (翻译)OpenDocument and Open XML security (OpenOffice.org and MS Office 2007)

    标题:Open Document 和 Open XML安全性(OpenOffice.org and MS Office 2007) 摘要,OpenDocument 和 Open XML 都是 Offi ...

  2. 【python】Leetcode每日一题-前缀树(Trie)

    [python]Leetcode每日一题-前缀树(Trie) [题目描述] Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的 ...

  3. liunx中文件夹不能删除怎么操作

    1.运行rm -rf 文件名称 2.不能删除对应文件并且提示"rm: cannot remove './.user.ini': Operation not permitted" 操 ...

  4. Unity动态构建mesh绘制多边形算法流程分析和实践

    前言 先说一下,写这篇博文的动机,原文的博主代码写的十分潇洒,以至于代码说明和注释都没有,最近恰逢看到,所以以此博文来分析其中的算法和流程 参考博文:https://blog.csdn.net/lin ...

  5. (转)如何优雅的使用rabbit mq

    RabbitMQ无疑是目前最流行的消息队列之一,对各种语言环境的支持也很丰富,作为一个.NET developer有必要学习和了解这一工具.消息队列的使用场景大概有3种: 1.系统集成,分布式系统的设 ...

  6. TypeScript 中限制对象键名的取值范围

    当我们使用 TypeScript 时,我们想利用它提供的类型系统限制代码的方方面面,对象的键值,也不例外. 譬如我们有个对象存储每个年级的人名,类型大概长这样: type Students = Rec ...

  7. [bug] springboot 静态资源 layui.css 404

    目录结构 引用路径 <link rel="stylesheet" href="../static/layui/css/layui.css" type=&q ...

  8. Python 送你一棵圣诞树

    Python 送你一棵圣诞树 2019-01-02阅读 8800   今天是圣诞节,先祝大家圣诞快乐!??? 有人要说了,圣诞节是耶稣诞生的日子,我又不信基督教,有啥好庆祝的.这你就有所不知了,Pyt ...

  9. 附: Python爬虫 数据库保存数据

    原文 1.笔记 #-*- codeing = utf-8 -*- #@Time : 2020/7/15 22:49 #@Author : HUGBOY #@File : hello_sqlite3.p ...

  10. Docker的介绍和安装(1)

    一.虚拟化简介 1.虚拟化概念 计算机虚拟化(Computing Virtualization),一种资源管理技术,是指通过虚拟化技术将一台计算机的各种实体资源 , 如处理器 , 网络 , 内存及存储 ...