关于阅读Struts2部分拦截器源码的记录
Struts2中的拦截器在ActionInvocation对象的invoke()方法中执行。
ActionInvocation对象从配置文件中读取Interceptor对象,加入到自己的存取拦截器的容器中。
在invoke()方法中,当容器中还有Interceptor对象时,就执行对应Interceptor的intercept方法;在intercept方法中,除了加入拦截器自己的部分语句,还会调用同一个ActionInvocation对象的invoke方法,然后invoke方法再执行下一个Interceptor的intercept方法,这样一直来回调用,直到ActionInvocation对象的容器中没有了Interceptor对象,即已经执行完全部的拦截器请求。ActionInvocation类里还有一个Action对象,当容器里的Interceptor的请求都执行完后,才执行Action对象的execute方法。
最后,执行完execute方法后,再执行各个Interceptor对象的intercept方法里的invoke方法后面的语句,即在进行相应的拦截器请求。
部分源码如下:
DefaultActionInvocation:
if (interceptors.hasNext()) { final InterceptorMapping interceptor = interceptors.next(); String interceptorMsg = "interceptor: " + interceptor.getName(); UtilTimerStack.push(interceptorMsg); try { resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this); } finally { UtilTimerStack.pop(interceptorMsg); } } else { resultCode = invokeActionOnly(); }
某个Interceptor :ExceptionMappingInterceptor :
public String intercept(ActionInvocation invocation) throws Exception { String result; try { result = invocation.invoke(); } catch (Exception e) { if (isLogEnabled()) { handleLogging(e); } List<ExceptionMappingConfig> exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings(); ExceptionMappingConfig mappingConfig = this.findMappingFromExceptions(exceptionMappings, e); if (mappingConfig != null && mappingConfig.getResult()!=null) { Map parameterMap = mappingConfig.getParams(); // create a mutable HashMap since some interceptors will remove parameters, and parameterMap is immutable invocation.getInvocationContext().setParameters(new HashMap<String, Object>(parameterMap)); result = mappingConfig.getResult(); publishException(invocation, new ExceptionHolder(e)); } else { throw e; } } return result; }