預設情況下,Spring将掃描所有@Component、@Controller、@Service和@Repository标注的類,以及這幾個注解所派生出來的注解所标注的類,如之前介紹的自定義的@MyComponent注解,并将它們作為一個bean定義在對應的bean容器中。Spring提供了兩個filter定義可以讓我們對需要掃描的類進行進一步的過濾,一個是<code><context:include-filter/></code>,一個是<code><context:exclude-filter/></code>。這兩個filter的配置基本是一樣的,所不同的是它們的功能。<code><context:include-filter/></code>對需要掃描的内容進行過濾,即告訴Spring除了按照預設的邏輯進行掃描以外,還需要對哪些内容進行掃描。而<code><context:exclude-filter/></code>則是用來對不需要進行掃描的内容進行過濾,即告訴Spring應該排除對哪些原本應該掃描的内容進行掃描。它們都是作為<code><context:component-scan/></code>的子元素進行定義的,我們可以在一個<code><context:component-scan/></code>标簽下單獨同時定義多個<code><context:include-filter/></code>或者是多個<code><context:exclude-filter/></code>,但是如果在一個<code><context:component-scan/></code>标簽下同時定義<code><context:include-filter/></code>和<code><context:exclude-filter/></code>則需要先定義<code><context:include-filter/></code>,再定義<code><context:exclude-filter/></code>。
在定義<code><context:include-filter/></code>或<code><context:exclude-filter/></code>時我們必須指定type屬性和expression屬性。type屬性表示按照哪種類型進行過濾,expression則表示需要進行過濾的表達式。
對于type屬性而言,我們可選的值有如下五種類型。
annotation:表示注解,根據注解來掃描目标類,即目标類應該使用哪個注解進行了标注,對應的expression應該是注解的全名稱。
assignable:表示是從哪個類或接口派生的,即目标類繼承了哪個類或實作了哪個接口,對應的expression應該是對應接口或類的全名稱。
aspect:表示将使用Aspect類型的表達式來表示目标類。
regex:表示将使用正規表達式來比對目标類名稱。
custom:表示将使用自定義的<code>org.springframework.core.type.TypeFilter</code>來比對對應的類。
如下示例表示我們将排除對使用了@Service注解進行标注的類的掃描,即不将對應的Class加入bean容器中。
這裡再重申一點,那就是使用Spring在掃描時預設是會掃描base-package指定的所有包及其子孫包下所有使用@Component、@Controller、@Service和@Repository及其其它使用這些注解進行标注的注解,使用這些注解進行标注過的Class都會被加入bean容器中。通過<code><context:include-filter/></code>我們可以将其它不在這些範疇的Class加入到bean容器中,通過<code><context:exclude-filter/></code>我們可以将在這個範疇的Class不納入到加入bean容器中的範疇。
是以我們也可以通過<code><context:include-filter/></code>來将對使用了某種類型的注解進行标注的Class加入bean容器中。如下示例,我們将之前介紹的@MyComponent定義成一個普通的注解,然後将其納入到bean容器的範疇即可讓Spring将使用@MyComponent進行标注的Class加入到bean容器中。
assignable表示根據繼承的類或實作的接口進行掃描。如下表示将掃描所有繼承或實作java.lang.Object的類,并将其加入bean容器,通過這種方式我們可以讓Spring将某些包下的所有的類都加入Spring的bean容器。
當指定type為aspect時表示将以Spring定義切面的形式來指定對應的需要進行比對的Class。如下示例則表示比對com.app包及其子孫包下所有名稱以Bean開頭的Class,并将它們加入bean容器。使用該type時需要将spring-aspects-xxx.jar加入類路徑下。
regex表示将采用正規表達式進行比對。如下示例就表示通過正規表達式比對所有的Class的名稱以Bean開始的類,并将它們加入bean容器中(點“.”在正規表達式中代表任意字元)。
custom表示使用自己定義的TypeFilter進行比對。下面來看一個示例,我們來定義一個自己的TypeFilter,其實作簡單的根據Class的名稱進行比對,隻要Class的名稱中包含Bean即表示比對成功。
之後我們在定義filter時就可以通過type指定為custom,然後對應的expression屬性指定我們的自定義TypeFilter即可。
(注:本文是基于Spring4.1.0所寫)