spring註解ComponentScan使用

註解@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 {
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章