学习一个框架,首要的是要先领会它的设计思想。从抽象、从全局上来审视这个框架。其中最具有参考价值的,就是这个框架所定义的核心接口。核心接口定义了框架的骨架,也在最抽象的意义上表达了框架的设计思想。
前因:发现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包中,为了更直观的理解,先上代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
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();
}
}
|
1
2
3
|
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 afterCompletion
if (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