简要的做一些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. angular2.0学习笔记1.开发环境搭建 (node.js和npm的安装)

    开发环境, 1.安装Node.js®和npm, node 6.9.x 和 npm 3.x.x 以上的版本. 更老的版本可能会出现错误,更新的版本则没问题. 控制台窗口中运行命令 node -v 和 n ...

  2. BZOJ1057或洛谷1169 [ZJOI2007]棋盘制作

    BZOJ原题链接 洛谷原题链接 设\(L[i][j],R[i][j],H[i][j]\)表示点\((i,j)\)向左.右.上尽量拓展的左端点.右端点.上端点的坐标. \(L,R\)直接初始化好,\(H ...

  3. compatible with

    和系统函数冲突

  4. c++11 template 模板练习

    直接上代码吧 to do // 111111.cpp: 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> ...

  5. vs2008 安装部署 启动项

    具体操作办法如下: 鼠标右键安装项目->视图->注册表 依次创建键: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion ...

  6. netty1 快速入门

    Netty是一个高性能.异步事件驱动的网路通信框架 ,由于精力有限,本人并没有对其源 码做了特别细致的研究.如果下面的内容有错误或不严谨的地方,也请大家指正和谅解. Netty的线程模型是Reacto ...

  7. datagrid 扩展 页脚 合计功能

    效果图:合计信息展示在页脚中(showFooter:true) code: <!DOCTYPE html> <html> <head> <meta chars ...

  8. DOM-查找和修改

    1. 查找: 按HTML查找: 问题: 每次只能按一个条件查找,如果查找条件复杂,则步骤很繁琐 解决: 选择器: 按选择器查找: 2个API 1. 只查找一个元素: var elem=parent.q ...

  9. 用rpm命令安装定时器crontab

    crontab -l  command not found 准备以下安装包: ls -l总用量 1004-rw-r--r-- 1 root root  76296 10月  9 16:01 croni ...

  10. centos7 hive + 远程mysql 搭建笔记

    1.require:java环境,本地可用的hadoop,远程可访问的mysql 2.拷贝hive文件(hive-2.2.1) 3.设置环境变量 export HIVE_HOME=/data/spar ...