springmvc源码分析系列-请求处理流程
接上一篇-springmvc源码分析开头片
上一节主要说了一下springmvc与struts2的作为MVC中的C(controller)控制层的一些区别及两者在作为控制层方面的一些优缺点。今天就结合下面的一张图和上一篇中关于springmvc各个模块之间及各个模块中的类的继承关系的一张图对springmvc的请求处理流程进行一个分析。当然有了springmvc的请求处理流程我们就知道了springmvc是如何在启动的时候去加载或者去解析对应的具体控制器,以及modleAndView使干什么用的,如何将controller处理后的结果映射到view中,也就是在我们java中的jsp或者freemaker中的。当然下面的这张图可能很多网友也有,但是可能每个人根据这张图的理解去分析的springmvc的原理都是不一样的(我只是结合这两张图我自己的一个理解)好了废话不多说咱们有图才有说服力。。。

这张图确实比较经典。首先我们大致的说一下:springmvc这个框架其实主要是有这几个大的模块组成的① dispatcherServlet ②handlerMapping③ controller④modelAndView⑤viewResolver⑥ view。当时这个springmvc的整个请求的流程不是加载的流程。对这个加载的流程做一个简答的介绍
①:DispatcherServlet是springmvc中的前端控制器(front controller),负责接收request并将request转发给对应的处理组件.
②:HanlerMapping是springmvc中完成url到controller映射的组件.DispatcherServlet接收request,然后从HandlerMapping查找处理request的controller.
③:Cntroller处理request,并返回ModelAndView对象,Controller是springmvc中负责处理request的组件(类似于struts2中的Action),ModelAndView是封装结果视图的组件.
④:视图解析器解析ModelAndView对象并返回对应的视图给客户端.
⑤:viewResolve是对我们的每个具体实现的controller封装后返回的modelAndView这个对象的解析处理,在这个根据我们配置的视图解析器将对应的modelAndView映射到对应的view(jsp或者其他的显示层语言)中去显示我们controller处理后返回到视图层的内容
⑥:显示每个controller返回的视图解析器的内容到对应的视图给客户端(view).
上面大致就是我们一个springnvc在发送一个get或者post的controller请求后再控制层的处理流程。
结合上面的请求处理流程,原本接下来应该是说一个在每个模块中也就是每一步是如何做的,但是在这里我想先去说一下加载的过程,也就是我们知道我们在使用springmvc的时候有时候我们使用配置文件的形式来配置,有时候使用注解的方式,但是大多数时候换是会采用注解的方式,这也是springmvc与struts2相比可以实现百分百零配置的优势所在。那么在我们不管是配置文件也好,是注解也好,我们知道springmvc的原生态的嵌入到我们的spring中的,那么在加载我们的spring文件的时候是如何加载springmvc的配置或者注解的呢?下面咱们从开始的地方来说一下:
首先大家不管是有没有去看过springmvc的源码,我想大家应该读知道我们在发送一个springmvc请求的时候是根据一个请求的去springmvc容器中去找跟这个url对应的具体的处理controller是哪个,找到后就去做业务处理,做完业务处理后封装一个modelandview 然后通知springmvc的viewResolve去对这个controller对应的modelAndView进行解析然后映射或者渲染到view中实现在客户端(这里一般是浏览器)上显示处理后的内容。但是这里我想大家都知道,那么springmvc的url和controller的对应关系是怎么建立的呢??
对于springmvc有了解的我想大家对spring也不陌生,因为springmvc原生态的支持spring。所以在spring启动加载容器的时候,也会去加载springmvc对应的controller的配置文件或者说注解。在spring加载完所有的bean的时候,springmvc会去遍历spring容器加载后的bean,然后根据我们的配置或者注解将controller上的url和对应的bean放到一个map中。这样我们就可以根据request请求中的url快速的定位到我们具体要使用的那个controller。这时候我们就有了两者的对应关系,但是这时候换需要我们去处理相关的参数信息。springmvc在处理参数信息的时候有两种方式,一种是在使用了@requestParam这个注解的时候,springmvc可以直接去将参数中的值和requestParam注解的参数进行一个绑定。如果不是使用的显示的注解方式,而是使用的根据参数名的方式映射绑定的话,那么springmvc在处理这样的参数的时候是使用的其他的工具类asm。这是因为java在做类的反射的时候只提供了获取方法参数类型的反射,并没有获取方法名的反射,因此这个时候springmvc在处理这个参数的绑定的时候,就使用asm的读取字节码的方式来获取方法名(asm这玩意是个操作字节码的框架,大家有兴趣的话可以去研究一下)。在这里两种方式跟大家说了,但是我要补充一下,如果你能使用注解的时候尽量使用注解,因为springmvc在使用asm框架去读取字节码的时候是很麻烦的也比较耗时,建议大家能使用@requestparam注解的尽量使用。
好了上面是对spring在加载springmvc相关控制器的时候是如何处理的做了一个大致的阐述。虽然不是很详细,但是总算有了对springmvc这个框架的一个整体的了解,这个时候我们再去分模块的去研究他。
下面先开始对dispatcherServlet的研究。
我们学过servlet的大家都知道,我们servlet的生命周期是 init() doservice(){doGet(),doPost()},doDestory().,我们看到dispatcherservlet的继承关系是--》frameWorkServlet--》httpServletBean--》httpServlet。所以由这样的继承关系在加上servlet的生命周期,我们就可以知道,在tomcat容器在启动加载的时候回去执行init().但是在这个init()中又回去调用子类的方法。这里我们截图看一下。


