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); } } | |