深入解析Struts拦截器的工作原理

Struts2中有三大核心:ognl,拦截器和action;想要学好Struts2,这三个核心是重中之重;这里就给大家介绍一下Struts2拦截器的工作原理

什么是拦截器

拦截器是在请求到达Action前后进行的一系列操作,Struts2默认自带了很大拦截器,这些拦截器定义在struts-default.xml中。Struts2中的拦截器是基于AOP动态代理思想的。关于Struts的结构,有一张很经典的图:

strtus结构

在这张图上可以清楚的看到请求经过了Action代理,然后通过了一系列Interceptor最终返回,下面我们就来了解一下,图中的Interceptor1,2,3是如何工作的。

拦截器的工作原理

在搭建Struts2框架时,我们首先需要在web.xml中配置StrutsPrepareAndExecuteFilter过滤器,这是因为请求会首先经过这个过滤器,然后会经过很多层,最后依次经过每一个拦截器(包括自定义的拦截器)。具体经过了哪些层,可以看下面这张图:

struts2请求的流程

从这张图可以看到每一层的包含关系,重点看一下最里面的两层,红色箭头和黄色箭头的部分,这两个方法是一个递归调用的过程,也就是说,当在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();
            }

关于递归的过程,我自己画了一个示意图:

struts2拦截器递归执行

看完上面的解释,这时候再回去看一开始的struts框架结构图的interceptor1,2,3,应该可以很容易理解了。
以上就是我对拦截器的执行的理解,希望能够帮助到大家!

猜你喜欢

转载自blog.csdn.net/tianc_pig/article/details/84543387