2.31@ComponentScan注解的includeFilters屬性


戴着假發的程序員出品  抖音ID:戴着假發的程序員  歡迎關注

[查看視頻教程]

這里的includeFilters和context:include-filter標簽的作用完全一致。

我們已經知道ComponentScan的配置可以通知spring掃描擁有spring標准注解的類。這些標注大致是:@Component、@Controller、@Service、@Repository。但是我們也可以通過includeFilters屬性配置通知spring掃描一些沒有標准注解但是我們希望spring幫我們管理的類。

includeFilters的值是一個數組,可以配置多個,includeFilters中配置的是一個Filter類型的注解。Filter的源碼如下:

 1 @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
 2 @java.lang.annotation.Target({})
 3 static @interface Filter {
 4     org.springframework.context.annotation.FilterType type() default org.springframework.context.annotation.FilterType.ANNOTATION;
 5 
 6     @org.springframework.core.annotation.AliasFor("classes")
 7     java.lang.Class<?>[] value() default {};
 8 
 9     @org.springframework.core.annotation.AliasFor("value")
10     java.lang.Class<?>[] classes() default {};
11 
12     java.lang.String[] pattern() default {};
13 }

Filter中有4個屬性,分別是

type:用來配置Filter的類型,這個類型是一個枚舉,這個類型一共有五種,下面再詳細解釋。

value:根據type的不同,這個表達式的配置方式也不同。

classes:當我們的type為ANNOTATION或者ASSIGNABLE_TYPE時,我們可以將對應的類配置在value屬性中也可以配置在calsses屬性中

pattern:當我們的type是REGEX時,我們可以將表達式配置的pattern中。

 

type屬性的五個值:

ANNOTATION:-指定掃描使用某個注解的類

ASSIGNABLE_TYPE:指定掃描某個接口派生出來的類

ASPECTJ:指定掃描AspectJ表達式相匹配的類

REGEX:指定掃描符合正則表達式的類

CUSTOM:指定掃描自定義的實現了org.springframework.core.type.filter.TypeFilter接口的類

 

就這個五個類型,我准備五個案例看看

[1]ANNOTATION:-指定掃描使用某個注解的類,將其加載進spring的容器。

我們准備如下的類目錄結構:

其中Person類實現:

Person有Spring的標准注解@Component.

 1 /**
 2  * @author 戴着假發的程序員
 3  *  
 4  * @description
 5  */
 6 @Component//Person類交給spring管理
 7 public class Person{
 8     public Person(){
 9         System.out.println("實例化Person類");
10     }
11 }

Dog類的實現:

Dog類並沒有Spring的標准注解,添加添加了我們自定義的注解:

 1 /**
 2  * @author 戴着假發的程序員
 3  *  
 4  * @description
 5  */
 6 @DkAnnotation
 7 public class Dog {
 8     public Dog(){
 9         System.out.println("實例化Dog類");
10     }
11 }

我們自定的注解@DkAnnotation

1 /**
2  * @author 戴着假發的程序員
3  *  
4  * @description
5  */
6 public @interface DkAnnotation {
7 }

添加一個配置類:

配置類中給ComponentScan添加屬性excludeFilters,類型為ANNOTATION,value為DkAnnotation.class。當然也可以使用classes代替value,注意value和classes都是數組,可以同時配置多個。

 1 /**
 2  * @author 戴着假發的程序員
 3  *  
 4  * @description
 5  */
 6 @Configuration()
 7 @ComponentScan(
 8         basePackages = "com. st.dk.demo6.beans",
 9         includeFilters = {@ComponentScan.Filter(type= FilterType.ANNOTATION,value= DkAnnotation.class)}
10 )
11 public class AppConfig {
12 }

測試:

1 @Test
2 public void testIncludeFilters(){
3     ApplicationContext ac =
4             new AnnotationConfigApplicationContext(AppConfig.class);
5 }

結果:

我們會發現spring會將有標注注解的Person類和我們有我們自定義注解的Dog都加載。

[2]ASSIGNABLE_TYPE:指定掃描某個接口派生出來的類

案例:

我們修改上面的案例,添加一個接口Info。

1 /**
2  * @author 戴着假發的程序員
3  *  
4  * @description
5  */
6 public interface Info {
7 }
java

修改Dog類,刪除Dog類上方的注解,但是讓Dog類實現接口Info。

 1 /**
 2  * @author 戴着假發的程序員
 3  *  
 4  * @description
 5  */
 6 public class Dog implements Info {
 7     public Dog(){
 8         System.out.println("實例化Dog類");
 9     }
10 }

