攔截器,在AOP(Aspect-Oriented Programming)中用於在某個方法或字段被訪問以前,進行攔截而後在以前或以後加入某些操做。攔截是AOP的一種實現策略。
在Webwork的中文文檔的解釋爲——攔截器是動態攔截Action調用的對象。它提供了一種機制可使開發者能夠定義在一個Action執行的先後執行的代碼,也能夠在一個Action執行前阻止其執行。同時也是提供了一種能夠提取Action中可重用的部分的方式。
談到攔截器,還有一個詞你們應該知道——攔截器鏈(Interceptor Chain,在Struts2中稱爲攔截器棧,Interceptor Stack)。攔截器鏈就是將攔截器按必定的順序鏈接成一條鏈。在訪問被攔截的方法或字段時,攔截器鏈中的攔截器就會按其以前定義的順序被調用。
下面是我對於攔截器概念的理解。
咱們知道在Struts2框架裏面有不少的攔截器,在攔截器裏面幫咱們實現了一部分功能。但在Strtus2框架裏面的不少的攔截器,並非都執行,每次只會執行一些默認的攔截器,那這些攔截器是在哪兒呢?Strtus2框架裏面默認攔截器位置的是在struts2-core-2.3.24.jar包下的struts-default.xml文件中,在該文件中,咱們可找到默認攔截器的配置:html
<interceptor-stack name="defaultStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="i18n"/> <interceptor-ref name="prepare"/> <interceptor-ref name="chain"/> <interceptor-ref name="scopedModelDriven"/> <interceptor-ref name="modelDriven"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="datetime"/> <interceptor-ref name="multiselect"/> <interceptor-ref name="staticParams"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"/> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="debugging"/> <interceptor-ref name="deprecation"/> </interceptor-stack>
問題來了,攔截器是在何時執行的呢?在Action對象建立以後,在Action裏面的方法執行以前執行攔截器。編程
大部分時候,攔截器方法都是經過代理的方式來調用的。Struts2的攔截器實現相對簡單。當請求到達Struts2的ServletDispatcher時,Struts2會查找配置文件,並根據其配置實例化相對的攔截器對象,而後串成一個列表,最後一個一個地調用列表中的攔截器。
Struts2的攔截器是可插拔的,攔截器是AOP的一種實現。Struts2攔截器棧就是將攔截器按必定的順序鏈接成一條鏈。在訪問被攔截的方法或字段時,Struts2攔截器鏈中的攔截器就會按其以前定義的順序被調用。
關於對攔截器的底層實現原理,個人理解是——攔截器的底層實現原理主要有兩部分:設計模式
攔截器的執行流程可參考官網提供的圖,以下:
看上面的圖,仍是比較空洞,因此我仍是作一點點解釋。要理解攔截器的執行流程,須理解下面這3點:app
過濾器理論上能夠過濾任意內容,如過濾jsp、過濾html、過濾圖片(路徑)、過濾servlet等。而攔截器是能夠攔截內容,但攔截器只能攔截action。框架