struts ----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



Java代碼  收藏代碼
  1.     
  2. 1.package com.interceptor.test;    
  3. 2.    
  4. 3.import java.util.ArrayList;    
  5. 4.import java.util.Iterator;    
  6. 5.import java.util.List;    
  7. 6./**  
  8. 7. * 模擬DefaultActionInvocation  
  9. 8. *  所有的攔截器存放在一個ArrayList中  
  10. 9. *  該類應當持有攔截器數組的引用和Action的引用  
  11. 10. */    
  12. 11.public class Invocation{    
  13. 12.    private List<Interceptor> interceptors = new ArrayList<Interceptor>();    
  14. 13.    private Iterator<Interceptor> interator;    
  15. 14.    private Action action;    
  16. 15.    /**  
  17. 16.     * 初始化攔截器和action  
  18. 17.     * 用new 模擬  
  19. 18.     * 實際上Invocation是從struts.xml讀取內容,並初始化的  
  20. 19.     */    
  21. 20.    public Invocation(){    
  22. 21.        //按順序加入Interceptor    
  23. 22.        interceptors.add(new FirstInterceptor());    
  24. 23.        interceptors.add(new SecondInterceptor());    
  25. 24.        interceptors.add(new ThirdInterceptor());    
  26. 25.        interator = interceptors.iterator();    
  27. 26.        action = new Action();    
  28. 27.    }    
  29. 28.    /**  
  30. 29.     * 這是一個遞歸方法  
  31. 30.     * 方法直接或者間接地調用自身即爲遞歸。 
  32. 31.     *invoke()調用intercept(),intercept()又調用invoke()   
  33. 32.     */    
  34. 33.    public void invoke(){    
  35. 34.        Interceptor interceptor;    
  36. 35.        //若鏈表中仍有Interceptor,則調用下一個Interceptor    
  37. 36.        if(interator.hasNext()){    
  38. 37.            interceptor = interator.next();    
  39. 38.            interceptor.intercept(this);    
  40. 39.        }    
  41. 40.        //鏈表中沒有Interceptor了,則調用Action    
  42. 41.        else{    
  43. 42.            action.execute();    
  44. 43.        }    
  45. 44.    }    
  46. 45.}    
  
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
Java代碼  收藏代碼
  1. 1.package com.interceptor.test;    
  2. 2.//模擬com.opensymphony.xwork2.interceptor.Interceptor接口    
  3. 3.//所有攔截器都應該實現該接口或者繼承自Interceptor的子類    
  4. 4.public interface Interceptor {    
  5. 5.    //這是攔截器類的最重要的方法    
  6. 6.    //invocation用於存儲攔截器鏈表    
  7. 7.    public void intercept(Invocation invocation);    
  8. 8.}    
  9.    
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
Java代碼  收藏代碼
  1.     
  2. 1.package com.interceptor.test;    
  3. 2.//第一個攔截器    
  4. 3.public class FirstInterceptor implements Interceptor{    
  5. 4.    @Override    
  6. 5.    public void intercept(Invocation invocation) {    
  7. 6.        //向控制輸出信息,來模擬action調用前的處理工作    
  8. 7.        System.out.println("first interceptor -->be called");    
  9. 8.        //回調DefaultAcctionInvocation的方法    
  10. 9.        invocation.invoke();    
  11. 10.        //模擬action調用後的處理工作    
  12. 11.        System.out.println("first interceptor -->return");    
  13. 12.    }    
  14. 13.}    
  15.    
  
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
Java代碼  收藏代碼
  1.    
  2. 1.package com.interceptor.test;    
  3. 2.//第二個攔截器    
  4. 3.public class SecondInterceptor implements Interceptor{    
  5. 4.    @Override    
  6. 5.    public void intercept(Invocation invocation) {    
  7. 6.        System.out.println("Second interceptor -->be called");    
  8. 7.        invocation.invoke();    
  9. 8.        System.out.println("Second interceptor -->return");    
  10. 9.    }    
  11. 10.}    
  12.    
 
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
Java代碼  收藏代碼
  1.    
  2. 1.package com.interceptor.test;    
  3. 2.//第三個攔截器    
  4. 3.public class ThirdInterceptor implements Interceptor{    
  5. 4.    @Override    
  6. 5.    public void intercept(Invocation invocation) {    
  7. 6.        System.out.println("Third interceptor -->be called");    
  8. 7.        invocation.invoke();    
  9. 8.        System.out.println("Third interceptor -->return");    
  10. 9.    }    
  11. 10.}    
  12.    
 
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
Java代碼  收藏代碼
  1. package com.interceptor.test;  
  2.   
  3. public class Action {  
  4.     public String execute(){  
  5.         System.out.println("Action-->execute");  
  6.         return "success";  
  7.     }  
  8. }  
package com.interceptor.test;

public class Action {
	public String execute(){
		System.out.println("Action-->execute");
		return "success";
	}
}

Main.java
Java代碼  收藏代碼
  1. 1.package com.interceptor.test;    
  2. 2.//用於啓動模擬程序    
  3. 3.//模擬StrutsActionProxy的execute()方法    
  4. 4.public class Main {    
  5. 5.    // 創建Invocation,並調用其invoke()方法    
  6. 6.    public static void main(String[] args) {    
  7. 7.        new Invocation().invoke();    
  8. 8.    }    
  9. 9.}    
  10.    
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.}  
 


控制檯輸出結果爲:
Java代碼  收藏代碼
  1.    
  2. 1.first interceptor -->be called    
  3. 2.Second interceptor -->be called    
  4. 3.Third interceptor -->be called    
  5. 4.Action-->execute    
  6. 5.Third interceptor -->return    
  7. 6.Second interceptor -->return    
  8. 7.first interceptor -->return    
  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的工作原理有更具體的瞭解了。

補充:本文中之所以只談遞歸,不談模式,是爲了讓讀者更深刻更具象的瞭解底層原理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章