如果你使用了listener监听器来加载配置,一般在Struts+Spring+Hibernate的项目中都是使用listener监听器的。如下

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Spring会创建一个WebApplicationContext上下文,称为父上下文(父容器) ,保存在 ServletContext中,key是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE的值。

可以使用Spring提供的工具类取出上下文对象:WebApplicationContextUtils.getWebApplicationContext(ServletContext);

DispatcherServlet是一个Servlet,可以同时配置多个,每个 DispatcherServlet有一个自己的上下文对象(WebApplicationContext),称为子上下文(子容器),子上下文可以访问父上下文中的内容,但父上下文不能访问子上下文中的内容。 它也保存在 ServletContext中,key是"org.springframework.web.servlet.FrameworkServlet.CONTEXT"+Servlet名称。当一个Request对象产生时,会把这个子上下文对象(WebApplicationContext)保存在Request对象中,key是DispatcherServlet.class.getName() + ".CONTEXT"。

可以使用工具类取出上下文对象:RequestContextUtils.getWebApplicationContext(request);

说明 :Spring 并没有限制我们,必须使用父子上下文。我们可以自己决定如何使用。

方案一,传统型:

父上下文容器中保存数据源、服务层、DAO层、事务的Bean。

子上下文容器中保存Mvc相关的Action的Bean.

事务控制在服务层。

由于父上下文容器不能访问子上下文容器中内容,事务的Bean在父上下文容器中,无法访问子上下文容器中内容,就无法对子上下文容器中Action进行AOP(事务)。

常用配置例如:

在主容器中(applicationContext.xml),将Controller的注解排除掉

    <context:component-scan base-package="jcode">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>

而在springMVC配置文件中将Service注解给去掉

<context:component-scan base-package="jcode">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>

