targetFilterLifecycle的作用

鬆門一枝花發表於2016-07-08

targetFilterLifecycle的作用,有需要的朋友可以參考下。


在web.xml中進行配置,對所有的URL請求進行過濾,就像"擊鼓傳花"一樣,鏈式處理。


配置分為兩種A和B。

A:普通配置



在web.xml中增加如下內容:

<filter>

<filter-name>permissionFilter</filter-name>

<filter-class>com.taobao.riskm.filter.PermissionFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>permissionFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

由filter和filter-mapping構成。filter指定過濾器處理類(實現了Filter介面),filter-mapping指定過濾的規則。

B:高階配置(允許代理注入Spring bean)



在web.xml中增加如下內容:

<filter>

<filter-name>permission</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

<init-param>

<param-name>targetFilterLifecycle</param-name>

<param-value>true</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>permission</filter-name>

<url-pattern>*.htm</url-pattern>

</filter-mapping>



在spring bean配置中加入:

<bean id="permission" class="com.taobao.kfc.kwb.web.permission.PermissionHttpServlet"></bean>


因為filter比bean先載入,也就是spring會先載入filter指定的類到container中,這樣filter中注入的spring bean就為null了。


解決辦法:

先filter中加入DelegatingFilterProxy類,"targetFilterLifecycle"指明作用於filter的所有生命週期。

原理是,DelegatingFilterProxy類是一個代理類,所有的請求都會首先發到這個filter代理,然後再按照"filter-name"委派到spring中的這個bean。


在Spring中配置的bean的name要和web.xml中的<filter-name>一樣.


此外,spring bean實現了Filter介面,但預設情況下,是由spring容器來管理其生命週期的(不是由tomcat這種伺服器容器來管理)。如果設定"targetFilterLifecycle"為True,則spring來管理Filter.init()和Filter.destroy();若為false,則這兩個方法失效!!


B和A最大的不同是,A是一個filter,優先被載入到container中,無法呼叫spring中後續的bean;而B是一個spring bean,可以引用其他的bean,而請求都通過DelegatingFilterProxy類委派給B!


B的另外一種配置方式:



<filter>

<filter-name>permission</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

<init-param>

<param-name>targetBeanName</param-name>

<param-value>Spring-bean-name</param-value>

</init-param>

</filter>


也就是增加一個"targetBeanName"的引數,值為實際執行Filter的bean。


注意:Filter和servlet都可以對URL進行處理,Filter是一個鏈式處理,只要你想繼續處理就可以傳遞下去;而Servlet則是一次處理並返回!適合簡單邏輯處理。


附錄:

<url-pattern>可以選擇以下幾種形式



/* 所有資源

*.html 以html結尾的資源

/fold/* 指定目錄

/abc.html 指定檔案

以”/’開頭和以”/*”結尾的是用來做路徑對映的,

以字首”*.”開頭的是用來做擴充套件對映的。



為什麼定義”/*.action”這樣一個看起來很正常的匹配會錯?

因為這個匹配即屬於路徑對映,也屬於擴充套件對映,導致容器無法判斷。



此外,filter就像"遞迴",在web.xml配置中的順序代表了filter的呼叫流程,而servlet被呼叫後不會繼續呼叫其他的servlet!因此配置中的順序不影響!