springboot 调用方法事物_SpringBoot CGLIB AOP解决Spring事务,对象调用自己方法事务失效....

对于像我这种喜欢滥用AOP的程序员,遇到坑也是习惯了,不仅仅是事务,其实只要脱离了Spring容器管理的所有对象,对于SpringAOP的注解都会失效,因为他们不是Spring容器的代理类,SpringAOP,就切入不了

当然可以使用原生ASPECTJ,不用SpringAOP,但是基于生态链问题,还是尽量使用SpringAOP

这里简单说一下,Spring如何选择使用CGLIB,或者是JDK代理,

简单来说,如果实现了某个接口,那么Spring就选择JDK代理(不一定),如果没有,那么就选择CGLIB代理,说起来简单,Spring还会闹脾气,不代理呢

一直以来比较多的情况是在Controller 调用Service 的方法,把事务直接在Service的方法上,妥妥的没问题,事务正常执行

考虑以下问题: 同对象的方法B 调用自己的方法A,这里的事务将会失效(严格上来说,只要对方法A使用注解AOP均会失效),原因是因为这里的this.调用的并不是Spring的代理对象

@Service

public classClassA{

@Transactional(propagation=Propagation.REQUIRES_NEW)public voidmethodA(){

}/*** 这里调用methodA() 的事务将会失效*/

public voidmethodB(){this.methodA();

}

}

最简单的解决方法为:(代理模式为JDK 的情况下(根据接口代理))

@Servicepublic class ClassA extendsBaseClass{

@Transactional(propagation=Propagation.REQUIRES_NEW)

@Overridepublic voidmethodA(){

}/*** 这里调用methodA() 的事务将会失效*/

public voidmethodB(){//使用getBean

((BaseClass)SpringUtil.getBean("classA")).methodA();

}

}

第二种方式:

解决第一步: 必须

SpringBoot:注解开启cglib代理,开启 exposeProxy = true,暴露代理对象 (否则AopContext.currentProxy()) 会抛出异常

@EnableAspectJAutoProxy(exposeProxy = true)

public class Application{

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}

配置方式:配置方式下,我用的是SpringBoot 1.5.4没有找到exposeProxy的选项,所以建议使用注解式.

传统Spring配置文件

XML

第二步(需要保证Spring对这个bean创建了代理对象,基本上涉及到Aop的方法的类,都会创建代理对象) 可以用以下代码判断

/*** Created by laizhenwei on 19:37 2017-10-14*/@Service("classImplProxy")

@Scope(proxyMode=ScopedProxyMode.INTERFACES)public class ClassImplProxy implementsIClass {

@Override

@Transactionalpublic voidsysout() {

}//是否代理对象

@Overridepublic booleanisAopProxy() {returnAopUtils.isAopProxy(AopContext.currentProxy());

}//是否cglib 代理对象

@Overridepublic booleanisCglibProxy() {returnAopUtils.isCglibProxy(AopContext.currentProxy());

}//是否jdk动态代理

@Overridepublic booleanisJdkDynamicProxy() {returnAopUtils.isJdkDynamicProxy(AopContext.currentProxy());

}

}

获取代理对象

@Servicepublic classClassA{

@Transactional(propagation=Propagation.REQUIRES_NEW)public voidmethodA(){

}

public voidmethodB(){

//手动获取此对象Spring的代理类

((ClassA)AopContext.currentProxy()).methodA();}

}

第三种方式

直接在当前类@Autowire 或者@Resource 注入自己,然后用注入的bean 调用方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值