1. 程式人生 > >spring的攔截器和aop

spring的攔截器和aop

探祕Spring AOP

         AOP(Aspect Oriented Programming),即面向切面程式設計;通過預編譯方式和執行期動態代理實現程式功能的統一維護的

一種技術。

         AOP是什麼?

         1、AOP是一種程式設計正規化,不是程式語言。

         2、每一個切面目的是為了解決特定問題,不能解決所有的問題。

         3、AOP是OOP(面向物件程式設計)的補充。

        AOP原理         

         spring AOP基於代理的方式,對原來的業務類生成代理物件(在執行期通過反射技術生成的),代理物件是原有物件的

代理,在代理物件中對原有業務物件的方法進行增強。springAOP底層基於jdk介面代理,cglib實現子類代理,springAop通過動

態代理實現。

         代理包括靜態代理和動態代理:

         靜態代理:程式設計師直接編寫一個代理類,class檔案已經存在。

         動態代理:在程式的執行期,通過反射機制生成一個代理物件。動態代理又分為jdk介面代理,cglib實現子類代理。

         攔截器

         java裡的攔截器是動態攔截Action呼叫的物件。它提供了一種機制可以使開發者可以定義在一個action執行的前後執行

的程式碼,也可以在一個action執行前阻止其執行,同時也提供了一種可以提取action中可重用部分的方式。在AOP(Aspect-

Oriented Programming)中攔截器用於在某個方法或欄位被訪問之前,進行攔截然後在之前或之後加入某些操作。

     原理

  攔截器 Interceptor 的攔截功能是基於 Java 的動態代理來實現的,具體可以參考博文“ 用 Java 實現攔截器 Interceptor 的攔截功能 ”,也可以通過閱讀 Spring 原始碼來了解更為權威的實現細節。

    實現方法

  在 Spring 框架之中,咱們要想實現攔截器的功能,主要通過兩種途徑,第一種是實現HandlerInterceptor

介面,第二種是實現WebRequestInterceptor介面。接下來,咱們分別詳細的介紹兩者的實現方法。

     HandlerInterceptor 介面

       在HandlerInterceptor介面中,定義了 3 個方法,分別為preHandle()postHandle()afterCompletion(),咱們就是通過複寫這 3 個方法來對使用者的請求進行攔截處理的。因此,咱們可以通過直接實現HandlerInterceptor介面來實現攔截器的功能。不過在 Spring 框架之中,其還提供了另外一個介面和一個抽象類,實現了對HandlerInterceptor介面的功能擴充套件,分別為:AsyncHandlerInterceptorHandlerInterceptorAdapter.

    對於AsyncHandlerInterceptor介面,其在繼承HandlerInterceptor介面的同時,又聲明瞭一個新的方法afterConcurrentHandlingStarted();而HandlerInterceptorAdapter抽象類,則是更進一步,在其繼承AsyncHandlerInterceptor介面的同時,又複寫了preHandle方法。因此,AsyncHandlerInterceptor更像是一個過渡的介面。

     在實際應用中,咱們一般都是通過實現HandlerInterceptor介面或者繼承HandlerInterceptorAdapter抽象類,複寫preHandle()postHandle()afterCompletion()這 3 個方法來對使用者的請求進行攔截處理的。下面,咱們就詳細介紹這個 3 個方法。

  • preHandle(HttpServletRequest request, HttpServletResponse response, Object handle)方法,該方法在請求處理之前進行呼叫。SpringMVC 中的 Interceptor 是鏈式呼叫的,在一個應用中或者說是在一個請求中可以同時存在多個 Interceptor 。每個 Interceptor 的呼叫會依據它的宣告順序依次執行,而且最先執行的都是 Interceptor 中的 preHandle 方法,所以可以在這個方法中進行一些前置初始化操作或者是對當前請求做一個預處理,也可以在這個方法中進行一些判斷來決定請求是否要繼續進行下去。該方法的返回值是布林值 Boolean 型別的,當它返回為 false 時,表示請求結束,後續的 Interceptor 和 Controller 都不會再執行;當返回值為 true 時,就會繼續呼叫下一個 Interceptor 的 preHandle 方法,如果已經是最後一個 Interceptor 的時候,就會是呼叫當前請求的 Controller 中的方法。
  • postHandle(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView)方法,通過 preHandle 方法的解釋咱們知道這個方法包括後面要說到的 afterCompletion 方法都只能在當前所屬的 Interceptor 的 preHandle 方法的返回值為 true 的時候,才能被呼叫。postHandle 方法在當前請求進行處理之後,也就是在 Controller 中的方法呼叫之後執行,但是它會在 DispatcherServlet 進行檢視返回渲染之前被呼叫,所以咱們可以在這個方法中對 Controller 處理之後的 ModelAndView 物件進行操作。postHandle 方法被呼叫的方向跟 preHandle 是相反的,也就是說,先宣告的 Interceptor 的 postHandle 方法反而會後執行。這和 Struts2 裡面的 Interceptor 的執行過程有點型別,Struts2 裡面的 Interceptor 的執行過程也是鏈式的,只是在 Struts2 裡面需要手動呼叫 ActionInvocation 的 invoke 方法來觸發對下一個 Interceptor 或者是 action 的呼叫,然後每一個 Interceptor 中在 invoke 方法呼叫之前的內容都是按照宣告順序執行的,而 invoke 方法之後的內容就是反向的。
  • afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)方法,也是需要當前對應的 Interceptor 的 preHandle 方法的返回值為 true 時才會執行。因此,該方法將在整個請求結束之後,也就是在 DispatcherServlet 渲染了對應的檢視之後執行,這個方法的主要作用是用於進行資源清理的工作。