關於context:component-scan配置中use-default-filters參數的作用


參考了多篇文章都說明了use-default-filters參數的基本用途,但有些主要點沒有說到,這里補充記錄下:

<context:component-scan base-package="com.jaamy"  use-default-filters="false"><context:include-filter type="annotation"  expression="org.springframework.stereotype.Controller" /></context:component-scan>

 這個只掃描com.jaamy包下的@Controller,不會掃描@Service、@Repository

 

<context:component-scan base-package="com.jaamy"><context:include-filter type="annotation"  expression="org.springframework.stereotype.Controller" /></context:component-scan>

 這個不但掃描com.jaamy包下的@Controller,同時也會掃描@Service、@Repository,注意這里沒有添加use-default-filters參數

 

下面配合源碼說明下use-default-filters參數的作用以及和context:include-filter、exclude-filter的關系。

代碼中是根據use-default-filters的值來確定是否需要調用registerDefaultFilters來添加默認的filters到includeFilters中,看下面的代碼:

org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider

復制代碼
public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters, Environment environment) {
        if (useDefaultFilters) {
            registerDefaultFilters();
        }
        Assert.notNull(environment, "Environment must not be null");
        this.environment = environment;
    }
復制代碼

 

use-default-filters為true時調用了下面的代碼,在includeFilters列表中添加了Component、ManagedBean和Named,因此use-default-filters的值直接影響includeFilters的內容,而includeFilters的容直接影響了要掃描的內容,因此use-default-filters的值是否配置也就決定了整體要掃描的內容。

復制代碼
protected void registerDefaultFilters() {
        this.includeFilters.add(new AnnotationTypeFilter(Component.class));
        ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
        try {
            this.includeFilters.add(new AnnotationTypeFilter(
                    ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
            logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
        }
        catch (ClassNotFoundException ex) {
            // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.        }
        try {
            this.includeFilters.add(new AnnotationTypeFilter(
                    ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
            logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
        }
        catch (ClassNotFoundException ex) {
            // JSR-330 API not available - simply skip.        }
    }
復制代碼

 

關於include-filter、exclude-filter的作用主要是用來過濾掃描到的bean是否合法:

首先通過exclude-filter進行黑名單過濾;

然后通過include-filter進行白名單過濾;

否則默認排除。 看下面的代碼:

復制代碼
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
        for (TypeFilter tf : this.excludeFilters) {
            if (tf.match(metadataReader, this.metadataReaderFactory)) {
                return false;
            }
        }
        for (TypeFilter tf : this.includeFilters) {
            if (tf.match(metadataReader, this.metadataReaderFactory)) {
                return isConditionMatch(metadataReader);
            }
        }
        return false;
    }
復制代碼

 

總結:

<context:component-scan base-package="com.jaamy"  use-default-filters="false">
         <context:include-filter type="annotation"  expression="org.springframework.stereotype.Controller" />
</context:component-scan>

針對上面的配置,use-default-filters的作用如下:

use-default-filters不配置或者是配置為true時:

不但要掃描include配置的com.jaamy包下的@Controller,而且還要掃描@Service和@Repository

use-default-filters配置為false時:

只掃描include配置的com.jaamy包下的@Controller,不掃描@Service和@Repository

 







免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM