ActionInvocation兑现分析
ActionInvocation实现分析
ActionInvocation是ActionProxy中非常重要的变量。在产生ActionProxy之后,调用proxy.prepare()来产生ActionInvocation的实例。
从ActionInvocation类的说明中,我们可以看到ActionInvocation包括拦截器和Action的实例。
An ActionInvocation represents the execution state of an Action. It holds the Interceptors and the Action instance. By repeated re-entrant execution of the invoke() method, initially by the ActionProxy, then by the Interceptors, the Interceptors are all executed, and then the Action and the Result.
那么他们是怎么实现的呢?来分析DefaultActionInvocation
DefaultActionInvocation包括如下的域:
不能从域中直接得到的接口方法是:
在它的构造器中
再来看init()方法:
再来看一个这个类的核心invoke()方法:
ActionInvocation是ActionProxy中非常重要的变量。在产生ActionProxy之后,调用proxy.prepare()来产生ActionInvocation的实例。
从ActionInvocation类的说明中,我们可以看到ActionInvocation包括拦截器和Action的实例。
An ActionInvocation represents the execution state of an Action. It holds the Interceptors and the Action instance. By repeated re-entrant execution of the invoke() method, initially by the ActionProxy, then by the Interceptors, the Interceptors are all executed, and then the Action and the Result.
那么他们是怎么实现的呢?来分析DefaultActionInvocation
DefaultActionInvocation包括如下的域:
protected Object action;//Object getAction() protected ActionProxy proxy;//ActionProxy getProxy() protected List preResultListeners;//void addPreResultListener(PreResultListener listener) protected Map extraContext; protected ActionContext invocationContext; protected Iterator interceptors; protected ValueStack stack;//ValueStack getStack(); protected Result result;//Result getResult() protected String resultCode;//String getResultCode() protected boolean executed = false;//boolean isExecuted(); protected boolean pushAction = true; protected ObjectFactory objectFactory; protected ActionEventListener actionEventListener;//void setActionEventListener(ActionEventListener listener) protected UnknownHandler unknownHandler;
不能从域中直接得到的接口方法是:
String invoke() throws Exception; String invokeActionOnly() throws Exception;
在它的构造器中
/** 在构造器的参数列表中,只有proxy能比较明确知道它的含义。 */ protected DefaultActionInvocation(final ObjectFactory objectFactory, final UnknownHandler handler, final ActionProxy proxy, final Map extraContext, final boolean pushAction, final ActionEventListener actionEventListener) throws Exception { UtilTimerStack.profile("create DefaultActionInvocation: ", new UtilTimerStack.ProfilingBlock<Object>() { public Object doProfiling() throws Exception { DefaultActionInvocation.this.proxy = proxy; DefaultActionInvocation.this.objectFactory = objectFactory; DefaultActionInvocation.this.extraContext = extraContext; DefaultActionInvocation.this.pushAction = pushAction; DefaultActionInvocation.this.unknownHandler = handler; DefaultActionInvocation.this.actionEventListener = actionEventListener; init(); return null; } }); }
再来看init()方法:
private void init() throws Exception { [//把extraContext放入contextMap,并把DefaultActionInvocation本身也放到contextMap中。还有对stack域的赋值。如果extraContext不存在ValueStack,则新产生一个。http://dl.iteye.com/upload/attachment/479236/fa9d2253-5ad4-3400-bb4f-b2a42cc91861.png Map contextMap = createContextMap(); //主要是利用传递进来的objectFactory来产生Action实例。objectFactory.buildAction(proxy.getActionName(), proxy.getNamespace(), proxy.getConfig(), contextMap); 这个方法生成proxy.getConfig().getClassName()的实例,并把contextMap inject到其中。 inject的实现没看懂 http://dl.iteye.com/upload/attachment/479248/1ee39aa5-5898-3508-a818-5b4fac28fab2.png createAction(contextMap); //如果需要向stack中推入action实例,则推入。 if (pushAction) { stack.push(action); } //ActionContext其实就是一map,核心就只有Map context;其它就是定义的编译时常量和一个管理各个线程的ActionContext的实例的静态ThreadLocal域。 invocationContext = new ActionContext(contextMap); invocationContext.setName(proxy.getActionName()); // get a new List so we don't get problems with the iterator if someone changes the list List interceptorList = new ArrayList(proxy.getConfig().getInterceptors()); interceptors = interceptorList.iterator(); }
再来看一个这个类的核心invoke()方法:
public String invoke() throws Exception { String profileKey = "invoke: "; try { UtilTimerStack.push(profileKey); if (executed) { throw new IllegalStateException("Action has already executed"); } if (interceptors.hasNext()) { final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next(); UtilTimerStack.profile("interceptor: "+interceptor.getName(), new UtilTimerStack.ProfilingBlock<String>() { public String doProfiling() throws Exception { resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this); return null; } }); } else { //在调用完所有Interceptor之后,调用此。即invokeAction(getAction(), proxy.getConfig());又即method.invoke(action,new Object[0]); 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 (Iterator iterator = preResultListeners.iterator(); iterator.hasNext();) { PreResultListener listener = (PreResultListener) iterator.next(); String _profileKey="preResultListener: "; try { UtilTimerStack.push(_profileKey); listener.beforeResult(this, resultCode); } finally { UtilTimerStack.pop(_profileKey); } } } // now execute the result, if we're supposed to if (proxy.getExecuteResult()) { executeResult(); } executed = true; } return resultCode; } finally { UtilTimerStack.pop(profileKey); } }