修改配置類,修改type屬性為ASSIGNABLE_TYPE,value或者classes屬性配置為Info .class。表示實現了Info接口的類要求spring加載。

 1 /**
 2  * @author 戴着假發的程序員
 3  *  
 4  * @description
 5  */
 6 @Configuration()
 7 @ComponentScan(
 8         basePackages = "com. st.dk.demo6.beans",
 9         includeFilters = {@ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE,value={Info.class})}
10 )
11 public class AppConfig {
12 }

再測試,我們會發現spring依然會加載Dog類。

[3]ASPECTJ:指定掃描AspectJ表達式相匹配的類,比如要求加載某個類的派生類

案例:

我們添加一個Animal類:

1 /**
2  * @author 戴着假發的程序員
3  *  
4  * @description
5  */
6 public class Animal {
7 }

修改Dog,繼承Animal。

 1 /**
 2  * @author 戴着假發的程序員
 3  *  
 4  * @description
 5  */
 6 public class Dog extends Animal {
 7     public Dog(){
 8         System.out.println("實例化Dog類");
 9     }
10 }

修改配置類,type配置為ASPECTJ,這里注意去掉value或者calsses屬性,添加pattern屬性,值為:com. st.dk.demo6.beans.Animal+

 1 /**
 2  * @author 戴着假發的程序員
 3  *  
 4  * @description
 5  */
 6 @Configuration()
 7 @ComponentScan(
 8         basePackages = "com. st.dk.demo6.beans",
 9         includeFilters = {@ComponentScan.Filter(type= FilterType.ASPECTJ,pattern = "com. st.dk.demo6.beans.Animal+")}
10 )
11 public class AppConfig {
12 }

再測試,我們會發現spring依然會加載Dog類。

[4]REGEX:指定掃描符合正則表達式的類

我們可以通過REGEX配置一個正則表達式,spring會根據正則匹配加載對應的類。

案例:我們修改Dog類,不實現接口,不繼承其他類,沒有注解。

 1 /**
 2  * @author 戴着假發的程序員
 3  *  
 4  * @description
 5  */
 6 public class Dog{
 7     public Dog(){
 8         System.out.println("實例化Dog類");
 9     }
10 }

修改配置類,type修改為REGEX,pattern修改為:“.*.*og”,表示加載og結尾的類。

 1 /**
 2  * @author 戴着假發的程序員
 3  *  
 4  * @description
 5  */
 6 @Configuration()
 7 @ComponentScan(
 8         basePackages = "com. st.dk.demo6.beans",
 9         includeFilters = {@ComponentScan.Filter(type= FilterType.REGEX,pattern = ".*.*og")}
10 )
11 public class AppConfig {
12 }

再測試,我們會發現spring依然會加載Dog類。

[5]CUSTOM:指定掃描自定義的實現了org.springframework.core.type.filter.TypeFilter接口的類

CUSTOM允許我們自定義加載策略,我們可以自己實現一個TypeFilter,實現自己的加載策略。

案例:我們自己實現一個Filter,用來加載Dog類。添加一個自己的類實現接口TypeFilter

 1 /**
 2  * @author 戴着假發的程序員
 3  *  
 4  * @description
 5  */
 6 public class DkFilter  implements TypeFilter {
 7     //關於metadataReader和metadataReaderFactory可以關注spring源碼解讀部分
 8     @Override
 9     public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
10         //獲取當前正在掃描的類的類名
11         String className = metadataReader.getClassMetadata().getClassName();
12         //判斷是不是Dog的class
13         if(className.equals(Dog.class.getName())){
14             //返回true表示讓spring加載當前的類.
15             return true;
16         }
17         //返回false表示不讓spring加載當前類
18         return false;
19     }
20 }

修改配置類,type修改為CUSTOM,value或者classes中配置DkFilter.class

 1 /**
 2  * @author 戴着假發的程序員
 3  *  
 4  * @description
 5  */
 6 @Configuration()
 7 @ComponentScan(
 8         basePackages = "com. st.dk.demo6.beans",
 9         includeFilters = {@ComponentScan.Filter(type= FilterType.CUSTOM,value = DkFilter.cl
10         )}
11 )
12 public class AppConfig {
13 }

再測試,我們會發現spring依然會加載Dog類。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM