接上一篇-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, ...
随机推荐
-
为什么要用base64编码
1.需求 了解为什么要使用base64对数据编码 2.理由 因为传输二进制数据的时候,网络中间的有些路由会把ascii码中的不可见字符删了,导致数据不一致.一般也会对url进行base64编码 Whe ...
-
ASP.NET MVC处理JsonResult返回时间DateTime问题
在开发ASP.NET MVC时,如果你有使用jQuery的Ajax去获取一些json数据时,其中数据返回有包含日期时间的话,也许会觉得有点小问题. 现针对此问题,写一个小例子来演示一下,创建一个控制器 ...
-
直播技术资源站 http://lib.csdn.net/base/liveplay/structure
直播技术资源站 http://lib.csdn.net/base/liveplay/structure
-
hdu 3635 Dragon Balls (带权并查集)
Dragon Balls Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
-
ES6学习(1)——如何通过babel将ES6转化成ES5
使用babel编译ES6 babel是一个工具,可以通过多个平台,让js文件从ES6转化成ES5,从而支持一些浏览器并未支持的语法. Insall babel $ sudo npm install b ...
-
dplyr 数据操作 常用函数(3)
接下了我们继续了解dplyr中有用的函数 1.if_else() if_else主要用于在数据做判断用 x<-data.frame(id=1:6, name=c("wang" ...
-
Android OpenGL ES(四)关于EGL .
OpenGL ES的javax.microedition.khronos.opengles 包定义了平台无关的GL绘图指令,EGL(javax.microedition.khronos.egl ) 则 ...
-
textarea的换行符处理以及正确的在Html中显示
个人不太喜欢在页面做过多的逻辑处理,贴出java的处理方式 /** * Html转换为TextArea文本 * @return */ public static String HtmlToText(S ...
-
获取ArcMap窗口句柄,通过WinAPI获取工作空间中点击要素的系统桌面坐标实现窗体跟随
这里用了个“桌面坐标”,是希望区分一下ArcGis的“屏幕坐标”(与之对应的还有一个“地理坐标”). 什么是“屏幕坐标”呢?使用ITool接口的OnMouseDown方法获取的“x,y”值即是,其原点 ...
-
原生js上传图片时的预览
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...