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,已及主体逻辑,就基本执行完了。