分享

Spring中component-scan标签的use-default-filters属性的作用以及...

 股海无涯苦作舟 2021-11-11

背景

    我们在Spring+SpringMVC+Mybatis的集成开发中,经常会遇到事务配置不起作用等问题,那么本文就来分析下由于spring和springmvc父子容器关系导致出现这种问题可能的原因以及解决方式.

问题分析及原理窥探

首先看下项目结构

图片

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

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

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

  1. spring标签<context:component-scan>会交给org.springframework.context.config.ContextNamespaceHandler处理。

  2. 在org.springframework.context.config.ContextNamespaceHandler中有如下源码:

    图片

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

  4. 如果没有配置<context:component-scan>的use-default-filters属性,则默认为true,在创建ClassPathBeanDefinitionScanner时会根据use-default-filters是否为true来调用如下代码:

    图片

    从以上源码我们可以看出默认ClassPathBeanDefinitionScanner会自动注册对@Component、@ManagedBean、@Named注解的Bean进行扫描。

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

从以上源码可看出:扫描时首先通过exclude-filter 进行黑名单过滤,然后通过include-filter 进行白名单过滤,否则默认排除。

结论

    若我们在spring-mvc.xml中进行如下配置:图片    则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”禁用掉默认的行为。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多