一、背景

​ 我们在Spring+SpringMVC+Mybatis的集成开发中,经常会遇到事务配置不起作用等问题,有时候就是因为包扫描出了问题,其中component-scan的标签的use-default-filters属性坑了很多人,那么本文就来分析下出现这种问题可能的原因以及解决方式。

二、分析及原理窥探

项目结构

我们在spring-mvc.xml文件中进行如下配置,这种方式会成功扫描到带有@Controller注解的Bean,不会扫描带有@Service@Repository注解的Bean,是正确的。

<context:component-scan base-package="com.hafiz.www.controller">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

但是如下方式配置不仅仅扫描到带有@Controller注解的Bean,还扫描到带有@Service@Repository注解的Bean,可能造成事务不起作用等问题。

<context:component-scan base-package="com.hafiz.www"></context:component-scan>

这是因为什么呢?下面让我们来从源码进行分析:

  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 进行白名单过滤,否则默认排除。

    三、结论

    在spring-mvc.xml中进行如下配置:

    <context:component-scan base-package="com.hafiz.www">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    则SpringMVC容器不仅仅扫描并注册带有@Controller注解的Bean,而且还扫描并注册了带有@Component的子注解@Service@Reposity的Bean。因为use-default-filters默认为true。所以如果不需要默认的,则use-default-filters=“false”禁用掉。叉车价格
    当我们进行上面的配置时,SpringMVC容器会把service、dao层的bean重新加载,从而造成新加载的bean覆盖了老的bean,但事务的AOP代理没有配置在spring-mvc.xml配置文件中,造成事务失效。解决办法是:在spring-mvc.xml配置文件中的context:component-scan标签中使用use-default-filters=“false”禁用掉默认的行为。

component-scan标签的use-default-filters属性的作用以及原理分析的更多相关文章

  1. context:component-scan标签的use-default-filters属性的作用以及原理分析

    一.背景 我们在Spring+SpringMVC+Mybatis的集成开发中,经常会遇到事务配置不起作用等问题,那么本文就来分析下出现这种问题可能的原因以及解决方式. 二.分析及原理窥探 1.项目结构 ...

  2. HTML5 script 标签的 crossorigin 和integrity属性的作用

    Bootstrap 4 依赖的基础库中出现了两个新的属性 <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.slim.m ...

  3. 在Asp.Net MVC中实现RequiredIf标签对Model中的属性进行验证

    在Asp.Net MVC中可以用继承ValidationAttribute的方式,自定制实现RequiredIf标签对Model中的属性进行验证 具体场景为:某一属性是否允许为null的验证,要根据另 ...

  4. CompareValues标签对Model中的属性进行验证

    在Asp.Net MVC中实现CompareValues标签对Model中的属性进行验证   在Asp.Net MVC中可以用继承ValidationAttribute的方式,自定制实现Model两个 ...

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

  6. HTML5中常用的标签(及标签的属性和作用)

    1.标签:<!DOCTYPE>作用:声明是文档中的第一成分,位于<html>标签之前. 2.标签:<html>作用:此元素可告知浏览器其自身是一个HTML文档.属性 ...

  7. HTML <img> 标签的 height 和 width 属性

    定义和用法 <img> 标签的 height 和 width 属性设置图像的尺寸. 提示:为图像指定 height 和 width 属性是一个好习惯.如果设置了这些属性,就可以在页面加载时 ...

  8. html的标签中 unselectable=on 属性的作用

    在IE浏览器中,当input获得焦点时,点击有unselectable="on"属性的标签时,不会触发onblur事件. 加上该属性的元素不能被选中. < !DOCTYPE ...

  9. HTML <script> 标签的 defer 和 async 属性

    HTMKL <script>标签中有defer和async属性,简单介绍一下两者的区别吧.   普通的script标签会让浏览器立即下载并执行完毕,执行也是按照先后顺序,再进行后面的解析. ...

随机推荐

  1. --oracle删除数据库表(无主键)中重复的记录

    --oracle删除数据库表(无主键)中重复的记录 1,  CREATE TABLE newtable as SELECT distinct * FROM T_SYSTEM_MENU_PRIV; 2, ...

  2. 一个百度MAP导航的基础封装

    项目中需要根据点击时候点击的内容,输入百度地图查找并展示规划等相关功能 于是封装了一个单独的百度map的html页面以供调用 功能包括了 ①展示底图 ②切换卫星图,切换卫星路线图,切换普通地图 ③通过 ...

  3. 嵌入式STM32开发环境之Keil5的安装(附资源)--

    全文copy,原文见https://blog.csdn.net/weixin_42602730/article/details/81007685 --------------------------- ...

  4. MYSQL 5.7.25最后一个5.x版本记录

      一:下载 位 https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.25-win32.zip 位 https://dev.mysql.co ...

  5. 百度地图热力图--批量地址转换应用(基于百度api)

    需求:把外卖订餐地址做个用户分布热力图 思路分析:第一步去百度地图api开放平台找例子 http://lbsyun.baidu.com/jsdemo.htm#c1_15 首先从百度API的demo例子 ...

  6. ubuntu18.04 VirtualBox 开启虚拟机出错 Kernel driver not installed (rc=-1908)

    写的很明白了 提示缺少GCC PERL MAKE,安装 重试..... 重启VM 搞定....

  7. spark 例子groupByKey分组计算

    spark 例子groupByKey分组计算 例子描述: [分组.计算] 主要为两部分,将同类的数据分组归纳到一起,并将分组后的数据进行简单数学计算. 难点在于怎么去理解groupBy和groupBy ...

  8. 20155216 2016-2017-2 《Java程序设计》第二周学习总结

    教材学习内容总结 类型 short占2字节 int占4字节 long占8字节 byte占1字节,可表示-128~127的整数 char占2字节 boolean不考虑占字节 float占4字节 doub ...

  9. 20155222卢梓杰 《Java程序设计》第1周学习总结

    20155222 <Java程序设计>第1周学习总结 教材学习内容总结 JDK是一个工具程序,包括了JAVA程序语言,工具程序与JRE,JRE包括了部署技术,JAVA SE API 与 J ...

  10. combotree -下拉框树异步加载

    问题: 下拉树数据比较多时,全加载会产生页面延迟,需要实现异步加载 方案: 点击事件加载:先加载部分,点击节点时再展开并追加子节点 onBeforeExpand事件:在展开树前加载,感觉这种方式比较优 ...