深入解析Struts攔截器的工作原理
什麼是攔截器
攔截器是在請求到達Action前後進行的一系列操作,Struts2默認自帶了很大攔截器,這些攔截器定義在struts-default.xml中。Struts2中的攔截器是基於AOP動態代理思想的。關於Struts的結構,有一張很經典的圖:
打開今日頭條,查看更多圖片在這張圖上可以清楚的看到請求經過了Action代理,然後通過了一系列Interceptor最終返回,下面我們就來了解一下,圖中的Interceptor1,2,3是如何工作的。
攔截器的工作原理
在搭建Struts2框架時,我們首先需要在web.xml中配置StrutsPrepareAndExecuteFilter過濾器,這是因為請求會首先經過這個過濾器,然後會經過很多層,最後依次經過每一個攔截器(包括自定義的攔截器)。具體經過了哪些層,可以看下面這張圖:
從這張圖可以看到每一層的包含關係,重點看一下最裡面的兩層,紅色箭頭和黃色箭頭的部分,這兩個方法是一個遞歸調用的過程,也就是說,當在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();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
關於遞歸的過程,我自己畫了一個示意圖:
看完上面的解釋,這時候再回去看一開始的struts框架結構圖的interceptor1,2,3,應該可以很容易理解了。
以上就是我對攔截器的執行的理解,希望能夠幫助到大家!
※推薦 9 個樣式化組件的 React UI 庫
※編寫高質量代碼 改善Python程序的91個建議
TAG:程序員小新人學習 |