测试了下spring 包扫描 :
<context:component-scan base-package="com.long.apple.scantest" use-default-filters="true">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
其中use-default-filters参数默认为true
也就说可以扫描@controller和@service/@Repository注解的bean;
如果设置use-default-filters参数默认为false就不再加载任何bean;
对以上情况也有列外,就是用
通过exclude-filter 进行黑名单过滤;
通过include-filter 进行白名单过滤;
也就说:如果参数use-default-filters设置为false只加载include-filter类型的bean,其它bean不再加载;
如果参数use-default-filters设置为true,则全部加载@controller和@service\@respository 类型的bean,排除exclude-filter类型的bean;
这样看来如果默认use-default-filters为true,再加include-filter控制,如果控制范围是@controller和@service\@respository 类型就没意义,当然可以加include-filter控制其它注解也实例化,比如自己实现的一个注解@zhujie
<context:component-scan
base-package="com.elong.apple.scantest" use-default-filters="true">
<context:exclude-filter type="annotation" expression="com.long.apple.scantest.Zhujie"/>
</context:component-scan>
可以写两个注解测试下:
具体实现代码可以参考org.springframework.context.annotation.ClassPathBeanDefinitionScanner中的代码处理:
其中两个方法:
1.如果没有配置<context:component-scan>的use-default-filters属性,则默认为true,在创建ClassPathBeanDefinitionScanner时会根据use-default-filters是否为true来调用如下代码:
- protected void registerDefaultFilters() {
- this.includeFilters.add(new AnnotationTypeFilter(Component.class));
- ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
- try {
- this.includeFilters.add(new AnnotationTypeFilter(
- ((Class<? extends Annotation>) cl.loadClass("javax.annotation.ManagedBean")), false));
- logger.info("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>) cl.loadClass("javax.inject.Named")), false));
- logger.info("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
- }
- catch (ClassNotFoundException ex) {
- // JSR-330 API not available - simply skip.
- }
2.通过include-filter/exclude-filter来判断你的Bean类是否是合法的:
- 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)) {
- AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
- if (!metadata.isAnnotated(Profile.class.getName())) {
- return true;
- }
- AnnotationAttributes profile = MetadataUtils.attributesFor(metadata, Profile.class);
- return this.environment.acceptsProfiles(profile.getStringArray("value"));
- }
- }
- return false;
- }