Spring Mvc 源码理解。

学习一个框架,首要的是要先领会它的设计思想。从抽象、从全局上来审视这个框架。其中最具有参考价值的,就是这个框架所定义的核心接口。核心接口定义了框架的骨架,也在最抽象的意义上表达了框架的设计思想。


前因:发现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)之后,下一步的处理将围绕其展开。

在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 afterCompletion
				if (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

    原文作者:Spring MVC
    原文地址: https://blog.csdn.net/czlpf/article/details/47780557
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