再进一步分析struts2拦截action的机制流程及原理

来源:互联网 发布:网店优化推广 编辑:程序博客网 时间:2024/05/29 17:38

再次进一步探讨一个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的流程。更进一步的详解待续.........


原创粉丝点击