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
Interceptor.java
FirstInterceptor.java
SecondInterceptor.java
ThirdInterceptor.java
Action.java
Main.java
控制台输出结果为:
相信看到输出结果之后,不用过多的解释,你也会对Interceptor的工作原理有更具体的了解了。
补充:本文中之所以只谈递归,不谈模式,是为了让读者更深刻更具象的了解底层原理。
拦截器是动态拦截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
- 1.package com.interceptor.test;
- 2.
- 3.import java.util.ArrayList;
- 4.import java.util.Iterator;
- 5.import java.util.List;
- 6./**
- 7. * 模拟DefaultActionInvocation
- 8. * 所有的拦截器存放在一个ArrayList中
- 9. * 该类应当持有拦截器数组的引用和Action的引用
- 10. */
- 11.public class Invocation{
- 12. private List<Interceptor> interceptors = new ArrayList<Interceptor>();
- 13. private Iterator<Interceptor> interator;
- 14. private Action action;
- 15. /**
- 16. * 初始化拦截器和action
- 17. * 用new 模拟
- 18. * 实际上Invocation是从struts.xml读取内容,并初始化的
- 19. */
- 20. public Invocation(){
- 21. //按顺序加入Interceptor
- 22. interceptors.add(new FirstInterceptor());
- 23. interceptors.add(new SecondInterceptor());
- 24. interceptors.add(new ThirdInterceptor());
- 25. interator = interceptors.iterator();
- 26. action = new Action();
- 27. }
- 28. /**
- 29. * 这是一个递归方法
- 30. * 方法直接或者间接地调用自身即为递归。
- 31. *invoke()调用intercept(),intercept()又调用invoke()
- 32. */
- 33. public void invoke(){
- 34. Interceptor interceptor;
- 35. //若链表中仍有Interceptor,则调用下一个Interceptor
- 36. if(interator.hasNext()){
- 37. interceptor = interator.next();
- 38. interceptor.intercept(this);
- 39. }
- 40. //链表中没有Interceptor了,则调用Action
- 41. else{
- 42. action.execute();
- 43. }
- 44. }
- 45.}
Interceptor.java
- 1.package com.interceptor.test;
- 2.//模拟com.opensymphony.xwork2.interceptor.Interceptor接口
- 3.//所有拦截器都应该实现该接口或者继承自Interceptor的子类
- 4.public interface Interceptor {
- 5. //这是拦截器类的最重要的方法
- 6. //invocation用于存储拦截器链表
- 7. public void intercept(Invocation invocation);
- 8.}
FirstInterceptor.java
- 1.package com.interceptor.test;
- 2.//第一个拦截器
- 3.public class FirstInterceptor implements Interceptor{
- 4. @Override
- 5. public void intercept(Invocation invocation) {
- 6. //向控制输出信息,来模拟action调用前的处理工作
- 7. System.out.println("first interceptor -->be called");
- 8. //回调DefaultAcctionInvocation的方法
- 9. invocation.invoke();
- 10. //模拟action调用后的处理工作
- 11. System.out.println("first interceptor -->return");
- 12. }
- 13.}
SecondInterceptor.java
- 1.package com.interceptor.test;
- 2.//第二个拦截器
- 3.public class SecondInterceptor implements Interceptor{
- 4. @Override
- 5. public void intercept(Invocation invocation) {
- 6. System.out.println("Second interceptor -->be called");
- 7. invocation.invoke();
- 8. System.out.println("Second interceptor -->return");
- 9. }
- 10.}
ThirdInterceptor.java
- 1.package com.interceptor.test;
- 2.//第三个拦截器
- 3.public class ThirdInterceptor implements Interceptor{
- 4. @Override
- 5. public void intercept(Invocation invocation) {
- 6. System.out.println("Third interceptor -->be called");
- 7. invocation.invoke();
- 8. System.out.println("Third interceptor -->return");
- 9. }
- 10.}
Action.java
- package com.interceptor.test;
- public class Action {
- public String execute(){
- System.out.println("Action-->execute");
- return "success";
- }
- }
Main.java
- 1.package com.interceptor.test;
- 2.//用于启动模拟程序
- 3.//模拟StrutsActionProxy的execute()方法
- 4.public class Main {
- 5. // 创建Invocation,并调用其invoke()方法
- 6. public static void main(String[] args) {
- 7. new Invocation().invoke();
- 8. }
- 9.}
控制台输出结果为:
- 1.first interceptor -->be called
- 2.Second interceptor -->be called
- 3.Third interceptor -->be called
- 4.Action-->execute
- 5.Third interceptor -->return
- 6.Second interceptor -->return
- 7.first interceptor -->return
相信看到输出结果之后,不用过多的解释,你也会对Interceptor的工作原理有更具体的了解了。
补充:本文中之所以只谈递归,不谈模式,是为了让读者更深刻更具象的了解底层原理。