Spring Mvc 源码理解。
来源:互联网 发布:帮软件充值话费的软件 编辑:程序博客网 时间:2024/05/19 17:04
学习一个框架,首要的是要先领会它的设计思想。从抽象、从全局上来审视这个框架。其中最具有参考价值的,就是这个框架所定义的核心接口。核心接口定义了框架的骨架,也在最抽象的意义上表达了框架的设计思想。
前因:发现springMvc可以使用spring中的bean,way?
由于SpringMvc就是Servlet,必须先了解servlet原理:http://blog.csdn.net/czlpf/article/details/47781473
一。SpringMvc的入口分为 init() 和 service() 两个入口。
1.init()仅在DispatherServlet创建的时候执行一次,为容器和组件做初始化。
2.service()方法在每次http请求的时候都执行。
Servlet的所以请求都会通过执行HttpServlet中service(ServletRequest ,ServletResponse)方法,该方法执行了service(HttpServletRequest,HttpServletResponse)
而该方法在FrameworkServlet中被重写,所以执行FrameworkServlet中的service(HttpServletRequest,HttpServletResponse)方法。
-----》》FrameworkServlet.processRequest()
-----》》DispatcherServlet.doService()
-----》》DispatcherServlet.doDispatch()
这个doDispatch()就是每次http请求到springMvc的重点。
首先选择一个handler获得HandlerExecutionChain
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {for (HandlerMapping hm : this.handlerMappings) {if (logger.isTraceEnabled()) {logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");}HandlerExecutionChain handler = hm.getHandler(request);if (handler != null) {return handler;}}return null;}
其中this.handlerMappings在init()方法已经初始化。详情查看init()流程。
下面研究这个HandlerExecutionChain:
HandlerExecutionChain类的代码不长,它定义在org.springframework.web.servlet包中,为了更直观的理解,先上代码。
package
org.springframework.web.servlet;
import
java.util.ArrayList;
import
java.util.Arrays;
import
java.util.List;
import
org.springframework.util.CollectionUtils;
public
class
HandlerExecutionChain {
private
final
Object handler;
private
HandlerInterceptor[] interceptors;
private
List<HandlerInterceptor> interceptorList;
public
HandlerExecutionChain(Object handler) {
this
(handler,
null
);
}
public
HandlerExecutionChain(Object handler, HandlerInterceptor[] interceptors) {
if
(handler
instanceof
HandlerExecutionChain) {
HandlerExecutionChain originalChain = (HandlerExecutionChain) handler;
this
.handler = originalChain.getHandler();
this
.interceptorList =
new
ArrayList<HandlerInterceptor>();
CollectionUtils.mergeArrayIntoCollection(originalChain.getInterceptors(),
this
.interceptorList);
CollectionUtils.mergeArrayIntoCollection(interceptors,
this
.interceptorList);
}
else
{
this
.handler = handler;
this
.interceptors = interceptors;
}
}
public
Object getHandler() {
return
this
.handler;
}
public
void
addInterceptor(HandlerInterceptor interceptor) {
initInterceptorList();
this
.interceptorList.add(interceptor);
}
public
void
addInterceptors(HandlerInterceptor[] interceptors) {
if
(interceptors !=
null
) {
initInterceptorList();
this
.interceptorList.addAll(Arrays.asList(interceptors));
}
}
private
void
initInterceptorList() {
if
(
this
.interceptorList ==
null
) {
this
.interceptorList =
new
ArrayList<HandlerInterceptor>();
}
if
(
this
.interceptors !=
null
) {
this
.interceptorList.addAll(Arrays.asList(
this
.interceptors));
this
.interceptors =
null
;
}
}
public
HandlerInterceptor[] getInterceptors() {
if
(
this
.interceptors ==
null
&&
this
.interceptorList !=
null
) {
this
.interceptors =
this
.interceptorList.toArray(
new
HandlerInterceptor[
this
.interceptorList.size()]);
}
return
this
.interceptors;
}
@Override
public
String toString() {
if
(
this
.handler ==
null
) {
return
"HandlerExecutionChain with no handler"
;
}
StringBuilder sb =
new
StringBuilder();
sb.append(
"HandlerExecutionChain with handler ["
).append(
this
.handler).append(
"]"
);
if
(!CollectionUtils.isEmpty(
this
.interceptorList)) {
sb.append(
" and "
).append(
this
.interceptorList.size()).append(
" interceptor"
);
if
(
this
.interceptorList.size() >
1
) {
sb.append(
"s"
);
}
}
return
sb.toString();
}
}
private
final
Object handler;
private
HandlerInterceptor[] interceptors;
不出我们所料,一个实质执行对象,还有一堆拦截器。这不就是Struts2中的实现么,SpringMVC没有避嫌,还是采用了这种封装。得到HandlerExecutionChain这个执行链(execution chain)之后,下一步的处理将围绕其展开。
if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}执行handler:
// Actually invoke the handler.mv = ha.handle(processedRequest, response, mappedHandler.getHandler());执行handler之后:
mappedHandler.applyPostHandle(processedRequest, response, mv);
catch (Exception ex) {triggerAfterCompletion(processedRequest, response, mappedHandler, ex);}catch (Error err) {triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);}
finally {if (asyncManager.isConcurrentHandlingStarted()) {// Instead of postHandle and afterCompletionif (mappedHandler != null) {mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);}}else {// Clean up any resources used by a multipart request.if (multipartRequestParsed) {cleanupMultipart(processedRequest);}}}
配置拦截器:
参考:
http://my.oschina.net/lichhao/blog/99039
http://downpour.iteye.com/blog/1341459
http://blog.csdn.net/soundfly/article/details/17380111
http://sishuok.com/forum/blogCategory/showByCategory.html?categories_id=106&user_id=2
- Spring Mvc 源码理解。
- Spring MVC的理解
- spring mvc理解
- Spring MVC深入理解
- Spring Mvc 简单理解
- 深入理解Spring MVC
- 深入理解Spring MVC
- 深入理解spring-mvc
- Spring MVC源码分析
- spring mvc 源码小解
- Spring MVC源码解析
- Spring MVC 源码
- Spring MVC源码分析
- Spring MVC源码剖析
- Spring mvc 源码学习
- Spring MVC源码分析
- Spring MVC源码分析
- Spring MVC源码剖析
- 二叉树螺旋遍历
- Android设计模式系列--观察者模式
- Android开发eclipse快捷键
- linux笔记之2--makefile
- 如何在Linux创建安全的临时文件
- Spring Mvc 源码理解。
- SpannableString设置除Color类中颜色以外的自定义颜色
- Android app身体质量指数(BMI)
- C++ 小记 vector 容器(一)
- arcgis api for javascript 图层控制
- Kettle发送邮件
- arp
- 黑马程序员—接口,异常,包
- 数据库平时错误和使用经验的总结