再次进一步探讨一个action请求,会有哪些过程:
第①步:
DefaultActionProxy.java(ActionProxy的实现类),下面是DefaultActionProxy中的execute()方法: struts2中的filter的StrutsPrepareAndExecuteFilter会初始化一个ActionProxy实例ActionProxy的实现类是DefaultActionProxy,此对象就是一个action的动态代理对象,并调用ActionProxy的excute方法。
DefaultActionProxy.java
public String execute() throws Exception { ActionContext nestedContext = ActionContext.getContext(); ActionContext.setContext(invocation.getInvocationContext()); String retCode = null; String profileKey = "execute: "; try { UtilTimerStack.push(profileKey); retCode = invocation.invoke();//标记 } finally { if (cleanupContext) { ActionContext.setContext(nestedContext); } UtilTimerStack.pop(profileKey); } return retCode; }
上面加粗的代码中即表明调用了ActionProxy的execute()方法,该execute()方法又调用了ActionInvocation.invoke()方法:
接下来查看ActionInvocation的实现类DefaultActionInvocation中的invoke()方法只贴出重要部分:
DefaultActionInvoca.java
// ..................//省略
if (interceptors.hasNext()) {
final InterceptorMapping interceptor = interceptors.next();
String interceptorMsg = "interceptor: " + interceptor.getName();
UtilTimerStack.push(interceptorMsg);
try {
resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);//标记
}
finally {
UtilTimerStack.pop(interceptorMsg);
}
} else {
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
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);
}
}
}
第③步:
上面代码可看出该ActionInvocation.invoke()方法又依次会调用拦截器类对象intercept(DefaultActionInvocation.this)方法,而该intercept(DefaultActionInvocation.this)方法又会调用ActionInvocation类的invoke()方法,递归实现(可以参考博文前面的拦截器原理讲解)。一直到拦截器全都调完,然后调用resultCode = invokeActionOnly(),该方法就是调用action.execute()方法。然后下面还有代码preResultListeners != null,这里的意思是在返回resultCode之前会调用监听器的相关方法。
关于上面的invoke()递归实现可以参见:http://blog.csdn.net/zjlolife/article/details/8745916
以上就是struts2中的处理action的流程。更进一步的详解待续.........