context:component-scan扫描使用上的容易忽略的use-default-filters
问题
如下方式可以成功扫描到@Controller注解的Bean,不会扫描@Service/@Repository的Bean。正确
- <context:component-scan base-package="org.bdp.system.test.controller">
- <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
- </context:component-scan>
但是如下方式,不仅仅扫描@Controller,还扫描@Service/@Repository的Bean,可能造成一些问题
- <context:component-scan base-package="org.bdp">
- <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
- </context:component-scan>
这个尤其在springmvc+spring+hibernate等集成时最容易出问题的地,最典型的错误就是:
事务不起作用
这是什么问题呢?
分析
1、<context:component-scan>会交给org.springframework.context.config.ContextNamespaceHandler处理;
- registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
2、ComponentScanBeanDefinitionParser会读取配置文件信息并组装成org.springframework.context.annotation.ClassPathBeanDefinitionScanner进行处理;
3、如果没有配置<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.
- }
可以看到默认ClassPathBeanDefinitionScanner会自动注册对@Component、@ManagedBean、@Named注解的Bean进行扫描。如果细心,到此我们就找到问题根源了。
4、在进行扫描时会通过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;
- }
即
首先通过exclude-filter 进行黑名单过滤;
然后通过include-filter 进行白名单过滤;
否则默认排除。
结论
- <context:component-scan base-package="org.bdp">
- <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
- </context:component-scan>
为什么这段代码不仅仅扫描@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:exclude-filter>指定的不扫描,<context:include-filter>指定的扫描.
context:component-scan扫描使用上的容易忽略的use-default-filters的更多相关文章
- HBase 的Get(读),Put(写),Delete(删),Scan(扫描)和Increment(列值递增)
一.HBase介绍 1.基本概念 HBase是一种Hadoop数据库,经常被描述为一种稀疏的,分布式的,持久化的,多维有序映射,它基于行键.列键和时间戳建立索引,是一个可以随机访问的存储和检索数据的平 ...
- [Spring Boot] Use Component Scan to scan for Bean
Component Scan is important concept when we want to create Bean. Currently we know what, for the cla ...
- ESA2GJK1DH1K基础篇: 测试APP扫描Air202上面的二维码绑定通过MQTT控制设备(兼容SIM800)
前言 此程序兼容SIM800 如果想绑定SIM800,请把其IMEI号,生成二维码,用手机APP扫描. 实现功能概要 APP通过扫描二维码获取GPRS设备的IMEI号,然后设置订阅的主题:device ...
- ESA2GJK1DH1K微信小程序篇: 测试微信小程序扫描Air202上面的二维码绑定设备,并通过MQTT控制设备
前言 一,微信小程序篇小程序下载(该功能为小程序篇基础功能源码) 实现功能概要 微信小程序通过扫描GPRS上的二维码,绑定GPRS设备.然后使用小程序通过GPRS远程控制开发板上的继电器, 远程显示单 ...
- springboot笔记-2-.核心的上下文以及配置扫描解析(上)
前言 上一节中说明了springboot是如何做到自动发现配置的,那么本节看下spring如何创建上下文并解析这些配置,加载我们注册到容器管理中的类.上节已经成功的创建了SpringApplicati ...
- SpingMVC的<context:component-scan>包扫描踩坑记录
公司项目配置的Spring项目的包扫描有点问题,出现了一个被Spring容器管理的Bean被创建了2次的现象.在此记录下解决的过程,方便后续查阅. 改动前: 容器启动监听器中会扫描全部包,创建 ...
- 异常 context 包的扫描
异常信息: org.xml.sax.SAXParseException; lineNumber: 7; columnNumber: 55; schema_reference.4: 无法读取方案文档 ' ...
- 利用 SonarScanner 静态扫描 Rainbond 上的 Maven 项目
对代码进行静态扫描是一种非常常见的代码质量保证手段,这种扫描不仅仅可以检查到代码中的缺陷,应用各种业界最佳实践,也可以检查出安全方面的漏洞,给予项目代码全方位的提升.在各种代码扫描方案之中,Sonar ...
- git上传过滤忽略文件
有些时候我们不想把某些文件纳入版本控制中,比如数据库文件,临时文件,设计文件等 在主目录下建立".gitignore"文件,此文件有如下规则: 忽略文件中的空行或以井号(#)开始的 ...
随机推荐
- jquery 清空表达内容
function clearForm(objE) { $(objE).find(':input').each( function() { switch (this.type) { case 'pass ...
- WPF样式——多条件触发器
希望创建多个条件都为真时才激发的触发器,就需要使用MultiTrigger提供的Condition集合 <Window x:Class="Styles.MultiTrigger&quo ...
- CentOS thrift python demo
编辑接口文件 hellowworld.thrift service HelloWorld { string ping(), string say(1:string msg) } 编辑 server.p ...
- ASP.NET MVC 技术债务
ASP.NET MVC 缓存.本地化和监控诊断 ASP.NET MVC 认证与授权 Entity Framework 创建数据模型
- php字符串函数和数组函数
/验证码$str="abcdefghijklmnopqrstuvwxyz0123456789";$a=substr($str,rand(0,35),1);$b=substr($st ...
- 【BZOJ 1188】 [HNOI2007]分裂游戏
Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子 ...
- VBS基础篇 - class
Class 语句:声明一个类的名称,以及组成该类的变量.属性和方法的定义. Class name '参数name必选项,Class 的名称 statements '一个或多个语句,定义了 Class ...
- python学习小结6:模块
模块:在Python中有一个概念叫做模块(module),简单地说,模块就是一个保存了Python代码的文件. 模块能定义函数,类和变量,模块里也能包含可执行的代码. ...
- 生成最小树prim算法
最小生成树prim算法实现 ‘ ’最小生成树,就是权值(两点间直线的值)之和的最小值. 首先,要用二维数组记录点和权值.如上图所示无向图: int G[6][6]; G[1] ...
- 查看系统网络连接打开端口、系统进程、DOS打开文件
问题描述: DOS查看系统网络连接打开端口.打开的服务 问题解决: (1)DOS查看系统网络连接打开端口 注: 使用 netstat 命令,可以查看系统打开的端口 (2)查看和关闭系统打开进程 ...