如何使用@component-scan排除不需要的類

前因

我們都知道component-scan在springmvc或者springboot中可以掃描包路徑,但是我們如何使用裏面的屬性排除不需要掃描的類?

方式一

使用spring的xml配置方式實現,這個是基本功,知道這種方式,那麼註解方式就容易理解了

<!-- 定義項目掃描包的路徑,並且排除ApplicationContextConfig和WebSpringMVCServletConfig-->
<context:component-scan base-package="com.leo">
    <context:exclude-filter type="assignable" expression="com.leo.config.ApplicationContextConfig"/>
	<context:exclude-filter type="assignable" expression="com.leo.config.WebSpringMVCServletConfig"/>
</context:component-scan>

裏面的type有以下幾種類型,用法不一一舉例了,大家可以自己嘗試。

過濾器類型 描述
annotation 過濾器掃描使用註解標註的那些類,並通過expression指定註解全類名
assignable 過濾器掃描派生於expression屬性指定的類
aspectj 過濾器掃描與expression屬性所指定的AspectJ表達式所匹配的那些類
custom 使用自定義的org.springframework.core.type.TypeFliter實現類,並通過expression指定全類名
regex 過濾器掃描類的名稱與expression屬性指定正則表達式所匹配的那些類

方式二

這種是通過@component-scan方式在配置掃描包路徑的時候直接不包含要排除的包。舉例說明一下如下:
項目的包路徑是:com.leo.configcon.leo.controllercon.leo.service
我不需要掃描com.leo.config,那麼配置@component-scan的時候就可以使用下面的配置直接不用掃描com.leo.config

@ComponentScan(basePackages = {"con.leo.controller","con.leo.service"})

方式三

其實大部分的情況是我們只有com.leo.config下面的某個類需要排除,那麼可以使用FilterType.ASSIGNABLE_TYPE排除。參考如下配置

@ComponentScan(basePackages = {"com.leo"}, excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {ApplicationContextConfig.class, WebSpringMVCServletConfig.class}))

方式四

如果上面的class非常多的話,使用上面的方式就不太合適了,那我們可以使用FilterType.ANNOTATION加自定義註解去實現。參考如下配置

@ComponentScan(basePackages = {"com.leo"}, excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = ScanIgnore.class))

自定義@ScanIgnore實現

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ScanIgnore {
}

方式五

也可通過自定義的過濾器去實現。使用FilterType.CUSTOM加上自定義的過濾器

@ComponentScan(basePackages = {"com.leo"}, excludeFilters = @ComponentScan.Filter(type = FilterType.CUSTOM, classes = MyTypeFilter.class))

自定義過濾器MyTypeFilter

public class MyTypeFilter implements TypeFilter{
    /**
     * 過濾當前類的信息,如果包含的則不需要掃描
     *
     * @param metadataReader 讀取當前正在掃描的信息
     * @param metadataReaderFactory 可以獲取到其他任何類的信息
     * @return
     * @throws IOException
     */
    @Override
    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();
        //包含這個包路徑的則被攔截
        if(className.startsWith("com.leo.config")){
            System.out.println("===============>"+className);
            return false;
        }
        return true;
    }
}

方式六

通過表達式來實現排除,使用FilterType.REGEX,配合pattern來實現。參考配合如下:

@ComponentScan(basePackages = {"com.leo"}, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.leo.config.*"))

總結

以上都是通過excludeFilters實現排除不需要類的方式,如果是反向操作,需要添加需要的類,則將上面的關鍵字替換爲includeFilters就好了。如果是配置文件的實現則

<context:exclude-filter></context:exclude-filter>
替換成
<context:include-filter></context:include-filter>

spring的配置文件是基礎,後面的無論是springmvc亦或者是springboot都是在這個基礎上擴展的,所以打好基礎很重要。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章