什么是struts2拦截器?
软件架构上来说,拦击器是实现了面向方面编程(AOP)的组件。它将影响了多个业务对象的公共行为封装到一个个可重用的模块,减少了系统的重复代码,实现功能的高度内聚,确保了业务对象的整洁和纯度。
为什么要使用拦截器?
拦截器消除了动作组件中的横切任务(cross-cutting task )。例如,日志是一个典型的横切关注。以前,我们可能需要为每个动作组件准备一些记录日志的代码。虽然这样看上去也没什么错误,但是一个不可忽视的事实是,这些用于记录日志的代码并不是动作组件与模型交互的一部分。并且,日志记录是我们想为系统处理的每一个请求完成的管理性任务,他不是动作组件所特有的,而是贯穿了所有的动作组件。struts2将这个功能放在了更高的层次上,我们可以把日志记录的代码一道动作组件之外,从而让动作组件更加清晰。
拦截器组件提供了一个不错的场所,来讲不同的横切关注点逻辑分成有层次的,可重用的部件。
拦截器的工作原理
当框架接收到一个请求的时候,它首先必须决定这个url映射到哪个动作组件。这个动作组件的一个实例就会被加入到一个新创建的ActionInvocation实例中。接着框架咨询声明性架构(xml配置或java注解),以发现哪一些拦截器应该被触发,以及按照什么样的顺序触发。将这些拦截器的引用添加到ActionInvocation中。消除了这些核心元素,ActionInvocation也拥有其他的重要的信息(请求对象和当前动作组件和可用的结果组件列表)。
当ActionInvocation被创建完毕,并且填充了所有需要的对象和信息,就可以被使用了。ActionInvocation公开了一个invoke()方法,框架通过调用这个方法开始动作的执行。当框架调用了这个这个方法时,ActionInvocation通过执行拦截器栈中的第一个拦截器开始这个调用过程。需要注意的是,invoke()方法并不是总是指向拦截器栈的第一个拦截器,ActionInvocation负责跟踪执行过程到达的状态,并把控制交给栈中合适的拦截器(通过调用拦截器中的intercept()方法,将控制权交给拦截器)。通过递归调用ActionInvocation的invoke()方法,拦截器栈中后续的拦截器继续执行,最终执行动作。这是因为每一次invoke()方法被调用时,ActionInvocation都会查询自身的状态,调用接下来的拦截器。在所有拦截器都被调用之后,invoke()方法会促使动作类执行。
拦截器例子:
aciton:
拦截器:
struts.xml配置:
从上图可以看到拦截器的进入顺序和出拦截器顺序
从上面图可以看出,拦截器销毁的顺序不定