Spring包扫描

来源:互联网 发布:程序员修炼之道百度云 编辑:程序博客网 时间:2024/06/06 14:07

测试了下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来调用如下代码:

 

Java代码  收藏代码
  1.   protected void registerDefaultFilters() {  
  2. this.includeFilters.add(new AnnotationTypeFilter(Component.class));  
  3. ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();  
  4. try {  
  5.     this.includeFilters.add(new AnnotationTypeFilter(  
  6.             ((Class<? extends Annotation>) cl.loadClass("javax.annotation.ManagedBean")), false));  
  7.     logger.info("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");  
  8. }  
  9. catch (ClassNotFoundException ex) {  
  10.     // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.  
  11. }  
  12. try {  
  13.     this.includeFilters.add(new AnnotationTypeFilter(  
  14.             ((Class<? extends Annotation>) cl.loadClass("javax.inject.Named")), false));  
  15.     logger.info("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");  
  16. }  
  17. catch (ClassNotFoundException ex) {  
  18.     // JSR-330 API not available - simply skip.  
  19. }  

 

2.通过include-filter/exclude-filter来判断你的Bean类是否是合法的:

 

Java代码  收藏代码
  1. protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {  
  2.     for (TypeFilter tf : this.excludeFilters) {  
  3.         if (tf.match(metadataReader, this.metadataReaderFactory)) {  
  4.             return false;  
  5.         }  
  6.     }  
  7.     for (TypeFilter tf : this.includeFilters) {  
  8.         if (tf.match(metadataReader, this.metadataReaderFactory)) {  
  9.             AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();  
  10.             if (!metadata.isAnnotated(Profile.class.getName())) {  
  11.                 return true;  
  12.             }  
  13.             AnnotationAttributes profile = MetadataUtils.attributesFor(metadata, Profile.class);  
  14.             return this.environment.acceptsProfiles(profile.getStringArray("value"));  
  15.         }  
  16.     }  
  17.     return false;  
  18. }  

 







0 0
原创粉丝点击