1. 程式人生 > >深入解析Struts攔截器的工作原理

深入解析Struts攔截器的工作原理

Struts2中有三大核心:ognl,攔截器和action;想要學好Struts2,這三個核心是重中之重;這裡就給大家介紹一下Struts2攔截器的工作原理

什麼是攔截器

攔截器是在請求到達Action前後進行的一系列操作,Struts2預設自帶了很大攔截器,這些攔截器定義在struts-default.xml中。Struts2中的攔截器是基於AOP動態代理思想的。關於Struts的結構,有一張很經典的圖:

strtus結構

在這張圖上可以清楚的看到請求經過了Action代理,然後通過了一系列Interceptor最終返回,下面我們就來了解一下,圖中的Interceptor1,2,3是如何工作的。

攔截器的工作原理

在搭建Struts2框架時,我們首先需要在web.xml中配置StrutsPrepareAndExecuteFilter過濾器,這是因為請求會首先經過這個過濾器,然後會經過很多層,最後依次經過每一個攔截器(包括自定義的攔截器)。具體經過了哪些層,可以看下面這張圖:

struts2請求的流程

從這張圖可以看到每一層的包含關係,重點看一下最裡面的兩層,紅色箭頭和黃色箭頭的部分,這兩個方法是一個遞迴呼叫的過程,也就是說,當在invoke()方法中呼叫一個攔截器時,攔截器中會有invocation.invoke()這一句,這一句表明會跳出當前攔截器,回到上一級,呼叫下一個攔截器,當所有的攔截器都呼叫了並且action執行完畢後,會遞歸回調攔截器中沒有執行完畢的內容。那麼invoke()方法中是如何呼叫下一個攔截器的呢?看看原始碼就明白了(最核心的程式碼):

 	  if (interceptors.hasNext()) {
                final InterceptorMapping interceptorMapping = interceptors.next();
                String interceptorMsg = "interceptorMapping: " + interceptorMapping.getName();
                UtilTimerStack.push(interceptorMsg);
                try {
                    Interceptor interceptor = interceptorMapping.getInterceptor();
                    if (interceptor instanceof WithLazyParams) {
                        interceptor = lazyParamInjector.injectParams(interceptor, interceptorMapping.getParams(), invocationContext);
                    }
                    resultCode = interceptor.intercept(DefaultActionInvocation.this);
                } finally {
                    UtilTimerStack.pop(interceptorMsg);
                }
            } else {
                resultCode = invokeActionOnly();
            }

關於遞迴的過程,我自己畫了一個示意圖:

struts2攔截器遞迴執行

看完上面的解釋,這時候再回去看一開始的struts框架結構圖的interceptor1,2,3,應該可以很容易理解了。
以上就是我對攔截器的執行的理解,希望能夠幫助到大家!