@ComponentScan、@Configurable、@TypeFilter
- @Configurable来标注该类为Spring中的配置类,@ComponentScan(“model”)是为该配置类指定要去扫描的参数。
- @TypeFilter注解
是通过设置条件来过滤一些资源,我们可以过滤一些资源不让它加载到ioc容器中。它的使用要在@ComponentScan这个注解中国去使用,通过excludeFilters参数传值,excludeFilters是一个数组,可以设定多个@TypeFilter。
/**
* @Configurable: 该注解是标注该类是配置类
* @ComponentScan:配置要扫描的包
* @TypeFilter 过滤一些资源,不让它加载到ioc容器中
* @author caohu
*/
@Configurable
@ComponentScan(value = "model", ,excludeFilters = {
// FilterType.ANNOTATION是通过注解的形式进行过滤
@Filter(type = FilterType.ANNOTATION,classes = {Controller.class}),
// FilterType.ASSIGNABLE_TYPE 是通过给定的类型
@Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {Product.class}),
// FilterType.ASPECTJ 根据正则表达式
@Filter(type = FilterType.ASPECTJ,classes = {""}),
// FilterType.CUSTOM 使用自定义规则(自定义实现TypeFilter)
@Filter(type = FilterType.CUSTOM,classes = {TypeFilterImp.class})
})
public class MainConfig {
}
//自定义实现TypeFilter
public class TypeFilterImp implement TypeFilter {
/**
* MetadataReader: 读取到的当前正在扫描的信息
* MetadataReaderFactory:可以获取到其他任何类的信息
*/
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
// 获取当前类注解的信息
AnnotationMetadata mr = metadataReader.getAnnotationMetadata();
// 获取当前正在扫描的类的信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
// 获取当前类的资源信息
Resource resource = metadataReader.getResource();
// 获取当前类的名字
String className = classMetadata.getClassName();
System.out.println("----"+className);
// contains包含“er”
if(className.contains("er")) {
return true;
}
return false;
}
}
@Conditional
- @Conditional注解是根据制定条件来进行注册,需要我创建配置条件的配置类,如果条件满足就进行注册,不满足就不去注册。
@Configurable
public class MainConfig {
/**
* 根据TestCondition的返回值确定是否创建这个Bean
*/
@Conditional({TestCondition.class})
@Bean
public Product wind() {
return new Product("张三","wind",1);
}
}
//自定义实现
public class TestCondition implements Condition{
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata arg1) {
Environment environment = context.getEnvironment();
// 获取当前操作系统的名字
String property = environment.getProperty("os.name");
if(property.contains("Windows")) {
return true;
}
return false;
}
}
@import
- @Import只能用在类上 ,@Import通过快速导入的方式实现把实例加入spring的IOC容器中
- 第一种用法:直接填class数组
//XX1和XX2会变成配置类,直接进入容器
@Import({ com.ch.XX1.class, com.ch.XX2.class})
public class TestDemo {
}
- ImportSelector方式
//TestDemo3会变成配置类,直接进入容器
@Import({ com.ch.TestImportSelector.class})
public class TestDemo {
}
public class TestImportSelector implements ImportSelector {
// 1、返回值: 就是我们实际上要导入到容器中的组件全类名【重点 】
// 2、参数: AnnotationMetadata表示当前被@Import注解给标注的所有注解信息【不是重点】
// 需要注意的是selectImports方法可以返回空数组但是不能返回null,否则会报空指针异常!
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"com.yc.Test.TestDemo3"};
}
}
- ImportBeanDefinitionRegistrar方式
//手动注册bean
@Import({ com.ch.TestImportBeanDefinitionRegistrar.class})
public class TestDemo {
}
public class TestImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
//指定bean定义信息(包括bean的类型、作用域...)
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestDemo4.class);
//注册一个bean指定bean名字(id)
beanDefinitionRegistry.registerBeanDefinition("TestDemo4444",rootBeanDefinition);
}
}