springMVC-Interceptor-源碼分析

本文主要記錄本身學習過程,若有錯誤請指出

一.用法

1.常引用攔截器 : HandlerInterceptor

代碼以下:web

本身實現的攔截器
上圖代碼中 myMyHandlerInterceptor 注意:

  1. 實現HandlerInterceptor接口
  2. @Component 註解

如今spring-ioc 容器中已經存在我本身建立的攔截器,可是還要把它WebMvcConfigurationSupport(後面會講爲啥要交給它管理)spring

代碼以下:spring-mvc

要完成對攔截器的使用,上圖代碼中注意兩點:

  1. 重寫 addInterceptors 方法
  2. @Configuration

上述作法以後可使用 攔截器了

二.源碼

看源碼 逆向思惟 -> 攔截器在哪裏執行的 -> 攔截器是哪裏來的

1.攔截在哪裏執行的

  1. 我看到網上有不少說攔截器的實現原理是動態代理,其實並非, aop的實現原理是動態代理
  2. 攔截器的實現原理是執行鏈 HandlerExecutionChain
  3. 這個過程是HandlerExecutionChain是spring-mvc(由於這個文章記錄的是攔截器,不會多說springmvc的東西) 中產生的.

執行代碼以下: org.springframework.web.servlet.DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse)mvc

上面代碼中的標註 1,2,3:

  1. 根據handlerMapping獲取執行鏈HandlerExecutionChain(不一樣的請求映射關係是放在不懂的mapping中的,這裏不一樣的請求指的是不一樣的controller或者是資源請求,這塊是mvc的東西很少說了.),正常獲取的mpping爲requestMappingHandlerMapping
  2. 獲取HandlerExecutionChain以後標註2的執行代碼就是攔截器的執行

3. 標註3的執行代碼正常的請求,此處不詳解

2.攔截器從哪裏來的

執行時期

  1. 獲取全部的攔截器,發現攔截器是存放在 HandlerExecutionChain.interceptors中.
  2. HandlerExecutionChain 是在 org.springframework.web.servlet.DispatcherServlet.getHandler(HttpServletRequest)中返回的,說明HandlerExecutionChain.interceptors也是在這個時候別賦值的.
  3. DispatcherServlet.getHandler(HttpServletRequest)代碼以下:

AbstractHandlerMapping.getHandlerExecutionChain(Object, HttpServletRequest)app

說明 HandlerExecutionChain interceptors 是 從 AbstractHandlerMapping.adaptedInterceptors中拿得值

spring啓動時期

如今咱們知道了 執行的攔截器是從 AbstractHandlerMapping.adaptedInterceptors中拿到的

先看下AbstractHandlerMapping的結構,發現咱們上面說到的requestMappinghandlerMapping是它的子類,這個也就是咱們要講的重點(requestMappinghandlerMapping的實例化過程)學習

這個地方先說下我看這段源碼的思路

  1. 咱們須要探究的是AbstractHandlerMapping.interceptors.由於咱們getHandler中使用的是requestMappinghandlerMapping的實例.他們又是父子關係.因此interceptors是在requestMappingHandlerMapping實例化過程當中被添加進去的.
  2. 思路到了這個地方,要知道,一個實例spring建立的過程: 放入BeanDefinitionMap -> getBean()(這裏springIoc的源碼不說了,之後有時間在寫).
  3. 在getBean的執行地方debug 條件爲BeanName.equals("requestMappingHandlerMapping"),發現不是經過構造器建立的,是根據@bean建立的.

發現是在WebMvcConfigurationSupport.requestMappingHandlerMapping()

AbstractHandlerMapping.setInterceptors(Object...)

WebMvcConfigurationSupport.getInterceptors() spa

看了上面的代碼你會發現addInterceptors是被咱們重寫的

咱們把本身的攔截器傳給了這個方法.

總結:

攔截器是在springmvc處理請求的時候執行debug

是在執行鏈中存放的.3d

執行鏈中的 interceptors 是從AbstractHandlerMapping中拿到的.代理

AbstractHandlerMapping 中的 攔截器 是在 requestMappingHandlerMapping 初始化的過程存放的.

requestMappingHandlerMapping 初始化的時候 會調用 WebMvcConfigurationSupport 中的 addInterceptors()方法

這個方法被咱們重寫了,就是在使用 攔截器 的兩個步驟中的 第二步 ,咱們把本身寫的攔截器傳了進去

相關文章
相關標籤/搜索