• Spring component-scan 的逻辑 、单例模式下多实例问题、事务失效


    原创内容,转发请保留:http://www.cnblogs.com/iceJava/p/6930118.html,非常欢迎指正,谢谢

    之前遇到该问题,今天查看了下 spring 4.x 的代码

    一,先理解下 context:component-scan 处理过程:
     1 <!-- scan the package and the sub package -->
     2 <!--
     3        【重要】:容易产生事务失效的地方,见:http://jinnianshilongnian.iteye.com/blog/1762632
     4        处理逻辑(入口见:org.springframework.context.config.ContextNamespaceHandler):
     5        1. context:component-scan 表示是否扫描指定路径下的所有 .class 文件;
     6            参见 org.springframework.core.io.support.PathMatchingResourcePatternResolver.getResources 方法
     7 
     8        2. use-default-filters,是否使用将 默认的 AnnotationTypeFilter 增加到 include-filter 过滤器,包括:
     9            @Component(包括子注解@Service、@Reposity、@Controller)、@ManagedBean、@Named注解 的Bean
    10            也就是说,如果使用 use-default-filters = true, 就不需要 <context:annotation-config/> 配置了
    11            参见 org.springframework.context.annotation.ComponentScanBeanDefinitionParser.configureScanner
    12 
    13 
    14        3. 遍历所有的bean, 保留满足 "不是 exclude-filter 黑名单、并且至少满足一条 include-filter 白名单" .class 文件
    15            参见 org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.isCandidateComponent 方法    
    16 --> 17 <context:component-scan base-package="com.hm.mobile" use-default-filters="false" > 18 <context:include-filter type="regex" expression=".*Controller$" /> 19 <context:include-filter type="regex" expression=".*Interceptor$" /> 20 </context:component-scan>

    二:单例模式下的多实例问题

    1. 包结构:

      

    MessageController、MessageConsumerListener、MessageProviderService 分别 使用了 @Controller @Service @Service

     

    2. application.xml 配置文件片段

     

    1 <context:component-scan base-package="com.hm.mobile" >
    2     <context:exclude-filter type="regex" expression=".*Controller$" />
    3     <context:exclude-filter type="regex" expression=".*Interceptor$" />
    4 </context:component-scan>

     

      不难理解,在该配置下,Spring 容器 扫描到:MessageConsumerListener、MessageProviderService 并实例化, 其中 MessageController 被黑名单排除

    3. dispatcher-servlet.xml 配置文件片段

    1 <context:component-scan base-package="com.hm.mobile">
    2     <context:include-filter type="regex" expression=".*Controller$" />
    3     <context:include-filter type="regex" expression=".*Interceptor$" />
    4 </context:component-scan>

      Spring MVC 容器 扫描到了 MessageConsumerListener、MessageProviderService、MessageController 并实例化 

     

    4. 通过 vituralVM,我们得到了证实:

     

    5. 在 application-servlet.xml 增加  use-default-filters="false"  之后

     

    
    

    三:事务失效问题

      a. 一般情况下,我们都是在 Spring 配置中事务,因此只有 spring 容器中的 service 对象 被 AOP 注入事务;换句话说, Spring MVC 容器中的service对象 是没有进行 AOP 事务注入的

         b. 因为 Spring mvc 中注入的 service 对象是 自身容器中的 对象,而不是 Spring 容器的

         备注:第三点,是本人自己的猜想,没来得及去验证。

  • 相关阅读:
    [bzoj3261]最大异或和(可持久化trie)
    [luogu3384] 【模板】树链剖分
    [luogu3369]普通平衡树(替罪羊树模板)
    fhq-treap模板
    [luogu3391] 【模板】文艺平衡树(fhq-treap反转区间)
    [luogu3369]普通平衡树(fhq-treap模板)
    [luogu3369]普通平衡树(treap模板)
    [bzoj3223]文艺平衡树(splay区间反转模板)
    A Path Plan(2018黑龙江省赛)
    Abandoned Animal(BAPC2017 Preliminaries )
  • 原文地址:https://www.cnblogs.com/iceJava/p/6930118.html
Copyright © 2020-2023  润新知