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

Xwork2 源码阅览(四)

2012-11-07 
Xwork2 源码阅读(四)xwork2 的Inteceptor,是实现AOP的,我理解的Aop,就是把代码拆开,分成一块一块的。然后在

Xwork2 源码阅读(四)

xwork2 的Inteceptor,是实现AOP的,我理解的Aop,就是把代码拆开,分成一块一块的。

然后在根据需要组装起来, 而Interceptor 就是代码分块后的一块。?

?

我们看一下xwork的具体实现步骤,

?

1 先是在xwork 配置文件中,配置action有哪些Interceptor ,

2 然后在xwork 初始化的时候,把action 的Interceptor 记录下来,

?

public class ActionConfig extends Located implements Serializable {    public static final String WILDCARD = "*";    protected List<InterceptorMapping> interceptors;    protected Map<String, String> params;    protected Map<String, ResultConfig> results;    protected List<ExceptionMappingConfig> exceptionMappings;    protected String className;    protected String methodName;    protected String packageName;    protected String name;    protected Set<String> allowedMethods;

?

?interceptors这个参数,记录的就是action配置的interceptor,

3 ?执行action的主体逻辑之前,先把interceptors 取出来,顺次执行一遍。

?

看一下xwork 是如何实现的,

主要是这三各类 :

DefaultActionInvocation, Action, Interceptor

Action 是我们自己写的,里边有我们要执行的主体逻辑,

Interceptor 则是主体逻辑之外的代码块,如打日志,

?

DefaultActionInvocation 则居中调度,

Action 在他里边,interceptor 由他通过ActionConfig 找到,

这样他就可以把Action和多个Interceptor粘合起来,

?

先看下?DefaultActionInvocation

?

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

这个主干方法,

先判断是否有 interceptor,

????? if (interceptors.hasNext()) {


如有,则执行interceptor

??? resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);

?

调用方法时,参数是 DefaultActionInvocation.this,

说明DefaultActionInvocation把自己本身做参数 传给了interceptor,

然后interceptor就有了DefaultActionInvocation的引用,就可以方便的和DefaultActionInvocation进行互通了。

?

看一个具体的 Interceptor,

    public String doIntercept(ActionInvocation invocation) throws Exception {        Object action = invocation.getAction();        if (!(action instanceof NoParameters)) {            ActionContext ac = invocation.getInvocationContext();            final Map parameters = retrieveParametersFromContext(ac);            if (LOG.isDebugEnabled()) {                LOG.debug("Setting params " + getParameterLogMap(parameters));            }            if (parameters != null) {            Map contextMap = ac.getContextMap();                try {                ReflectionContextState.setCreatingNullObjects(contextMap, true);                ReflectionContextState.setDenyMethodExecution(contextMap, true);                ReflectionContextState.setReportingConversionErrors(contextMap, true);                    ValueStack stack = ac.getValueStack();                    setParameters(action, stack, parameters);                } finally {                ReflectionContextState.setCreatingNullObjects(contextMap, false);                ReflectionContextState.setDenyMethodExecution(contextMap, false);                ReflectionContextState.setReportingConversionErrors(contextMap, false);                }            }        }        return invocation.invoke();    }

?具体执行逻辑不用看,只看第一句和最后一句,

Object action = invocation.getAction();

找到action,

return invocation.invoke();
Interceptor执行完本身的逻辑,就把程序的执行权还给ActionInvocation,

而后回到ActionInvocation 的invoke() 方法,

判断是否有后续的Interceptor,重复上述过程,

直到action的所有Interceptor都执行完。

?

当action的所有Interceptor都执行完,就到了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的主体方法,

?methodResult = method.invoke(action, new Object[0]);

执行方法,返回methodResult ,

?

到了这,一个action的Interceptor,已及主体逻辑,就基本执行完了。

?

?

?

?

?

?

?

?

?

?

?

热点排行