说明:因为spring的context是父子容器,所以会产生冲突,由ServletContextListener产生的是父容器,springMVC产生的是子容器,子容器Controller进行扫描装配时装配了@Service注解的实例,而该实例理应由父容器进行初始化以保证事务的增强处理,所以此时得到的将是原样的Service(没有经过事务加强处理,故而没有事务处理能力。

还有一种方式是将service层改用xml配置,其实这样做也是变相的让springmvc无法扫描service,而只能依赖父窗口也就是ServletContextListener来进行初始化,这样同样被赋予了事务性。

方案二,激进型:

Java世界的“面向接口编程”的思想是正确的,但在增删改查为主业务的系统里,Dao层接口,Dao层实现类,Service层接口,Service层实现类,Action父类,Action。再加上众多的O(vo\po\bo)和jsp页面。写一个小功能 7、8个类就写出来了。 开发者说我就是想接点私活儿,和PHP,ASP抢抢饭碗,但我又是Java程序员。最好的结果是大项目能做好,小项目能做快。所以“激进型”方案就出现了-----没有接口、没有Service层、还可以没有众多的O(vo\po\bo)。那没有Service层事务控制在哪一层?只好上升的Action层。

本文不想说这是不是正确的思想,我想说的是Spring不会限制你这样做。

由于有了父子上下文,你将无法实现这一目标。解决方案是只使用子上下文容器,不要父上下文容器 。所以数据源、服务层、DAO层、事务的Bean、Action的Bean都放在子上下文容器中。就可以实现了,事务(注解事务)就正常工作了。这样才够激进。

总结:不使用listener监听器来加载spring的配置文件,只使用DispatcherServlet来加载spring的配置,不要父子上下文,只使用一个DispatcherServlet,事情就简单了,什么麻烦事儿也没有了

Spring父子上下文(WebApplicationContext)(防止事务失效)的更多相关文章

  1. Spring父子上下文的使用案例

    Spring父子上下文的使用案例 一.背景 二.需求 三.实现步骤 1.基础代码编写 2.测试结果 四.小彩蛋 五.完整代码 一.背景 最近在看在使用Spring Cloud的时候发现,当我们通过Fe ...

  2. Spring MVC @Transactional注解方式事务失效的解决办法

    在springMVC类上绑定@Transactional的注解,但是访问数据库时,总是报 can't localtion to current JTA Transactional. 后来发现sprin ...

  3. 聊聊spring事务失效的12种场景,太坑了

    前言 对于从事java开发工作的同学来说,spring的事务肯定再熟悉不过了. 在某些业务场景下,如果一个请求中,需要同时写入多张表的数据.为了保证操作的原子性(要么同时成功,要么同时失败),避免数据 ...

  4. Spring事务失效的2种情况

    使用默认的事务处理方式 因为在java的设计中,它认为不继承RuntimeException的异常是”checkException”或普通异常,如IOException,这些异常在java语法中是要求 ...

  5. Spring MVC学习------------WebApplicationContext

    父子上下文(WebApplicationContext) 假设你使用了listener监听器来载入配置.一般在Struts+Spring+Hibernate的项目中都是使用listener监听器的. ...

  6. spring声明式事务 同一类内方法调用事务失效(转)

    原文 https://blog.csdn.net/jiesa/article/details/53438342 [问题] Spring的声明式事务,我想就不用多介绍了吧,一句话“自从用了Spring ...

  7. spring+springMVC,声明式事务失效,原因以及解决办法

    http://blog.csdn.net/z69183787/article/details/37819627#comments 一.声明式事务配置: <bean id="transa ...

  8. java面试记录二:spring加载流程、springmvc请求流程、spring事务失效、synchronized和volatile、JMM和JVM模型、二分查找的实现、垃圾收集器、控制台顺序打印ABC的三种线程实现

    注:部分答案引用网络文章 简答题 1.Spring项目启动后的加载流程 (1)使用spring框架的web项目,在tomcat下,是根据web.xml来启动的.web.xml中负责配置启动spring ...

  9. spring事务失效

    最近在做spring 项目中突然发现事务在遇到异常是没有回滚而是提交了,在查了大量的资料之后,算是有了一点头绪,写下来方便以后查找: 前些日子一朋友在需要在目标对象中进行自我调用,且需要实施相应的事务 ...

随机推荐

  1. 《DNS攻击防范科普系列2》 -DNS服务器怎么防DDoS攻击

    在上个系列<你的DNS服务真的安全么?>里我们介绍了DNS服务器常见的攻击场景,看完后,你是否对ddos攻击忧心重重?本节我们来告诉你,怎么破局!! 首先回顾一下DDoS攻击的原理.DDo ...

  2. bzoj1016题解

    [解题思路] Kruskal的拓展. 可以先对边排序,进行一次Kruskal,判断是否可行,并计算出每种权值的边需要多少条. 然后暴力统计每种权值可行的方案数,根据乘法原理乘起来即可.复杂度o(210 ...

  3. windows启动redis失败

    # Warning: no config file specified, using the default config. In order to specify a config file use ...

  4. Feign连接超时 Read timed out

    在远程调用的过程中由于连接超时,导致无法成功请求数据,下面是报错 项目中用的是spring-cloud-starter-openfeign 2.2.0版本 找到对应的文档,开始查阅资料 文档首页就找到 ...

  5. delphi 实现最小化系统托盘(rz控件最简单 评论)

    1.new -->application 2.在form1中加入一个tPopMenu 命名为pm1 3.uses ShellAPI; 4.定义一个常量在 const WM_TRAYMSG = W ...

  6. Python匹马行天下之初识python!

    python的发展史 1989年,被称为龟叔的Guido在为ABC语言写插件时,产生了写一个简洁又实用的编程语言的想法,并开始着手编写.因为其喜欢Monty Python喜剧团,所以将其命名为pyth ...

  7. 2018ICPC焦作 D-Keiichi Tsuchiya the Drift King /// 几何

    题目大意: https://nanti.jisuanke.com/t/34142 有一个弯道抽象成圆的一部分 车子抽象成矩形 漂移过程中矩形上边会与圆的圆心在同一条直线上 以右上点贴着弯道边缘进行漂移 ...

  8. 006-Java的break和continue

    break 和 continue关键字的使用 break: 结束当前循环 continue:结束当次循环 示例如下 class JavaTest{ public static void main(St ...

  9. Aop 简单实例

    一 , 定义aop @Aspect @Component public class MyAspect { //* com 这里有个 空格 ! @Pointcut("execution(* c ...

  10. Git 获取项目git clone

    git clone 克隆项目 git clone 实际上是一个封装了其他几个命令的命令. 它创建了一个新目录,切换到新的目录,然后 git init 来初始化一个空的 Git 仓库, 然后为你指定的 ...