昨天看了會spring web中部分代碼,主要是各種filter,回顧一下:
Spring的web包中中有很多過濾器,這些過濾器位於org.springframework.web.filter並且理所當然地實現了javax.servlet.Filter,不過實現的方式有以下幾類:
(1) 直接實現Filter,這一類過濾器只有CompositeFilter;
(2) 繼承抽象類GenericFilterBean,該類實現了javax.servlet.Filter,這一類的過濾器只有一個,即DelegatingFilterProxy;
(3) 繼承抽象類OncePerRequestFilter,該類為GenericFilterBean的直接子類,這一類過濾器包括CharacterEncodingFilter、HiddenHttpMethodFilter、HttpPutFormContentFilter、RequestContextFilter和ShallowEtagHeaderFilter;
(4) 繼承抽象類AbstractRequestLoggingFilter,該類為OncePerRequestFilter的直接子類,這一類過濾器包括CommonsRequestLoggingFilter、Log4jNestedDiagnosticContextFilter和ServletContextRequestLoggingFilter。
本文要講述的,即是GenericFilterBean、OncePerRequestFilter和AbstractRequestLoggingFilter。
GenericFilterBean
抽象類GenericFilterBean實現了javax.servlet.Filter、org.springframework.beans.factory.BeanNameAware、org.springframework.context.EnvironmentAware、org.springframework.web.context.ServletContextAware、org.springframework.beans.factory.InitializingBean和org.springframework.beans.factory.DisposableBean五個接口,作用如下:
(1) Filter,實現過濾器;
(2) BeanNameAware,實現該接口的setBeanName方法,便於Bean管理器生成Bean;
(3) EnvironmentAware,實現該接口的setEnvironment方法,指明該Bean運行的環境;
(4) ServletContextAware,實現該接口的setServletContextAware方法,指明上下文;
(5) InitializingBean,實現該接口的afterPropertiesSet方法,指明設置屬性生的操作;
(6) DisposableBean,實現該接口的destroy方法,用於回收資源。
GenericFilterBean的工作流程是:init-doFilter-destory,其中的init和destory在該類中實現,doFilter在具體實現類中實現。
GenericFilterBean中包含一個內部私有類FilterConfigPropertyValues,主要用於將web.xml中定義的init-param的值取出。
OncePerRequestFilter
抽象類oncePerRequestFilter繼承自GenericFilterBean,它保留了GenericFilterBean中的所有方法並對之進行了擴展,在oncePerRequestFilter中的主要方法是doFilter。
AbstractRequestLoggingFilter
AbstractRequestLoggingFilter繼承了OncePerRequestFilter並實現了其doFilterInternal方法
我們在使用過濾器時,通常沒必要知道GenericFilterBean、OncePerRequestFilter和AbstractRequestLoggingFilter,但不防礙我們了解這幾個類,就上文所述,
AbstractRequestLoggingFilter繼承自OncePerRequestFilter,
OncePerRequestFilter繼承自GenericFilterBean,
所以我們知道,genericFilterBean是任何類型的過濾器的一個比較方便的超類,
這個類主要實現的就是從web.xml文件中取得init-param中設定的值,然后對Filter進行初始化(當然,其子類可以覆蓋init方法)。
OncePerRequestFilter繼承自GenericFilterBean,那么它自然知道怎么去獲取配置文件中的屬性及其值,所以其重點不在於取值,而在於確保在接收到一個request后,每個filter只執行一次,它的子類只需要關注Filter的具體實現即doFilterInternal。
AbstractRequestLoggingFilter是對OncePerRequestFilter的擴展,它除了遺傳了其父類及祖先類的所有功能外,還在doFilterInternal中決定了在過濾之前和之后執行的事件,它的子類關注的是beforeRequest和afterRequest。
總體來說,這三個類分別執行了Filter的某部分功能,當然,具體如何執行由它們的子類規定,若你需要實現自己的過濾器,也可以根據上文所述繼承你所需要的類。
另外Spring代碼中有不少抽象工具類,內部只有靜態方法,為避免別人誤用它來生成實例,將它設計為抽象類,這是設計者的意圖。
