参考了多篇文章都说明了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
参考地址:http://jinnianshilongnian.iteye.com/blog/1762632