注解@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 {
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