struts2之Intercepter

1、攔截器簡介
        攔截器,在AOP(Aspect-Oriented Programming)中用於在某個方法或字段被訪問之前,進行攔截然後在之前或之後加入某些操作。攔截是AOP的一種實現策略。 

        攔截器是動態攔截Action調用的對象。它提供了一種機制可以使開發者可以定義在一個action執行的前後執行的代碼,也可以在一個action執行前阻止其執行。同時也是提供了一種可以提取action中可重用的部分的方式。

        攔截器棧(Interceptor Stack)類似於過濾器鏈。攔截器棧就是將攔截器按一定的順序聯結成一條鏈。在訪問被攔截的方法或字段時,攔截器棧的攔截器就會按其之前定義的順序被調用。也可以叫做攔截器鏈(Interceptor Stack),攔截器棧一詞更明確的表名了連接器鏈的實現方式。

2、攔截器的原理
                   
      1)聯繫: 
         Struts2 中的攔截器和 servelt 中的過濾器是非常的相似的。過濾器 public interface Filter 接口裏面有三個方法:
    • init(FilterConfig filterConfig),
    • destroy(),
    • doFilter(ServletRequest request, ServletResponse response, FilterChain chain)。
        而在 com.opensymphony.xwork2.interceptor 中,裏面有個 Interceptor 這是個接口,裏面也有三個方法,有 init,   destroy 和 intercept 三個方法。 struts2 中  String intercept(ActionInvocation invocation)就相當於Filter中的doFilter方法。
        2)原理
                Struts 2的攔截器實現相對簡單。當請求到達Struts2的ServletDispatcher時,Struts 2會查找配置文件,並根據其配置實例化相對的攔截器對象,然後串成一個列表(list),最後一個一個地調用列表中的攔截器。事實上,我們之所以能夠如此 靈活地使用攔截器,完全歸功於“動態代理”的使用。動態代理是代理對象根據客戶的需求做出不同的處理。對於客戶來說,只要知道一個代理對象就行了。
                那Struts2中,攔截器是如何通過動態代理被調用的呢?當Action請求到來的時候,會由系統的代理生成一個Action的代理對象,由 這個代理對象調用Action的execute()或指定的方法,並在struts.xml中查找與該Action對應的攔截器。如果有對應的攔截器,就 在Action的方法執行前(後)調用這些攔截器;如果沒有對應的攔截器則執行Action的方法。其中系統對於攔截器的調用,是通過 ActionInvocation來實現的。代碼如下:
if (intexrceptors.hasNet()) {  
  Interceptor interceptor=(Interceptor)interceptors.next();  
  resultCode = interceptor.intercept(this);  
} else {  
  if (proxy.getConfig().getMethodName() == null) {  
    resultCode = getAction().execute();  
  } else {  
    resultCode = invokeAction(getAction(), proxy.getConfig());  
   }
}  
3、原理的實現模擬過程
1)攔截器接口
    public interface MyInterceptor {  

        public void inteceptor(Invocation invocation) ;  

    } <span style="font-size:18px;"><span style="font-size:12pt">  
</span></span>
2)攔截器兩個實現類
    <span style="font-size:18px;">public class FirstInterceptor implements MyInterceptor {  

        public void inteceptor(Invocation invocation) {  

            System.out.println("第一個攔截器開始。。。。");  

            //調用invoke方法  

            invocation.invoke() ;  

            System.out.println("第一個攔截器結束.......");  

        }  

    } 

    public class SecondInterceptor implements MyInterceptor {  

        public void inteceptor(Invocation invocation) {  

            System.out.println("第二個攔截器開始.....");  

            //調用invoke方法  

            invocation.invoke() ;  

            System.out.println("第二個攔截器結束......");  

        }  

    }<span style="font-size:12pt">  
</span></span>
3)Action
        <span style="font-size:18px;">public class Action {  
            public String execute() {  
                System.out.println("執行execute方法");  
                return null ;  
            }  
        }</span>
4)控制器
        <span style="font-size:18px;">public class Invocation {  

            List<MyInterceptor> interceptors = new ArrayList<MyInterceptor>();  

            int index = -1;  

            public Invocation() {  

                //需要執行的攔截器  

                this.interceptors.add(new FirstInterceptor());  

                this.interceptors.add(new SecondInterceptor());  

            }  

            public void invoke() {  

                index++;  

                if (index < interceptors.size()) {  

                    //一次調用攔截器的inteceptor方法  

                    interceptors.get(index).inteceptor(this);  

                } else {  

                    //攔截器攔截完畢後執行action  

                    new Action().execute();  

                }  

            }  

        }   </span>
5)攔截器入口
      <span style="font-size:18px;">  public static void main(String[] args) {  

            //struts2的攔截器入口就是invoke方法  

            new Invocation().invoke() ;  

        }</span>

發佈了159 篇原創文章 · 獲贊 243 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章