Spring父子上下文重叠


问题描述

如果使用传统的方式来开发Spring项目,要部署在Tomcat上面,一般会依赖Spring与Spring MVC,在Tomcat的web.xml中会配置一个加载service的配置文件,这个在Tomcat启动的时候会进行加载,会生成一个Spring的容器。

默认情况下,Tomcat会在资源目录下加载配置servlet名称的另外一个xml配置文件,比如servlet名称为test,那么会加载test-servlet.xml配置文件,如果使用Spring MVC的话,会解析这个配置文件并且再生成一个Spring的容器,同时设置Tomcat启动时创建的那个容器为父容器。

容器分离的影响:

  • 一般在父容器中会加载service,dao之类的东西,不加载controller
  • 在mvc容器中只加载controller

两个容器负责不同的bean,但是如果在父容器中配置了一些AOP想要处理controller的内容,因为容器的隔离,AOP就不会生效。


解决方案

如果明白为什么会出现父子容器问题,那么可以想到如下方案

  • 如果只需要处理service的bean,那么只在父容器的配置文件中操作
  • 如果只处理controller的bean,那么在mvc的配置文件中修改
  • 如果同时要处理service,还要处理controller,那么在两个配置文件中都进行修改

一般我们在Spring的配置文件application.xml中对Service层代码配置事务管理,可以对Service的方法进行AOP增强或事务处理如事务回滚,但是遇到一个问题,在Controller类中调用Service层方法,配置的事务管理会失效,查询相关资料发现原因。其实Spring和SpringMVC俩个容器为父子关系,Spring为父容器,而SpringMVC为子容器。也就是说application.xml中应该负责扫描除@Controller的注解如@Service,而SpringMVC的配置文件应该只负责扫描@Controller,否则会产生重复扫描导致Spring容器中配置的事务失效。

因此正确的配置方式应该为:

首先我会在Spring的applicationContext.xml文件中配置配上下面这段代码:

<context:component-scan base-package="com.chuxin.platform,com.chuxin.core">      <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan>

也就是扫描:component的时候把Controller排除掉

而在SpringMVC的dispatcher-servlet.xml配置文件中配置下面这段代码:

<context:component-scan base-package="com.chuxin.platform.controller" use-default-filters="false">      <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan>

意思是,mvc只扫描controller。其他的component注解就不扫描

为什么这么配置呢,就是为了方式父子上下文扫描重叠的问题。Spring的applicationContext.xml是主上下文,而SpringMVC的dispatcher-servlet.xml是一个子上下文,如果父子上下文扫描重叠就会导致事务不生效。

最后
经过测试,其实问题主要在于SpringMVC的配置文件扫包范围,Spring的配置文件就算也扫了@Controller注解,但是在SpringMVC会重新扫描一次,事务管理的Service只要没被重新扫描就不会出现事务失效问题。


---------------------
作者:hhcccchh
来源:CSDN
原文:https://blog.csdn.net/hhcccchh/article/details/104022770
版权声明:本文为上一个作者原创文章,转载请附上博文链接请询问hhcccchh!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值