標籤:struts struts2.0 技術
1.1.1 ActionInvocation類
ActionInvocation定義為一個介面,主要作用是表現action的執行狀態。它擁有攔截器和action的執行個體。通過反覆的執行invoke方法。首先被actionProxy,然後是攔截器,所有攔截器執行完後就是action和result .
圖3.3.4 ActionInvocation類的主要方法
1.1.2 DefaultActionInvocation類
DefaultActionInvocation類是ActionInvocation介面的實作類別. 一般都用該類執行個體化ActionInvocation。 主要的方法如下:
圖3.3.5 DefaultActionInvocation類的主要方法
關鍵方法:invoke()方法
executed = false; 預設為false,表示該action還沒有執行。 如果執行就會拋出已經執行的異常。
然後判斷攔截器是否已經配置,如果配置了攔截器就會從配置資訊中獲得攔截器配置類InterceptorMapping。此類中只包含兩個屬性,一個就是name和interceptor執行個體。
public String invoke() throws Exception { String profileKey = "invoke: "; try { UtilTimerStack.push(profileKey); if (executed) { throw new IllegalStateException("Action has already executed"); } //遞迴執行interceptor if (interceptors.hasNext()) { //interceptors是InterceptorMapping實際上是像一個像//FilterChain一樣的Interceptor鏈 //通過調用Invocation.invoke()實現遞迴牡迴圈 final InterceptorMapping interceptor =interceptors.next(); String interceptorMsg = "interceptor: " + interceptor.getName(); UtilTimerStack.push(interceptorMsg); try { //在每個Interceptor的方法中都會return invocation.invoke() resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this); } finally { UtilTimerStack.pop(interceptorMsg); } } else { //當所有interceptor都執行完,最後執行Action,invokeActionOnly會調用//invokeAction()方法 resultCode = invokeActionOnly(); } |
|
// this is needed because the result will be executed, then control will return to the Interceptor, which will // return above and flow through again //在Result返回之前調用preResultListeners //通過executed控制,只執行一次 if (!executed) { if (preResultListeners !=null) { for (Object preResultListener :preResultListeners) { PreResultListener listener = (PreResultListener) preResultListener; String _profileKey = "preResultListener: "; try { UtilTimerStack.push(_profileKey); listener.beforeResult(this,resultCode); } finally { UtilTimerStack.pop(_profileKey); } } } // now execute the result, if we‘re supposed to //執行result。 if (proxy.getExecuteResult()) { executeResult(); } executed = true; } return resultCode; } finally { UtilTimerStack.pop(profileKey); } } |
|