springmvc源码分析
版权声明:本文为博主原创文章,未经博主允许不得转载。
Blog文章地址:http://www.jmatrix.org/spring/453.html
1. 概述
对于Web开发者,MVC模型是大家再熟悉不过的了,SpringMVC中,满足条件的请求进入到负责请求分发的DispatcherServlet,DispatcherServlet根据请求url到控制器的映射(HandlerMapping中保存),HandlerMapping最终返回HandlerExecutionChain,其中包含了具体的处理对象handler(也即我们编程时写的controller)以及一系列的拦截器interceptors,此时DispatcherServlet会根据返回的HandlerExecutionChain中的handler找到支持这一处理器类型的适配器(handlerAdapter),在处理器适配器中最终会去调用控制器的请求响应方法并返回结果视图(ModelAndView),得到结果视图后,通过render方法完成结果的显示。
HanderMapping的继承体系:
HandlerAdapter的继承体系:
同样的视图解析器ViewResolver针对不同的输出格式也有一系列的实现类,具体可自己看。
2. 实现分析
以我自己的一个web项目中spring mvc的配置为例:
- <context:component-scan base-package="cn.ds.log" />
- <bean id="defaultHandlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
- <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
- </bean>
- <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
- </bean>
- <bean
- class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter">
- </bean>
- <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="prefix">
- <value>/WEB-INF/jsp/</value>
- </property>
- <property name="suffix">
- <value>.jsp</value>
- </property>
- </bean>
这里因为是采用全注解的方式,所以先通过context:component-scan配置让spring自定扫描的包路径,接着配置handlerMapping、handlerAdapter及ViewResolver,几乎包含了SpringMVC的配置中需要涉及的所有元素。后面需要涉及具体的HanderMapping等的实现时,将以这里配置中的实现为例进行分析,其它的大家“同理可解”。⊙﹏⊙b汗
2.1 Spring MVC初始化流程
DispatcherServlet的继承体系如:
看到它们继承自HttpServlet,你就知道初始化过程应该是从init方法开始了,整个初始化的流程为:
很简单是么?我也觉得是,至少从上面的时序图看来是这样,不过前提是你已经很了解Spring IOC的实现原理了。上面的时序图中,在5的initStragegies()中除了调用6,7的函数外,还有几个类似的初始化函数,因为这里主要是为了理解整个的流程,所以我都省略了。上面流程可能需要分析的地方就在于3,4步,我们看看initWebApplicationContext函数的实现:
- protected WebApplicationContext initWebApplicationContext() {
- WebApplicationContext rootContext =
- WebApplicationContextUtils.getWebApplicationContext(getServletContext());
- WebApplicationContext wac = null;
- if (this.webApplicationContext != null) {
- // A context instance was injected at construction time -> use it
- wac = this.webApplicationContext;
- if (wac instanceof ConfigurableWebApplicationContext) {
- ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
- if (!cwac.isActive()) {
- ……
- configureAndRefreshWebApplicationContext(cwac);
- }
- }
- }
- if (wac == null) {
- wac = findWebApplicationContext();
- }
- if (wac == null) {
- // No context instance is defined for this servlet -> create a local one
- wac = createWebApplicationContext(rootContext);
- }
- if (!this.refreshEventReceived) {
- // Either the context is not a ConfigurableApplicationContext with refresh
- // support or the context injected at construction time had already been
- // refreshed -> trigger initial onRefresh manually here.
- onRefresh(wac);
- }
- if (this.publishContext) {
- ……
- }
- return wac;
- }
看起来貌似有点复杂,其实理解了IOC容器的实现原理(可以看下“spring ioc源码分析”一文,⊙﹏⊙多年前弄的,这次暑假实习时又以读书报告的形式写了,感觉当年肿么可以写得这么乱……也是一种成长,不打算修改)就很简单,函数一开始会去获取WebApplicationContext对象,这个对象在ContextLoaderListener初始化IOC容器时就已经把它set到ServletContext的属性中,而且它也正是ConfigurableWebApplicationContext的实例,第一个if语句其实就是如果此时SpringIOC容器没有初始化的话就在这里启动IOC容器的初始化过程,因为看“省略(1)”中的代码你就知道,它会在这里调用refresh函数,“世人”都知道这就是IOC容器启动的入口,这里会解析配置文件springmvc-servlet.xml。
这里最终要执行onRefresh(),而这个就是SpringMVC初始化的入口。
(注:其实这里也可以配置log4j,通过其打印的info信息来看IOC与MVC的初始化顺序)
相关内容:
1. Spring MVC源码分析——请求处理,http://blog.csdn.net/shi1122/article/details/8041017
2. Spring MVC源码分析——视图解析,http://blog.csdn.net/shi1122/article/details/8586463
springmvc源码分析的更多相关文章
- 8、SpringMVC源码分析(3):分析ModelAndView的形成过程
首先,我们还是从DispatcherServlet.doDispatch(HttpServletRequest request, HttpServletResponse response) throw ...
- 7、SpringMVC源码分析(2):分析HandlerAdapter.handle方法,了解handler方法的调用细节以及@ModelAttribute注解
从上一篇 SpringMVC源码分析(1) 中我们了解到在DispatcherServlet.doDispatch方法中会通过 mv = ha.handle(processedRequest, res ...
- springMVC源码分析--ViewNameMethodReturnValueHandler返回值处理器(三)
之前两篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)和springMVC源码分析--HandlerMethodReturnValu ...
- springMVC源码分析--HandlerMethodReturnValueHandlerComposite返回值解析器集合(二)
在上一篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)我们介绍了返回值解析器HandlerMethodReturnValueHand ...
- springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)
之前两篇博客springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)和springMVC源码解析--HandlerMethodArgumentResol ...
- springMVC源码分析--访问请求执行ServletInvocableHandlerMethod和InvocableHandlerMethod
在之前一篇博客中springMVC源码分析--RequestMappingHandlerAdapter(五)我们已经简单的介绍到具体请求访问的执行某个Controller中的方法是在RequestMa ...
- springMVC源码分析--RequestMappingHandlerAdapter(五)
上一篇博客springMVC源码分析--HandlerAdapter(一)中我们主要介绍了一下HandlerAdapter接口相关的内容,实现类及其在DispatcherServlet中执行的顺序,接 ...
- springMVC源码分析--HttpRequestHandlerAdapter(四)
上一篇博客springMVC源码分析--HandlerAdapter(一)中我们主要介绍了一下HandlerAdapter接口相关的内容,实现类及其在DispatcherServlet中执行的顺序,接 ...
- springMVC源码分析--SimpleControllerHandlerAdapter(三)
上一篇博客springMVC源码分析--HandlerAdapter(一)中我们主要介绍了一下HandlerAdapter接口相关的内容,实现类及其在DispatcherServlet中执行的顺序,接 ...
- springMVC源码分析--SimpleServletHandlerAdapter(二)
上一篇博客springMVC源码分析--HandlerAdapter(一)中我们主要介绍了一下HandlerAdapter接口相关的内容,实现类及其在DispatcherServlet中执行的顺序,接 ...
随机推荐
- MySQL常用数据类型小结
在 MySQL 中,有三种主要的类型:字符串.数字和日期/时间类型. 目录 [隐藏] 1 字符串类型 2 数值类型 3 日期和时间类型 4 使用建议 5 艺搜参考 字符串类型 CHAR 0-255字 ...
- WPF datagrid 动态增加列
DataGrid动态增加列 <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.m ...
- 滚动到底部加载更多及下拉刷新listview的使用
最新内容建议直接访问原文:滚动到底部加载更多及下拉刷新listview的使用 本文主要介绍可同时实现下拉刷新及滑动到底部加载更多的ListView的使用. 该ListView优点包括:a. 可自定义下 ...
- APK瘦身实践
首发地址:http://www.jayfeng.com/2015/12/29/APK%E7%98%A6%E8%BA%AB%E5%AE%9E%E8%B7%B5/ 因为推广的需要,公司需要把APK的大小再 ...
- Swift3.0语言教程字符串与文件的数据转换
Swift3.0语言教程字符串与文件的数据转换 Swift3.0语言教程字符串与文件的数据转换,如果想要对字符串中的字符进行永久保存,可以将字符串中的字符写入到文件中.当然,开发者也可以将写入的内容进 ...
- MACD 基本用法
基本用法 1. MACD 金叉:DIFF 由下向上突破 DEA,为买入信号. 2. MACD 死叉:DIFF 由上向下突破 DEA,为卖出信号. 3. MACD 绿转红:MACD 值由负变正,市场由空 ...
- HDU5724 Chess(SG定理)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5724 Description Alice and Bob are playing a spe ...
- git的合并与推送
集中式合作模式 1.git fetch 获取远程更新 2.git merge origin/master 进行合并,如果报错,则相应解决.注:你得用git bash命令行执行才能看见报错详情,用ecl ...
- iOS 自动布局小结
1> sizeclasses 可以限制某个 storyboard 显示在什么样的屏幕上,如 当前 storyboard 在iPhone 的左斜右斜或 iPad上是否显示.. 2> Hug值 ...
- 一个简单的零配置命令行HTTP服务器 - http-server (nodeJs)
http-server 是一个简单的零配置命令行HTTP服务器, 基于 nodeJs. 如果你不想重复的写 nodeJs 的 web-server.js, 则可以使用这个. 安装 (全局安装加 -g) ...