结合上面的这两幅图,我简单的做一个介绍。我们都知道servlet的生命周期开始于init()所以在加载容器的时候当然也是要从init开始,所以我就从dispatcherServlet最上层的实现类开始找,知道找到httpBeanServlet,然后再看他的父类httpservlet,httpservlet的父类genericServlet,最后是实现的一个servlet的接口。我从servlet的接口中找到了容器最开始加载的init()这个方法。这个时候我们去看genericServlet的时候发现只是对接口中的init方法进行了一个实现 但是具体的实现内容没有去做。我们再去看httpServlet这个继承了genericServlet的抽象类中没有init()这个方法。这个时候我们再去httpbeanServlet中发现了一个呗定义为final类型的init()方法。我们知道final类型的方法是不能被子类继承的,好了到这里我们终于找到了加载开始的入口。
----------今天我们找到了门,明天我们进门去一探究竟。明天晚上见^_^
springmvc源码分析系列-请求处理流程的更多相关文章
- SpringMVC源码分析-400异常处理流程及解决方法
本文涉及SpringMVC异常处理体系源码分析,SpringMVC异常处理相关类的设计模式,实际工作中异常处理的实践. 问题场景 假设我们的SpringMVC应用中有如下控制器: 代码示例-1 @Re ...
- SpringMVC源码分析系列
说到java的mvc框架,struts2和springmvc想必大家都知道,struts2的设计基本上完全脱离了Servlet容器,而springmvc是依托着Servlet容器元素来设计的,同时sp ...
- SpringMVC源码分析和启动流程
https://yq.aliyun.com/articles/707995 在Spring的web容器启动时会去读取web.xml文件,相关启动顺序为:<context-param> -- ...
- SpringMVC源码分析(3)DispatcherServlet的请求处理流程
<springmvc源码分析(2)dispatcherservlet的初始化>初始化DispatcherServlet的多个组件. 本文继续分析DispatcherServlet解析请求的 ...
- MyCat源码分析系列之——配置信息和启动流程
更多MyCat源码分析,请戳MyCat源码分析系列 MyCat配置信息 除了一些默认的配置参数,大多数的MyCat配置信息是通过读取若干.xml/.properties文件获取的,主要包括: 1)se ...
- 8、SpringMVC源码分析(3):分析ModelAndView的形成过程
首先,我们还是从DispatcherServlet.doDispatch(HttpServletRequest request, HttpServletResponse response) throw ...
- 框架-springmvc源码分析(二)
框架-springmvc源码分析(二) 参考: http://www.cnblogs.com/leftthen/p/5207787.html http://www.cnblogs.com/leftth ...
- 框架-springmvc源码分析(一)
框架-springmvc源码分析(一) 参考: http://www.cnblogs.com/heavenyes/p/3905844.html#a1 https://www.cnblogs.com/B ...
- [心得体会]SpringMVC源码分析
1. SpringMVC (1) springmvc 是什么? 前端控制器, 主要控制前端请求分配请求任务到service层获取数据后反馈到springmvc的view层进行包装返回给tomcat, ...
随机推荐
- 数据迁移实战:基于Kettle的Mysql到DB2的数据迁移
From:https://my.oschina.net/simpleton/blog/525675 一.什么是ETL ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数 ...
- javacript中apply和call的区别
apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性. 接受的参数是一个字符串. call:和apply的意思一样,只不过是参数列表不一样. 接收的参数是一个数组. 例如: <s ...
- HDU 1418 抱歉 (欧拉公式)
[题目链接]:pid=1418">click here~~ [题目大意]: 假设平面上有n个点,而且每一个点至少有2条曲线段和它相连,就是说,每条曲线都是封闭的.同一时候,我们规定: ...
- 深度解析开发项目之 03 - enum的使用
深度解析开发项目之 03 - enum的使用 01 - 在#import和@interface之间定义typedef enum 注意: 默认是0,1,2,3 02 - 定义可以操作的数据类型的属性 0 ...
- Topcoder SRM 638 DIV 2 (大力出奇迹)
水题,就是一个暴力.大力出奇迹. Problem Statement There is a narrow passage. Inside the passage there are some wo ...
- Chisel辅助iOS 应用程序调试,MusicApp模仿酷狗4.0 UI框架
本文转载至 http://www.cocoachina.com/ios/20140825/9446.html Chisel Chisel集合了大量的LLDB 命令来辅助iOS 应用程序调试,并支持添 ...
- 开源G711A/PCMA、G711U/PCMU、G726、PCM转码AAC项目EasyAACEncoder
项目及源码地址:https://github.com/EasyDarwin/EasyAACEncoder EasyAACEncoder 是EasyDarwin开源流媒体服务团队整理.开发的一款音频转码 ...
- JAVA工厂方法模式(Factory Method)
1.普通工厂模式 普通工厂模式:就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建. 1-1.建立Sender接口 public interface Sender { public void ...
- keybd_event、SendInput笔记
void keybd_event(BYTE bVk, BYTE bScan, DWORD dwFlags, ULONG_PTR dwExtraInfo); bVk:虚拟键码 bScan:键的硬件扫描码 ...
- 创建一个catkin工作空间
先确定自己的环境变量是否设置正确 export | grep ROS 若出现如下的,说明是正确的 declare -x ROSLISP_PACKAGE_DIRECTORIES="" ...