问题

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

  1. <context:component-scan base-package="org.bdp.system.test.controller">
  2. <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
  3. </context:component-scan>

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

  1. <context:component-scan base-package="org.bdp">
  2. <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
  3. </context:component-scan>

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

事务不起作用

这是什么问题呢?

分析

1、<context:component-scan>会交给org.springframework.context.config.ContextNamespaceHandler处理;

  1. 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来调用如下代码:

  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. }

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

4、在进行扫描时会通过include-filter/exclude-filter来判断你的Bean类是否是合法的:

  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 进行白名单过滤;

否则默认排除。

结论

  1. <context:component-scan base-package="org.bdp">
  2. <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
  3. </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的更多相关文章

  1. HBase 的Get(读),Put(写),Delete(删),Scan(扫描)和Increment(列值递增)

    一.HBase介绍 1.基本概念 HBase是一种Hadoop数据库,经常被描述为一种稀疏的,分布式的,持久化的,多维有序映射,它基于行键.列键和时间戳建立索引,是一个可以随机访问的存储和检索数据的平 ...

  2. [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 ...

  3. ESA2GJK1DH1K基础篇: 测试APP扫描Air202上面的二维码绑定通过MQTT控制设备(兼容SIM800)

    前言 此程序兼容SIM800 如果想绑定SIM800,请把其IMEI号,生成二维码,用手机APP扫描. 实现功能概要 APP通过扫描二维码获取GPRS设备的IMEI号,然后设置订阅的主题:device ...

  4. ESA2GJK1DH1K微信小程序篇: 测试微信小程序扫描Air202上面的二维码绑定设备,并通过MQTT控制设备

    前言 一,微信小程序篇小程序下载(该功能为小程序篇基础功能源码) 实现功能概要 微信小程序通过扫描GPRS上的二维码,绑定GPRS设备.然后使用小程序通过GPRS远程控制开发板上的继电器, 远程显示单 ...

  5. springboot笔记-2-.核心的上下文以及配置扫描解析(上)

    前言 上一节中说明了springboot是如何做到自动发现配置的,那么本节看下spring如何创建上下文并解析这些配置,加载我们注册到容器管理中的类.上节已经成功的创建了SpringApplicati ...

  6. SpingMVC的<context:component-scan>包扫描踩坑记录

        公司项目配置的Spring项目的包扫描有点问题,出现了一个被Spring容器管理的Bean被创建了2次的现象.在此记录下解决的过程,方便后续查阅. 改动前: 容器启动监听器中会扫描全部包,创建 ...

  7. 异常 context 包的扫描

    异常信息: org.xml.sax.SAXParseException; lineNumber: 7; columnNumber: 55; schema_reference.4: 无法读取方案文档 ' ...

  8. 利用 SonarScanner 静态扫描 Rainbond 上的 Maven 项目

    对代码进行静态扫描是一种非常常见的代码质量保证手段,这种扫描不仅仅可以检查到代码中的缺陷,应用各种业界最佳实践,也可以检查出安全方面的漏洞,给予项目代码全方位的提升.在各种代码扫描方案之中,Sonar ...

  9. git上传过滤忽略文件

    有些时候我们不想把某些文件纳入版本控制中,比如数据库文件,临时文件,设计文件等 在主目录下建立".gitignore"文件,此文件有如下规则: 忽略文件中的空行或以井号(#)开始的 ...

随机推荐

  1. Tmall Programmer Triples Smartisan Sales

    页面程序造假,丢脸丢到华尔街日报去咯 http://blogs.wsj.com/chinarealtime/2014/10/13/tmall-programmer-triples-smartisan- ...

  2. YARN环境搭建 之 一:CentOS7.0系统配置

    一.我缘何选择CentOS7.0 14年7月7日17:39:42发布了CentOS 7.0.1406正式版,我曾使用过多款Linux,对于Hadoop2.X/YARN的环境配置缘何选择CentOS7. ...

  3. 加载驱动模块时Device or resource busy的解决方法

    加载驱动模块时Device or resource busy的解决方法 加载驱动模块时Device or resource busy的解决方法 insmod或modprobe驱动模块时Device o ...

  4. 这些年,我收集的JavaScript代码

    这些年,我收集的JavaScript代码(一) http://www.cnblogs.com/jscode/archive/2012/07/25/2605395.html 这些年,我收集的JavaSc ...

  5. C# Socket连接请求超时机制

    作者:RazanPaul 译者:Todd Wei 原文:http://www.codeproject.com/KB/IP/TimeOutSocket.aspx 介绍 您可能注意到了,.Net的Syst ...

  6. JPA学习---第六节:大数据字段映射与字段延迟加载

    1.大数据字段所需的注解 @Lob ,例如: @Lobprivate String info; 在mysql中映射产生的字段的类型是longtext:在oracle中是  CLOB @Lobpriva ...

  7. libreoffice转换文档的方法(支持各平台各版本的libreoffice)

    前段时间完成了一个利用libreoffice转换文档进行预览的资源管理系统,用的是jodconvert这个多年未更新的转换项目,由于版本不兼容等原因,导致最新版的libreoffice不能用,浪费了许 ...

  8. Z480联想笔记本突然没有了声音

    这几天笔记本突然没有了声音,重启几次都没有效果. 1.检查了声卡驱动,没有发现问题: 2.检查是否设置了静音,没有问题: 有人说重装驱动,懒得重装,于是下面的一个操作给解决了: 在“设备管理器”中找到 ...

  9. FMS (端口问题)如何穿透防火墙

    转自http://www.cnblogs.com/zhchongyao/archive/2010/01/22/1653803.html 先是管理端口,就是fms2_console文件连接到server ...

  10. Codeforces Round #360 (Div. 2) E. The Values You Can Make 01背包

    题目链接: 题目 E. The Values You Can Make time limit per test:2 seconds memory limit per test:256 megabyte ...