ActionInvocation实现分析

ActionInvocation是ActionProxy中非常重要的变量。在产生ActionProxy之后,调用proxy.prepare()来产生ActionInvocation的实例。
从ActionInvocation类的说明中,我们可以看到ActionInvocation包括拦截器和Action的实例。
An ActionInvocation represents the execution state of an Action. It holds the [color=red]Interceptors[/color] and the [color=red]Action instance[/color]. 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);
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值