第3小节:自定义TypeFilter指定过滤规则
在配置类上的包扫描注解中添加属性:@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {BookService.class})
@Configuration //告诉spring这是一个配置类
@ComponentScan(value = “com.atguigu”,includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class}),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {BookService.class})
},useDefaultFilters = false)
//FilterType.ANNOTATION:按照注解
//FilterTYpe.ASSIGANBLE_TYPE:按照给定的类型
public class MainConfig {
@Bean(“person”) //给容器中注册一个bean;类型为返回值的类型,id默认是方法名作为id
public Person person01(){
return new Person(“li”,20);
}
测试类不变
测试结果:——只扫描controller,service组件,同时会把雨bookservice有关的组件都扫描
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookController
bookService
person
//FilterType.ASPECTJ:使用ASPECTJ表达式
//Filter.Type.REGEX:使用正则指定过滤规则
//Filter.Type.CUSTOM:使用自定义过滤规则
使用自定义过滤规则:
写一个TypeFilter的实现类:写一个类继承TypeFilter接口,实现里面的match()方法,该方法中有两个参数,一个是:metadataReade,可以用它获取当前正在扫描的类,一个是:metadataReaderFactory,用它可以获取到其他类信息
public class MyTypeFilter implements TypeFilter {
/*
metadataReader:读取到当前正在扫描的类的信息
metadataReaderFactory:可以获取到其他任何类信
*/
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取当前类注解的信息
AnnotationMetadata annotationMetadata=metadataReader.getAnnotationMetadata();
//获取当前正在扫描的类信息
ClassMetadata classMetadata=metadataReader.getClassMetadata();
//获取当前类资源(类路径)
Resource resource= (Resource) metadataReader.getResource();
//打印获取到的类信息:类名
String className=classMetadata.getClassName();
System.out.println("----->"+className);
return false;
}
}
在配置类中的包扫描注解@ComponentScan中使用这个自定义的过滤规则:
@ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})
@Configuration
@ComponentScan(value = “com.atguigu”,includeFilters = {
@ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})
},useDefaultFilters = false)
public class MainConfig {
@Bean(“person”)
public Person person01(){
return new Person(“li”,20);
}
测试类不变
测试结果:
----->com.atguigu.bean.Person
----->com.atguigu.config.MyTypeFilter
----->com.atguigu.controller.BookController
----->com.atguigu.dao.BookDao
----->com.atguigu.service.BookService
----->com.atguigu.test.IOCTest
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
person
指定过滤规则,因为此时Ioc容器中只有这两个组件:mainConfig ,person,,其他的controller,service等没有,因为包扫描使用的自定义规则,而自定义规则返回值是false,也就是一个组件都不匹配
现在在过滤类中指定规则:
if(className.contains(“er”)){
return true;
}
public class MyTypeFilter implements TypeFilter {
/*
metadataReader:读取到当前正在扫描的类的信息
metadataReaderFactory:可以获取到其他任何类信
*/
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取当前类注解的信息
AnnotationMetadata annotationMetadata=metadataReader.getAnnotationMetadata();
//获取当前正在扫描的类信息
ClassMetadata classMetadata=metadataReader.getClassMetadata();
//获取当前类资源(类路径)
Resource resource=metadataReader.getResource();
//打印获取到的类信息:类名
String className=classMetadata.getClassName();
System.out.println("----->"+className);
if(className.contains("er")){
return true;
}
return false;
}
}
测试类不变
测试结果:
----->com.atguigu.MainTest
----->com.atguigu.bean.Person
----->com.atguigu.config.MyTypeFilter
----->com.atguigu.controller.BookController
----->com.atguigu.dao.BookDao
----->com.atguigu.service.BookService
----->com.atguigu.test.IOCTest
五月 29, 2020 12:14:37 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory registerBeanDefinition
信息: Overriding bean definition for bean ‘person’ with a different definition: replacing [Generic bean: class [com.atguigu.bean.Person]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [/Users/zhangxuemei/spring/target/classes/com/atguigu/bean/Person.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=mainConfig; factoryMethodName=person01; initMethodName=null; destroyMethodName=(inferred); defined in com.atguigu.config.MainConfig]
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
person
myTypeFilter
bookController
bookService