spring-mvc源码阅读笔记
简要的做一些spring-mvc部分的源码学习笔记
Spring-mvc做的工作主要是俩大方面吧:一个是初始化一个ioc容器,一个是mvc部分的控制和视图模块的实现。
先说下ioc容器的初始化部分:ioc的初始化主要在俩个地方,一个是contextLoadListener里,另一个在DispatcherServlet里。
contextLoadListener:
在contextLoadListener里初始化的ioc容器是整个web项目里的一个父容器。整个初始化的过程也比较简单,首先是实例化一个context,具体是哪个context类呢,我们可以在web.xml的配置里指定,不过我们一般也不会指定这个参数,所以就直接实例化了一个默认的context-XmlWebApplicationContext。实例化以后,就开始加载我们配置文件里的那些bean。配置文件的位置我们一般都在web.xml里进行了配置。具体的加载的过程都在refresh()方法里。
这refresh方法里我们一般比较关心的是不同类型的bean的注册的过程还有实例化的过程。具体的注册过程就不再说了。 在注册完成后,会首先实例化一些ioc关心的bean,比如各种processor,还有一些特定类型的bean,具体可以细看下代码。然后会把实例化后的一些在ioc容器里有特定功能的bean进行注册,就比如那些beanProcessor。最后呢,还会实例化那些单例的,非懒加载的bean。 其它的bean就不进行实例化了,只有在getBean()的时候才会去实例化。
DispatcherServlet:
在DispatcherServlet再次初始化了一个新的ioc容器,这个ioc容器是上面说的那个父容器的子容器,这个容器的加载的bean的范围就是我们在web.xml里配置的那些配置文件里的bean。需要注意的是,在实例化bean的时候,会先在自己的这个容器里取,取不到的时候,会去父容器的获取,但是父容器取不到子容器里的bean。这也是有时候我们的一些配置没有生效,可以思考下是不是这个原因导致的。具体的初始化的过程和上面大同小异,就不再细说了。这里除了ioc的初始化,还初始化了mvc里需要的一些功能块。比如mvc的控制模块,视图模块等等。这些模块都是建立的ioc容器之上的。
下面就开始说下mvc模块的实现
首先可以看下DispatcherServlet里的initStrategies方法,里面初始化了控制和视图需要的一系列的组件 我们先来关心下handlerMappings 这个组件,它主要负责请求对应的具体的controller的映射。
可以看到实例化的过程也是很简单,首先在ioc容器的查找有没有注册进去的HandlerMapping这种类型的bean,有的话,就直接从ioc容器里取出来,否则就实例化一个默认的HandlerMapping实例。尽管默认的这个bean并没有在ioc中注册,但是实例化过程还是借助了ioc容器,目的嘛,就是为了利用ioc容器里提供的各种bean processor,把需要的一些bean都注入进这个HandlerMapping里,然后也比较巧妙吧,把这些processor的调用方法当做了回调方法,在里边做了一系列的初始化的动作。
举个例子,就拿DefaultAnnotationHandlerMapping为例,这个handlerMapping处理了我们经常用的@Controller和@RequestMapping这样的注解。 在这个类的父类里可以看到有一个detectHandelrs方法,这个方法把遍历了ioc容器里注册的所有的bean,发现这个bean有上述那俩个注解后就会进行详细的解析,把所有可以处理的url,还有相对于的controller bean都记录下来,供处理请求的时候调用。其实这里可以学到一些注解的灵活的使用方法。
另一个想说一写的组件式HandlerAdapter, 它的初始化步骤和HandlerMappings是一样的。这个类做的功能是,在处理http请求的时候,会对请求路径对应的具体方法的参数和注解进行解析和处理。 这里再举个例子,我们经常用到的@RequestBody注解,这个注解意味着这个接口处理的是post请求,然后会把post中的body里的报文反序列化成接口上的bean对象。 这个反序列化的过程就在这个组件里。然后我发现在我工作的项目里配置了<mvc:annotation-driven> 这个注解,比较好奇,所有看了下这个注解的parser,发现这个注解的作用正是在ioc容器里注册了一些mvc模块会用到的组件的bean,其中就包括我们这里提到的HandlerAdapter.
我的这个工程里在<mvc:annotation-driven>这个注解里还配置了一个MessagerConverter,包括json的converter,在parser里发现,这写converter是HandlerAdapter里的一些成员变量,作用嘛大家都很清楚,就是上面讲的,把报文进行反序列化到bean实例。 当然这个HandlerAdapter里还有很多别的一些小组件,都是通过这种方式来初始化的。。。
在mvc这个模块里,用到了一些设计模式,比如控制器模式,命令模式。 以前对命令模式和责任链模式会有一些混淆,因为它俩有时会一起使用,或者使用场景有一些重叠吧。看下这边的代码有利于更好的理解。
还有spring的ioc的设计思路,后续的多次升级提供的功能,个人感觉,其实对原有的代码造成的影响并不大,因为这些功能大多都是借助了ioc流程中的各种processor回调来实现的,包括在mvc模块中。这种设计思路也是很值得借鉴的。。。
视图部分等后续再进行整理。。
spring-mvc源码阅读笔记的更多相关文章
- Spring事务源码阅读笔记
1. 背景 本文主要介绍Spring声明式事务的实现原理及源码.对一些工作中的案例与事务源码中的参数进行总结. 2. 基本概念 2.1 基本名词解释 名词 概念 PlatformTransaction ...
- Apollo源码阅读笔记(二)
Apollo源码阅读笔记(二) 前面 分析了apollo配置设置到Spring的environment的过程,此文继续PropertySourcesProcessor.postProcessBeanF ...
- Apollo源码阅读笔记(一)
Apollo源码阅读笔记(一) 先来一张官方客户端设计图,方便我们了解客户端的整体思路. 我们在使用Apollo的时候,需要标记@EnableApolloConfig来告诉程序开启apollo配置,所 ...
- Spring MVC源码——Servlet WebApplicationContext
上一篇笔记(Spring MVC源码——Root WebApplicationContext)中记录了下 Root WebApplicationContext 的初始化代码.这一篇来看 Servlet ...
- 精尽Spring MVC源码分析 - 寻找遗失的 web.xml
该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...
- 精尽Spring MVC源码分析 - 调式环境搭建
该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...
- 精尽Spring MVC源码分析 - 文章导读
该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...
- 精尽Spring MVC源码分析 - WebApplicationContext 容器的初始化
该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...
- 精尽Spring MVC源码分析 - 一个请求的旅行过程
该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...
- 精尽Spring MVC源码分析 - MultipartResolver 组件
该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...
随机推荐
- DirectX中坐标系问题
自己属于笨类型,以前总是记不住directx坐标系是怎样的,今天在网上看到一篇文章,借鉴过来. 1. 明确DirectX是左手坐标系. 描述如下:1. 伸出左手,手面朝上,手背朝下,握住z轴,大拇指方 ...
- linux下的压缩命令
linux zip命令 zip -r myfile.zip ./* 将当前目录下的所有文件和文件夹全部压缩成myfile.zip文件,-r表示递归压缩子目录下所有文件. 2.unzip unzip - ...
- linux 管道符与通配符
###管道符 *命令格: 命令1 | 命令2 //命令1的正确输出作为命令2的操作对象 ll | more netstat -an | grep xxx 通配符 类似于正则表达式 ? 一个以上 [] ...
- spring MVC中Dubbo的配置
1.服务提供方的bubbo配置: <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi=& ...
- LED
LED 时间限制: 1 Sec 内存限制: 128 MB 题目描述 数字显示器题目描述:最近学校晚上文化广场的人很多哇,原因是晚上大屏幕会放电影.无聊的艾神和x73也决定一起去文化大广场看一场电影, ...
- 探索未知种族之osg类生物---器官初始化三
当判断到viewer中没有一个graphicContext可用时,osg就会默认的进行一次对viewer的实现操作,这样可以保证osg以后可以安心的在屏幕上进行作画.那我们就来看看这个osgViewe ...
- linux下svn导入新目录到svn服务器特定地址
svn import transplant-apps/ svn://xx.xx.xx.90/ -m "changelog:add transplant-apps to 90-svn" ...
- if __name__ == '__main__的理解
模块之间引用不能循环成环,圆圈 模块的收搜 !!!把模块当作脚本执行 什么叫模块:py文件,如果一个py文件被导入了,他就是一个模块, 模块没有具体的调用过程 但是能对外提供功能 什么叫脚 ...
- python 找出一篇文章中出现次数最多的10个单词
#!/usr/bin/python #Filename: readlinepy.py import sys,re urldir=r"C:\python27\a.txt" disto ...
- 在vue中的点击事件怎么获取当前点击的元素
首先 vue的点击事件 是用 @click = “clickfun()” 属性 在html中绑定的,在点击的函数中 添加$event 参数就可以比如<button @click = “click ...