简要的做一些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源码阅读笔记的更多相关文章

  1. Spring事务源码阅读笔记

    1. 背景 本文主要介绍Spring声明式事务的实现原理及源码.对一些工作中的案例与事务源码中的参数进行总结. 2. 基本概念 2.1 基本名词解释 名词 概念 PlatformTransaction ...

  2. Apollo源码阅读笔记(二)

    Apollo源码阅读笔记(二) 前面 分析了apollo配置设置到Spring的environment的过程,此文继续PropertySourcesProcessor.postProcessBeanF ...

  3. Apollo源码阅读笔记(一)

    Apollo源码阅读笔记(一) 先来一张官方客户端设计图,方便我们了解客户端的整体思路. 我们在使用Apollo的时候,需要标记@EnableApolloConfig来告诉程序开启apollo配置,所 ...

  4. Spring MVC源码——Servlet WebApplicationContext

    上一篇笔记(Spring MVC源码——Root WebApplicationContext)中记录了下 Root WebApplicationContext 的初始化代码.这一篇来看 Servlet ...

  5. 精尽Spring MVC源码分析 - 寻找遗失的 web.xml

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  6. 精尽Spring MVC源码分析 - 调式环境搭建

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  7. 精尽Spring MVC源码分析 - 文章导读

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  8. 精尽Spring MVC源码分析 - WebApplicationContext 容器的初始化

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  9. 精尽Spring MVC源码分析 - 一个请求的旅行过程

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  10. 精尽Spring MVC源码分析 - MultipartResolver 组件

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

随机推荐

  1. 10.18JS日记

    1.JS的本质就是处理数据,数据来自后台的数据库,所以变量起到了临时存储的作用, ES制定了js的数据类型 2.数据类型有哪些? (1)字符串 String (2)数字  Number (3)布尔 B ...

  2. 5C - A == B ?

    Give you two numbers A and B, if A is equal to B, you should print "YES", or print "N ...

  3. C++中string类

    https://blog.csdn.net/sinat_36184075/article/details/54836053 https://blog.csdn.net/fdqw_sph/article ...

  4. 去掉easyui datagrid内部虚线的方式。

    去掉easyui        datagrid内部虚线的方式.easyui datagrid的样式是统一写在样式文件中的,如果想要统一替换可以找对应的datagird样式文件中的以下部分.如果想要改 ...

  5. 安装composer,以及通过composer安装laravel

    1安装composer http://docs.phpcomposer.com/00-intro.html#Installation-Windows中选择windows安装 下载并且运行 Compos ...

  6. 八大排序算法的Java代码实现

    简单插入排序 public class QuickSort { private static void quickSort(int [] a, int low, int high){ if (low ...

  7. 论坛:设计实体-->分析功能-->实现功能 之 《分析功能》

    其中 管理文章 的功能没有做,以下做的设计 浏览与参与 功能的步骤 分析功能   5个功能.   7个请求. 实现功能   Action, 7个方法   Service   Dao   Jsp For ...

  8. Null value was assigned to a property of primitive type setter of cn.itcast.oa.domain.Forum.topicCount

    [引用http://m.blog.csdn.net/blog/u013998070/41087351] Null value was assigned to a property of primiti ...

  9. 解决linux ubuntu不能识别华为手机的问题--升级内核

    敝人手中有一个华为mate8,但是debian, ubuntu及一系列衍生版均不能识别.只能识别出一个华为手机助手,但是无法使用华为的内置存贮. 在fedora上是可以完美使用的. 归根到底的原因,是 ...

  10. java 开发微信中回调验证一直提示 解密失败处理(Java)

    微信公众号平台接入JDK6和JDK7及JDK8加解密失败处理(Java) 根据自己jdk版本编译,如jdk7或者jdk6 ,此时部署后提示报错:java.security.InvalidKeyExce ...