Struts2中有三大核心:ognl,拦截器和action;想要学好Struts2,这三个核心是重中之重;这里就给大家介绍一下Struts2拦截器的工作原理
。
什么是拦截器
拦截器是在请求到达Action前后进行的一系列操作,Struts2默认自带了很大拦截器,这些拦截器定义在struts-default.xml中。Struts2中的拦截器是基于AOP动态代理思想的。关于Struts的结构,有一张很经典的图:
在这张图上可以清楚的看到请求经过了Action代理,然后通过了一系列Interceptor最终返回,下面我们就来了解一下,图中的Interceptor1,2,3是如何工作的。
拦截器的工作原理
在搭建Struts2框架时,我们首先需要在web.xml中配置StrutsPrepareAndExecuteFilter过滤器,这是因为请求会首先经过这个过滤器,然后会经过很多层,最后依次经过每一个拦截器(包括自定义的拦截器)。具体经过了哪些层,可以看下面这张图:
从这张图可以看到每一层的包含关系,重点看一下最里面的两层,红色箭头和黄色箭头的部分,这两个方法是一个递归调用的过程,也就是说,当在invoke()方法中调用一个拦截器时,拦截器中会有invocation.invoke()这一句,这一句表明会跳出当前拦截器,回到上一级,调用下一个拦截器,当所有的拦截器都调用了并且action执行完毕后,会递归回调拦截器中没有执行完毕的内容。那么invoke()方法中是如何调用下一个拦截器的呢?看看源码就明白了(最核心的代码):
if (interceptors.hasNext()) {
final InterceptorMapping interceptorMapping = interceptors.next();
String interceptorMsg = "interceptorMapping: " + interceptorMapping.getName();
UtilTimerStack.push(interceptorMsg);
try {
Interceptor interceptor = interceptorMapping.getInterceptor();
if (interceptor instanceof WithLazyParams) {
interceptor = lazyParamInjector.injectParams(interceptor, interceptorMapping.getParams(), invocationContext);
}
resultCode = interceptor.intercept(DefaultActionInvocation.this);
} finally {
UtilTimerStack.pop(interceptorMsg);
}
} else {
resultCode = invokeActionOnly();
}
关于递归的过程,我自己画了一个示意图:
看完上面的解释,这时候再回去看一开始的struts框架结构图的interceptor1,2,3,应该可以很容易理解了。
以上就是我对拦截器的执行的理解,希望能够帮助到大家!