Spring包扫描

本文介绍了Spring的包扫描机制,详细解析了`<context:component-scan>`标签的`use-default-filters`属性,以及如何通过`exclude-filter`和`include-filter`进行黑白名单过滤。当`use-default-filters`为true时,会扫描@Controller、@Service和@Repository注解的bean,反之则不加载。同时,可以通过自定义注解并结合include-filter来控制额外的bean实例化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

测试了下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. }  

 







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值