struts2的灵魂——Interceptor(拦截器)

来源:转载


1.什么是拦截器:
拦截器是动态拦截Action调用的对象。它提供了一种机制使得开发者可以定义action执行之前或之后执行的代码,也可以在一个action执行前将其阻止。

2.AOP:
提到拦截器,我们不得不提到AOP.
AOP(Aspect-Oriented Programming)译为:“面向切面编程”或者“面向方面编程”。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。拦截器的就是实现AOP的一种策略。
下图是拦截器的工作原理简略图:


3.拦截器的作用:
我们可以用Interceptor在Action的方法执行之前或者之后做一些处理,struts的核心功能正是由拦截器来实现的,比如捕获异常、数据校验、安全审查等等。

4.拦截器的工作原理:
Interceptor Stack(拦截器堆)中有顺序的存储着多个Interceptor,他们联接成链状,然后按照添加的顺序,依次调用。这里用到了递归调用,我认为这是设计者的聪明之处。
DefaultActionInvocation类持有拦截器链的引用,以及action的引用,是控制递归调用的重要类。
关于递归更深入的探讨,请猛击:http://candy-code.iteye.com/blog/1443427
下面我们就来模拟一下Interceptor的工作原理
5.Interceptor模拟:

Invocation.java

package com.interceptor.test;import java.util.ArrayList;import java.util.Iterator;import java.util.List;/** * 模拟DefaultActionInvocation *所有的拦截器存放在一个ArrayList中 *该类应当持有拦截器数组的引用和Action的引用 */public class Invocation{private List<Interceptor> interceptors = new ArrayList<Interceptor>();private Iterator<Interceptor> interator;private Action action;/** * 初始化拦截器和action * 用new 模拟 * 实际上Invocation是从struts.xml读取内容,并初始化的 */public Invocation(){ //按顺序加入Interceptorinterceptors.add(new FirstInterceptor());interceptors.add(new SecondInterceptor());interceptors.add(new ThirdInterceptor());interator = interceptors.iterator();action = new Action();}/** * 这是一个递归方法 *方法直接或间接地调用自身即为递归 * invoke()调用intercept(),intercept()又调用invoke() * 实际上就是 第一个拦截器调用第二个拦截,第二个调用第三个,依次类推 */public void invoke(){Interceptor interceptor;//若链表中仍有Interceptor,则调用下一个Interceptorif(interator.hasNext()){interceptor = interator.next();interceptor.intercept(this);}//链表中中没有Interceptor了,则调用Actionelse{action.execute();}}}


Interceptor.java
package com.interceptor.test;//模拟com.opensymphony.xwork2.interceptor.Interceptor接口//所有拦截器都应该实现该接口或者继承自Interceptor的子类public interface Interceptor {//这是拦截器类的最重要的方法//invocation用于存储拦截器链表public void intercept(Invocation invocation);}

FirstInterceptor.java
package com.interceptor.test;//第一个拦截器public class FirstInterceptor implements Interceptor{@Overridepublic void intercept(Invocation invocation) {//向控制输出信息,来模拟action调用前的处理工作System.out.println("first interceptor -->be called");//回调DefaultAcctionInvocation的方法invocation.invoke();//模拟action调用后的处理工作System.out.println("first interceptor -->return");}}

SecondInterceptor.java
package com.interceptor.test;//第二个拦截器public class SecondInterceptor implements Interceptor{@Overridepublic void intercept(Invocation invocation) {System.out.println("Second interceptor -->be called");invocation.invoke();System.out.println("Second interceptor -->return");}}

ThirdInterceptor.java
package com.interceptor.test;//第三个拦截器public class ThirdInterceptor implements Interceptor{@Overridepublic void intercept(Invocation invocation) {System.out.println("Third interceptor -->be called");invocation.invoke();System.out.println("Third interceptor -->return");}}

Main.java
package com.interceptor.test;//用于启动模拟程序//模拟StrutsActionProxy的execute()方法public class Main {// 创建Invocation,并调用其invoke()方法public static void main(String[] args) {new Invocation().invoke();}}

Action.java
package com.interceptor.test;public class Action {public String execute(){System.out.println("Action-->execute");return "success";}}


控制台输出结果为:

first interceptor -->be calledSecond interceptor -->be calledThird interceptor -->be calledAction-->executeThird interceptor -->returnSecond interceptor -->returnfirst interceptor -->return


相信看到输出结果之后,不用过多的解释,你也会对Interceptor的工作原理有更具体的了解了。



分享给朋友:
您可能感兴趣的文章:
随机阅读: