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类。

 

posted @ 2020-10-13 08:19  戴着假发的程序员0-1  阅读(1621)  评论(0编辑  收藏  举报