简要的做一些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. sqlserver自带的导入导出工具,分别导入大批量mysql和oracle数据时的感受

    sqlserver自带的导入导出工具,分别导入大批量mysql和oracle数据时,mysql经常出现格式转换出错,不好导入  导入的数据量比较大时,还不如自己写个工具导入 今天在导oracle时,想 ...

  2. Junit4知识梳理

    一.junit官网 junit4:http://junit.org/junit4/ junit5:http://junit.org/junit5/ 二.github junit4: https://g ...

  3. js 闭包 理解 copy

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 下面就是我的学习笔记,对于Javascript初学者应该是很有用的. 一.变量的作用域 要理解 ...

  4. Servlet会话管理一(URL重写和表单隐藏域)

    会话可以简单的理解为客户端用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器的整个过程称为一个会话.即一个客户端用户和服务器端进行通讯的过程,也是客户端和服务器端之间的数据传 ...

  5. [FreeMind] 绘制思维时遇到的常见问题解决办法

    如何改变节点的摆放方向? 如果是新建节点,选择要放置节点的那一侧,按enter键,或者鼠标右键,插入平行节点即可. 如果是已经建好的节点,可以用ctrl+x, ctrl+v粘贴到另一边,或者选中子节点 ...

  6. ES线程池

    每个Elasticsearch节点内部都维护着多个线程池,如index.search.get.bulk等,用户可以修改线程池的类型和大小,线程池默认大小跟CPU逻辑一致 一.查看当前线程组状态 cur ...

  7. SpringMVC学习笔记:表单提交 参数的接收

    SpringMVC可以接收原生form表单和json格式数据 有一个名为Book的model,其中的属性如下: 字符串类型的name,数字类型的price,数组类型的cover,集合类型的author ...

  8. 20155312 2016-2017-2 《Java程序设计》第九周学习总结

    20155312 2016-2017-2 <Java程序设计>第九周学习总结 课堂内容总结 两个类有公用的东西放在父类里. 面向对象的三要素 封装 继承 多态:用父类声明引用,子类生成对象 ...

  9. C# AOP框架入门(转)

    出处:https://www.cnblogs.com/isaboy/p/Csharp_AOP_Log.html AOP面向切面编程(Aspect Oriented Programming),是通过预编 ...

  10. springboot 程序发布到tomcat运行

    springboot 一般使用jar 的方式运行,我们需要将程序放到tomcat环境下运行. 步骤如下: 1.修改pom文件. 排除内置的tomcat <dependency> <g ...