注解@ComponentScan就相当于spring xml配置文件中的context:component-scan,用来扫描指定的package,把符合条件的bean注入到容器里面。
Spring @ComponentScan – Filter Types用法连接
一般用法
@ComponentScan主要用法就是用来扫描指定的包下面的bean对象,ComponentScan可以配置多个,springboot默认就是扫描启动类所在的包的下面所有的bean,如果还需要额外指定别的package,则需要新增一个ComponentScan,并且需要手动指定springboot所在类的package的路径,要不然就不会被加载。
@SpringBootApplication
@ComponentScan(value = {"cn.component"})
@ComponentScan(value = {"com.madman.springbootdemo"})
public class SpringbootdemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootdemoApplication.class, args);
}
}
主要几个属性
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
是否使用默认的过滤器,一般都是true,如controller,service这些注解都是默认加载的,如果设置为false,这些就不会被加载。
boolean useDefaultFilters() default true;
设置哪些会被加载
Filter[] includeFilters() default {};
设置哪些不会被加载
Filter[] excludeFilters() default {};
boolean lazyInit() default false;
ComponentScan一般都是配置包的路劲,
basePackageClasses 用于指定特定的类,就比如说需要加载某个特定的类可以使用这一的写法。
@ComponentScan(basePackages = "cn.component", basePackageClasses = {Red.class})
FilterType.ANNOTATION使用
这个例子就是只扫描cn.component2包下面的包含注解是Controller的类,其他的service、Component则不会被扫描,需要注意的地方就是这里的useDefaultFilters一定要设置成false,要不然还是会把其他的加载进来,因为默认就是会加载spring的一些特定的注解。
@ComponentScan(value = {"cn.component2"}, useDefaultFilters = false, includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class)})
FilterType.ASSIGNABLE_TYPE使用
这个类型主要是根据类型来判断是否加载,比如说这里就只会加载Color的类和他的子类,子类也会被加载的。
@ComponentScan(value = {"cn.component2"}, useDefaultFilters = false, includeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Color.class)})
FilterType.ASPECTJ使用切面进行匹配
@ComponentScan(value = {"cn.component2"}, useDefaultFilters = false, includeFilters = {@ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = {"cn.component2.*"})})
FilterType.REGEX
使用正则表达式进行匹配,这个和上面的FilterType.ASPECTJ有点相似,但是匹配的语法不一样。在这里插入代码片
@ComponentScan(value = {"cn.component2"}, useDefaultFilters = false, includeFilters = {@ComponentScan.Filter(type = FilterType.REGEX, pattern = {".*[2,d]"})})
FilterType.CUSTOM
使用自定义的过滤器,制定个性化的加载方式。
@ComponentScan(value = {"cn.component2"}, useDefaultFilters = false, includeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM, classes = {CustomFilter.class})})
自定义过滤器需要实现TypeFilter 接口。
public class CustomFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
ClassMetadata classMetadata = metadataReader.getClassMetadata();
Resource resource = metadataReader.getResource();
if (classMetadata.getClassName().contains("Co")) {
return true;
}
return false;
}
}
每个过滤器的具体实现类
每个过滤器的具体实现类可以通过FilterType这个类点开去查看。
ANNOTATION的具体实现类是org.springframework.core.type.filter.AnnotationTypeFilter。
ASSIGNABLE_TYPE的具体实现类是org.springframework.core.type.filter.AssignableTypeFilter。
测试的时候都是使用includeFilters ,excludeFilters的用法是一样的。
应用
SpringBoot在启动的时候就会使用两个自定义的扫描过滤,TypeExcludeFilter和AutoConfigurationExcludeFilter。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {