热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

context:componentscan扫描使用上的容易忽略的usedefaultfilters

问题如下方式可以成功扫描到@Controller注解的Bean,不会扫描@Service@Repository的Bean。正确Java代码但是如下方式,不仅仅扫描@Controll

问题

如下方式可以成功扫描到@Controller注解的Bean,不会扫描@Service/@Repository的Bean。正确

Java代码  ,
  1.  package="org.bdp.system.test.controller">   
  2.      "annotation" expression="org.springframework.stereotype.Controller"/>   
  3.   

但是如下方式,不仅仅扫描@Controller,还扫描@Service/@Repository的Bean,可能造成一些问题

Java代码  ,
  1.  package="org.bdp">   
  2.      "annotation" expression="org.springframework.stereotype.Controller"/>   
  3.   

这个尤其在springmvc+spring+hibernate等集成时最容易出问题的地,最典型的错误就是:

事务不起作用

这是什么问题呢?

分析

1、会交给org.springframework.context.config.ContextNamespaceHandler处理;

Java代码  ,
  1. registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());  

2、ComponentScanBeanDefinitionParser会读取配置文件信息并组装成org.springframework.context.annotation.ClassPathBeanDefinitionScanner进行处理;

3、如果没有配置的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.             ((Classextends 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.             ((Classextends 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. }  

可以看到默认ClassPathBeanDefinitionScanner会自动注册对@Component、@ManagedBean、@Named注解的Bean进行扫描。如果细心,到此我们就找到问题根源了。

4、在进行扫描时会通过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. }  

首先通过exclude-filter 进行黑名单过滤;

然后通过include-filter 进行白名单过滤;

否则默认排除。

结论

Java代码  ,
  1. package="org.bdp">   
  2.      "annotation" expression="org.springframework.stereotype.Controller"/>   
  3.   

为什么这段代码不仅仅扫描@Controller注解的Bean,而且还扫描了@Component的子注解@Service、@Reposity。因为use-default-filters默认为true。所以如果不需要默认的,则use-default-filters=“false”禁用掉。

备注:Use-default-filter此时为true那么会对base-package包或者子包下的所有的进行java类进行扫描,并把匹配的java类注册成bean。

Use-dafault-filters=”false”的情况下:指定的不扫描,指定的扫描.

context:component-scan扫描使用上的容易忽略的use-default-filters


推荐阅读
  • .NET Web应用程序安装包的制作经历:Sql数据库安装的3种方式
    一次难得的安装包制作经历,因为之前从没有制作过安装包,那就免不了遇到问题,在摸索和学习中获得了不少宝贵经验,在这里我将用图文并茂的形式详细描述一下流程及主要难点问题的解决方法,希望 ... [详细]
  • 《找地儿》
    -(void)viewDidLoad{[superviewDidLoad];tabBar[[UITabBarControlleralloc]init];tabBar.tabBar. ... [详细]
  • 假设前台通过submit传值,代码如下:那么controller中接收的方法就是在注解里做设置,先上代码,之后再根据代码解释:value值:在springMVC框架中,我们通过@R ... [详细]
  • cURL是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP、FTP、TELNET等。最爽的是,PHP也支持cURL库。本文将介绍cURL的一些高级特性,以 ... [详细]
  • 基于LNMP环境安装配置phpMyAdmin4.8
    phpMyAdmin是一个以PHP为基础、以Web-Base方式架构在网站主机上的、可以通过web方式管理和操作MySQL数据库的管理工具。本文主要内容为基于LNMP环境安装php ... [详细]
  • J ... [详细]
  • httprunner3.X相比httprunner2.X系统中会新增4个命令:httprunner:核心命令hrun:httprunner的缩写,功能与httprunner完全相同 ... [详细]
  • 2.2 与球体相交几何解
    现在,一个简单的球体相交例子已经被概述。这里有一些关于计算效率的概念。一个普遍的看法是,应该尽可能地避免使用平方根函数。检查计时:sqrt()耗时通常是乘法的15~30倍。类似的, ... [详细]
  • 2017年5月24日星期三--出埃及记Exodus26:12Asfortheadditionallengthofthetentcurtains,thehalfcurtainthat ... [详细]
  • 一、昨天做的因为今天是第一天,所以昨天只是开了个会,分配了一些任务,我和小组的另一成员zyp做的是开机启动的代码实现。二、遇到的问题今天做的是开机启动的功能。在开机启动的代码上,我 ... [详细]
  • 广州市智昊电气发布的新一代符合配电物联网要求低压回路测控终端(综合监测装置)带通信功能的数字多功能仪表,DAM8000系列低压测控终端的功能是采集三相电压、开关位置、以及配合电流互 ... [详细]
  • python之基础篇(八)——模块与包
    防伪码:忘情公子著python中的模块将代码量较大的程序分割成多个有组织的、彼此独立但又能互相交互的代码片段,这些自我包含的有组织的代码段就是模块。模块在物理形式上表现为以.py结 ... [详细]
  • 本次实验目的,使用Pacemaker实现DRBD存储及应用高可用?实验环境:系统版本:CentOSrelease6.5(Final)_x64node1:ip:192.168.0.2 ... [详细]
  • 这是一道典型的强连通的题目。 所谓强连通,就是对于一个有向图,若一个集合内任意2点都能过互相达,于是这个几何就是一个强连通分量。 对于任意图,都可以分解人多个不相交的强连通集合。  ... [详细]
  • 6年前的一个U盘记得还是参加某会议送的,当时做了量产多做了一个光盘区,现在用不着了想还原成普通U盘忘了方法。可见笔记的重要性Chipgenius看了主控 PS2251-50芯片是海 ... [详细]
author-avatar
每天吃的饱饱的
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有