小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

深入理解攔截器原理及攔截器與過(guò)濾器的區(qū)別分析

 liang1234_ 2017-12-13

Struts2攔截器

一、定義理解

1. Struts2攔截器是在訪問(wèn)某個(gè)Action或Action的某個(gè)方法,字段之前或之后實(shí)施攔截,并且Struts2攔截器是可插拔的,攔截器是AOP的一種實(shí)現(xiàn).

2. 攔截器棧(Interceptor Stack)。Struts2攔截器棧就是將攔截器按一定的順序聯(lián)結(jié)成一條鏈。在訪問(wèn)被攔截的方法或字段時(shí),Struts2攔截器鏈中的攔截器就會(huì)按其之前定義的順序被調(diào)用。

二、實(shí)現(xiàn)(Struts2攔截器原理)

Struts2攔截器的實(shí)現(xiàn)原理相對(duì)簡(jiǎn)單,當(dāng)請(qǐng)求到達(dá)Struts 2ServletDispatcher時(shí),Struts 2會(huì)查找配置文件,并根據(jù)其配置實(shí)例化相對(duì)的攔截器對(duì)象,然后串成一個(gè)列表(list),最后一個(gè)一個(gè)地調(diào)用列表中的攔截器。

當(dāng)Action請(qǐng)求到來(lái)的時(shí)候,會(huì)由系統(tǒng)的代理生成一個(gè)Action的代理對(duì)象,由這個(gè)代理對(duì)象調(diào)用Actionexecute()或指定的方法,并在struts.xml中查找與該Action對(duì)應(yīng)的攔截器。如果有對(duì)應(yīng)的攔截器,就在Action的方法執(zhí)行前(后)調(diào)用這些攔截器;如果沒(méi)有對(duì)應(yīng)的攔截器則執(zhí)行Action的方法。其中系統(tǒng)對(duì)于攔截器的調(diào)用,是通過(guò)ActionInvocation來(lái)實(shí)現(xiàn)的

三、深入Struts2攔截器

Struts2規(guī)定用戶自定義攔截器必須實(shí)現(xiàn)com.opensymphony.xwork2.interceptor.Interceptor接口。該接口聲明了3個(gè)方法,

public void init();
public void destroy();
public String intercept(ActionInvocation invocation)

throws Exception;

其中,init和destroy方法會(huì)在程序開(kāi)始和結(jié)束時(shí)各執(zhí)行一遍,不管使用了該攔截器與否,只要在struts.xml中聲明了該Struts2攔截器就會(huì)被執(zhí)行。另外,Interceptor的接口定義沒(méi)有什么特別的地方,除了initdestory方法以外,intercept方法是實(shí)現(xiàn)整個(gè)攔截器機(jī)制的核心方法。而它所依賴的參數(shù)ActionInvocation則是著名的Action調(diào)度者。

不過(guò),struts中又提供了幾個(gè)抽象類,不必單一方式去實(shí)現(xiàn)接口來(lái)定義攔截器,但其實(shí)質(zhì)還是實(shí)現(xiàn)Interceptor接口

public abstract class AbstractInterceptor implements Interceptor;
public abstract class MethodFilterInterceptor 
extends AbstractInterceptor;

其中AbstractInterceptor提供了init()和destroy()的空實(shí)現(xiàn),使用時(shí)只需要覆蓋intercept()方法;

重點(diǎn):在ActionInvocation中,一個(gè)很重要的方法invocation.invoke(),invocation.invoke()這個(gè)方法其實(shí)是整個(gè)攔截器框架的實(shí)現(xiàn)核心;其實(shí)在invocation.invoke()中調(diào)用intercept()的方法中又對(duì)ActionInvocationinvoke()方法進(jìn)行遞歸調(diào)用,ActionInvocation循環(huán)嵌套在intercept()中,一直到語(yǔ)句result = invocation.invoke()執(zhí)行結(jié)束。這樣,Interceptor又會(huì)按照剛開(kāi)始執(zhí)行的逆向順序依次執(zhí)行結(jié)束。一個(gè)有序鏈表,通過(guò)遞歸調(diào)用,變成了一個(gè)堆棧執(zhí)行過(guò)程,將一段有序執(zhí)行的代碼變成了2段執(zhí)行順序完全相反的代碼過(guò)程,從而巧妙地實(shí)現(xiàn)了AOP。這也就成為了Struts2的Action層的AOP基礎(chǔ)。

其中,invocation.invoke()這個(gè)方法具有以下兩層含義:

 1. 如果攔截器堆棧中還有其他的Interceptor,那么invocation.invoke()將調(diào)用堆棧中下一個(gè)Interceptor的執(zhí)行。
     2. 如果攔截器堆棧中只有Action了,那么invocation.invoke()將調(diào)用Action執(zhí)行。

基于此,我們可以得出結(jié)論:

 1. 如果在攔截器中,我們不使用invocation.invoke()來(lái)完成堆棧中下一個(gè)元素的調(diào)用,而是直接返回一個(gè)字符串作為執(zhí)行結(jié)果,那么整個(gè)執(zhí)行將被中止。
     2. 我們可以以invocation.invoke()為界,將攔截器中的代碼分成2個(gè)部分,在invocation.invoke()之前的代碼,將會(huì)在Action之前被依次執(zhí)行,而在invocation.invoke()之后的代碼,將會(huì)在Action之后被逆序執(zhí)行。
由此,我們就可以通過(guò)invocation.invoke()作為Action代碼真正的攔截點(diǎn),從而實(shí)現(xiàn)AOP。

最后,我們分析一下攔截器和過(guò)濾器的區(qū)別:

  (1)攔截器是基于JAVA反射機(jī)制的,而過(guò)濾器是基于函數(shù)回調(diào)的。
      (2)過(guò)濾器依賴于Servlet容器,而攔截器不依賴于Servlet容器
      (3)攔截器只能對(duì)Action請(qǐng)求起作用,而過(guò)濾器可以對(duì)幾乎所有的請(qǐng)求起作用。
      (4)攔截器可以訪問(wèn)Action上下文、值棧里的對(duì)象,而過(guò)濾器不能
      (5)在Action的生命周期中,攔截器可以多次被調(diào)用,而過(guò)濾器只能在容器初始化時(shí)被調(diào)用一次。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多