1.1.1 ActionInvocation类
ActionInvocation定义为一个接口,主要作用是表现action的执行状态。它拥有拦截器和action的实例。通过反复的执行invoke方法。首先被actionProxy,然后是拦截器,所有拦截器执行完后就是action和result .
![](https://img-blog.csdn.net/20140624194915484?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3hiMDg0MTkwMTExNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图3.3.4 ActionInvocation类的主要方法
1.1.2 DefaultActionInvocation类
DefaultActionInvocation类是ActionInvocation接口的实现类. 一般都用该类实例化ActionInvocation。 主要的方法如下:
![](https://img-blog.csdn.net/20140624194932906?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3hiMDg0MTkwMTExNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图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);
}
}
| |