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

Xwork2 源码翻阅(三)

2012-11-05 
Xwork2 源码阅读(三)接着看Dispatcher ?ActionProxy proxy config.getContainer().getInstance(ActionPr

Xwork2 源码阅读(三)

接着看Dispatcher

?

           ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(                    namespace, name, extraContext, true, false);

?

用Container 构造一个 ActionProxyFactory,在用ActionProxyFactory create一个 ActionProxy。

?

    public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map extraContext, boolean executeResult, boolean cleanupContext) {                ActionInvocation inv = new DefaultActionInvocation(extraContext, true);        container.inject(inv);        return createActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext);    }

?

?

xwork中,action的调用是借助 Proxy 模式,

Proxy 模式的实现,则是 DefaultActionProxy, Action, ActionInvocation 合伙完成的。

下边是一些关键代码

?

DefaultActionProxy

?

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

?

?

?DefaultActionInvocation 得 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 {    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);    }    }

?

resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);
是判断这个action是否有未被执行的拦截器,

?

resultCode = invokeActionOnly();

如没有或拦截器执行完毕,则执行invokeActionOnly

?

?invokeActionOnly方法

?

    public String invokeActionOnly() throws Exception {    return invokeAction(getAction(), proxy.getConfig());    }   protected String invokeAction(Object action, ActionConfig actionConfig) throws Exception {        String methodName = proxy.getMethod();        if (LOG.isDebugEnabled()) {            LOG.debug("Executing action method = " + actionConfig.getMethodName());        }        String timerKey = "invokeAction: "+proxy.getActionName();        try {            UtilTimerStack.push(timerKey);                        boolean methodCalled = false;            Object methodResult = null;            Method method = null;            try {                method = getAction().getClass().getMethod(methodName, new Class[0]);            } catch (NoSuchMethodException e) {                // hmm -- OK, try doXxx instead                try {                    String altMethodName = "do" + methodName.substring(0, 1).toUpperCase() + methodName.substring(1);                    method = getAction().getClass().getMethod(altMethodName, new Class[0]);                } catch (NoSuchMethodException e1) {                // well, give the unknown handler a shot                if (unknownHandler != null) {                try {                methodResult = unknownHandler.handleUnknownActionMethod(action, methodName);                methodCalled = true;                } catch (NoSuchMethodException e2) {                // throw the original one                throw e;                }                } else {            throw e;            }                }            }                if (!methodCalled) {        methodResult = method.invoke(action, new Object[0]);        }                    if (methodResult instanceof Result) {            this.explicitResult = (Result) methodResult;            return null;            } else {            return (String) methodResult;            }        } catch (NoSuchMethodException e) {            throw new IllegalArgumentException("The " + methodName + "() is not defined in action " + getAction().getClass() + "");        } catch (InvocationTargetException e) {            // We try to return the source exception.            Throwable t = e.getTargetException();            if (actionEventListener != null) {                String result = actionEventListener.handleException(t, getStack());                if (result != null) {                    return result;                }            }            if (t instanceof Exception) {                throw(Exception) t;            } else {                throw e;            }        } finally {            UtilTimerStack.pop(timerKey);        }    }

?

method = getAction().getClass().getMethod(methodName, new Class[0]);
取出需执行的action的方法,如 execute()

?

methodResult = method.invoke(action, new Object[0]);
利用反射,执行action 方法

?

上边就是利用proxy模式,调用一个action的具体逻辑 的 过程。

?

一般的action里,都有一些变量,如从request中取出的参数等,

如要执行action 方法,如execute(),则必须先吧这些变量赋值 已供方法中使用,

这个工作,就是 拦截器(Interceptor) 的任务之一,

?

下篇探讨一下拦截器。

?

热点排行