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包中,为了更直观的理解,先上代码。

?
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
packageorg.springframework.web.servlet;
 
importjava.util.ArrayList;
importjava.util.Arrays;
importjava.util.List;
 
importorg.springframework.util.CollectionUtils;
 
publicclassHandlerExecutionChain {
 
    privatefinalObject handler;
 
    privateHandlerInterceptor[] interceptors;
 
    privateList<HandlerInterceptor> interceptorList;
 
    publicHandlerExecutionChain(Object handler) {
        this(handler,null);
    }
 
    publicHandlerExecutionChain(Object handler, HandlerInterceptor[] interceptors) {
        if(handlerinstanceofHandlerExecutionChain) {
            HandlerExecutionChain originalChain = (HandlerExecutionChain) handler;
            this.handler = originalChain.getHandler();
            this.interceptorList = newArrayList<HandlerInterceptor>();
            CollectionUtils.mergeArrayIntoCollection(originalChain.getInterceptors(),this.interceptorList);
            CollectionUtils.mergeArrayIntoCollection(interceptors,this.interceptorList);
        }
        else{
            this.handler = handler;
            this.interceptors = interceptors;
        }
    }
 
    publicObject getHandler() {
        returnthis.handler;
    }
 
    publicvoidaddInterceptor(HandlerInterceptor interceptor) {
        initInterceptorList();
        this.interceptorList.add(interceptor);
    }
 
    publicvoidaddInterceptors(HandlerInterceptor[] interceptors) {
        if(interceptors != null) {
            initInterceptorList();
            this.interceptorList.addAll(Arrays.asList(interceptors));
        }
    }
 
    privatevoidinitInterceptorList() {
        if(this.interceptorList == null) {
            this.interceptorList = newArrayList<HandlerInterceptor>();
        }
        if(this.interceptors != null) {
            this.interceptorList.addAll(Arrays.asList(this.interceptors));
            this.interceptors = null;
        }
    }
 
    publicHandlerInterceptor[] getInterceptors() {
        if(this.interceptors == null&&this.interceptorList != null) {
            this.interceptors = this.interceptorList.toArray(newHandlerInterceptor[this.interceptorList.size()]);
        }
        returnthis.interceptors;
    }
 
    @Override
    publicString toString() {
        if(this.handler == null) {
            return"HandlerExecutionChain with no handler";
        }
        StringBuilder sb = newStringBuilder();
        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");
            }
        }
        returnsb.toString();
    }
 
}
乱七八糟一大堆,相信你也没全看完,也没必要全看。其实只需要看两行足矣。
?
1
2
3
privatefinalObject handler;
 
privateHandlerInterceptor[] interceptors;

不出我们所料,一个实质执行对象,还有一堆拦截器。这不就是Struts2中的实现么,SpringMVC没有避嫌,还是采用了这种封装。得到HandlerExecutionChain这个执行链(execution chain)之后,下一步的处理将围绕其展开。

在Dispatcher中,执行拦截器
在执行handler之前:
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);}}}


配置拦截器:

 

java代码:
查看复制到剪贴板打印
  1. <bean name="/test" class="cn.javass.chapter5.web.controller.TestController"/>  
  2. <bean id="handlerInterceptor1"   
  3. class="cn.javass.chapter5.web.interceptor.HandlerInterceptor1"/>  
  4. <bean id="handlerInterceptor2"   
  5. class="cn.javass.chapter5.web.interceptor.HandlerInterceptor2"/>  
  6.    

 

java代码:
查看复制到剪贴板打印
  1. <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">  
  2.     <property name="interceptors">  
  3.         <list>  
  4.            <ref bean="handlerInterceptor1"/>  
  5.           <ref bean="handlerInterceptor2"/>  
  6.         </list>  
  7.     </property>  
  8. </bean>  

 




参考:

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

0 0
原创粉丝点击