首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

ActionInvocation兑现分析

2012-08-30 
ActionInvocation实现分析ActionInvocation是ActionProxy中非常重要的变量。在产生ActionProxy之后,调用pro

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包括如下的域:

    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);    }    }

热点排行