Spring aop 如何通过获取代理对象实现事务切换

Spring aop 获取代理对象实现事务切换

在项目中,涉及到同一个类中一个方法调用另外一个方法,并且两个方法的事务不相关,

这里面涉及到一个事务切换的问题,一般的方法没问题,根据通过aop注解在方法上通过加注解标识,

答案是:

通过spring aop类里面的AopContext类获取当前类的代理对象,

这样就能切换对应的事务管理器了,具体做法如下:

(1).在applicationContext.xml文件中配置如下:

<!-- 开启暴露Aop代理到ThreadLocal支持  -->
    <aop:aspectj-autoproxy expose-proxy="true"/>  

(2).在需要切换的地方获取代理对象,

再调用对应的方法,如下:

((类名) AopContext.currentProxy()).方法();  

(3).注意

这里需要被代理对象使用的方法必须是public类型的方法,不然获取不到代理对象,会报下面的错误:

java.lang.IllegalStateException: Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.

开启暴露AOP代理即可.

因为开启事务和事务回滚,实际这个过程是aop代理帮忙完成的,当调用一个方法时,它会先检查时候有事务,有则开启事务,

当调用本类的方法是,它并没有将其视为proxy调用,而是方法的直接调用,所以也就没有检查该方法是否含有事务这个过程,

那么本地方法调用的事务也就无效了。

获取代理bean的原始对象

public class AopTargetUtil {
   /**
    * 获取 目标对象
    * @param proxy 代理对象
    * @return
    * @throws Exception
    */
   public static Object getTarget(Object proxy) throws Exception {
      if(!AopUtils.isAopProxy(proxy)) {
         return proxy;//不是代理对象
      }
      if(AopUtils.isJdkDynamicProxy(proxy)) {
         return getJdkDynamicProxyTargetObject(proxy);
      } else { //cglib
         return getCglibProxyTargetObject(proxy);
      }
   }
   private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
      Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
      h.setAccessible(true);
      Object dynamicAdvisedInterceptor = h.get(proxy);
      Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
      advised.setAccessible(true);
      Object target = ((AdvisedSupport)advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
      return target;
   }
   private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
      Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
      h.setAccessible(true);
      AopProxy aopProxy = (AopProxy) h.get(proxy);
      Field advised = aopProxy.getClass().getDeclaredField("advised");
      advised.setAccessible(true);
      Object target = ((AdvisedSupport)advised.get(aopProxy)).getTargetSource().getTarget();
      return target;
   }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Spring如何基于aop实现事务控制

    spring的事务控制本质上是通过aop实现的. 在springboot中使用时,可以通过注解@Transactional进行类或者方法级别的事务控制,也可以自己通过spring提供的事务管理器手动控制事务 一. @Transactional注解进行进行类或者方法级别的事务控制 不需要进行特别的设置,按照正常的配置整合spring和mybatis后,在需要进行事务控制的类上或者方法上加上 @Transactional注解,即可对其进行事务控制. 二.手动控制事务 当需要在一个方法的内部进行事务控

  • Spring AOP拦截-三种方式实现自动代理详解

    这里的自动代理,我讲的是自动代理bean对象,其实就是在xml中让我们不用配置代理工厂,也就是不用配置class为org.springframework.aop.framework.ProxyFactoryBean的bean. 总结了一下自己目前所学的知识. 发现有三种方式实现自动代理 用Spring一个自动代理类DefaultAdvisorAutoProxyCreator: <bean class="org.springframework.aop.framework.autoproxy.

  • SpringAOP事务配置语法及实现过程详解

    配置事务: 使用的tx前缀的标签, 导入tx的命名空间 配置事务管理器 , 把事务管理器交给Spring管理: <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 注入DataSource --> <property name="dataSource" ref="

  • Springboot通过aop实现事务控制过程解析

    spring的事务控制本质上是通过aop实现的. 在springboot中使用时,可以通过注解@Transactional进行类或者方法级别的事务控制,也可以自己通过spring提供的事务管理器手动控制事务 一. @Transactional注解进行进行类或者方法级别的事务控制 不需要进行特别的设置,按照正常的配置整合spring和mybatis后,在需要进行事务控制的类上或者方法上加上 @Transactional注解,即可对其进行事务控制. 二.手动控制事务 当需要在一个方法的内部进行事务控

  • Spring aop 如何通过获取代理对象实现事务切换

    Spring aop 获取代理对象实现事务切换 在项目中,涉及到同一个类中一个方法调用另外一个方法,并且两个方法的事务不相关, 这里面涉及到一个事务切换的问题,一般的方法没问题,根据通过aop注解在方法上通过加注解标识, 答案是: 通过spring aop类里面的AopContext类获取当前类的代理对象, 这样就能切换对应的事务管理器了,具体做法如下: (1).在applicationContext.xml文件中配置如下: <!-- 开启暴露Aop代理到ThreadLocal支持 --> &

  • 关于spring aop两种代理混用的问题

    目录 spring aop两种代理混用问题 一.首先复习一下两种代理 二.我们项目是spring-boot项目 spring的aop和代理模式理解 代理模式代码的主要特点是 代理模式目前实现的方式有三种 Aop的最大意义是 spring aop两种代理混用问题 工作繁忙,但是遇到问题还是要总结积累下来,今天项目中出现了代理混用的问题,解决之后记录一下对两种代理方式的学习理解. 一.首先复习一下两种代理 JDK动态代理 和 cglib代理 1.如果目标对象实现了接口,默认情况下会采用JDK的动态代

  • SpringBoot/Spring AOP默认动态代理方式实例详解

    目录 1. springboot 2.x 及以上版本 2. Springboot 1.x 3.SpringBoot 2.x 为何默认使用 Cglib 总结: Spring 5.x中AOP默认依旧使用JDK动态代理 SpringBoot 2.x开始,AOP为了解决使用JDK动态代理可能导致的类型转换异常,而使用CGLIB. 在SpringBoot 2.x中,AOP如果需要替换使用JDK动态代理可以通过配置项spring.aop.proxy-target-class=false来进行修改,proxy

  • 利用spring aop实现动态代理

    下面由我来给大家展示用spring aop实现动态代理的例子(电脑打印) 下面就看一下具体的代码: 先定义一个打印机的接口 package aop007_ComPrint; public interface Print { public void ColorPrint(); //彩色打印 public void WhitePrint(); //黑白打印 } 然后定义两个实现类,分别实现彩色打印和黑白打印 package aop007_ComPrint; public class ColorPri

  • Spring AOP 与代理的概念与使用

    一.AOP 的基本概念 1.1 什么是 AOP Aspect Oriented Programming,面向切面编程. 就跟我们说 OOP 是面向对象一样,AOP 是面向切面的.切面是分散在应用中的一个标准代码或功能.切面通常与实际的业务逻辑不同(例如,事务管理).每个切面专注于一个特定的环切功能. 这里的切面呢,可以理解为横切.比如在所有的 DAO 层方法上加上一个同样的切面,功能是记录日志:又或者在某个接口上应用一个切面,作用是检查权限. AOP 是基于代理来实现的.而代理又分为静态代理和动

  • 深入浅出讲解Spring框架中AOP及动态代理的应用

    目录 一. Spring AOP 1. 传统问题: 2. 问题的解决策略: 3. AOP优点: 二.  动态代理 1.JDK动态代理 2. CGLIB代理 一. Spring AOP 面向切面编程(Aspect Oriented Programming,AOP)是软件编程思想发展到一定阶段的产物,是对面向对象编程(Object Oriented Programming,OOP)的有益补充, 目前已成为一种比较成熟的编程方式.AOP适用于具有横向逻辑的场所,如访问控制.事务管理.性能监测等. 1.

  • Spring AOP实现声明式事务机制源码解析

    目录 一.声明式全局事务 二.源码 三.小结: 一.声明式全局事务 在Seata示例工程中,能看到@GlobalTransactional,如下方法示例: @GlobalTransactional public boolean purchase(long accountId, long stockId, long quantity) { String xid = RootContext.getXID(); LOGGER.info("New Transaction Begins: " +

  • Spring AOP代理详细介绍

    Spring AOP代理详细介绍 前言: 一开始我对spring AOP还是属于一知半解的状态,这几天遇到一个问题,加上又查看了一些Spring相关知识,感觉对这个问题有了更深刻的认识.所以写下来分享一下. 我们知道,Spring支持多种AOP方式,Spring自己的基于代理的AOP和AspectJ的基于编织(weaving)的AOP.如果一个类实现了一个或多个接口,那么Spring就会使用默认的JDK动态代理,如果没有实现任何接口,就会使用cglib来代理.当然我们也可以手动改变这些设置.这也

  • Spring AOP里的静态代理和动态代理用法详解

    什么是代理? 为某一个对象创建一个代理对象,程序不直接用原本的对象,而是由创建的代理对象来控制原对象,通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间 什么是静态代理? 由程序创建或特定工具自动生成源代码,在程序运行前,代理类的.class文件就已经存在 通过将目标类与代理类实现同一个接口,让代理类持有真实类对象,然后在代理类方法中调用真实类方法,在调用真实类方法的前后添加我们所需要的功能扩展代码来达到增强的目的. 优点

  • Spring AOP底层原理及代理模式

    目录 Spring AOP底层原理代理模式 一.什么是 AOP 二.AOP 底层原理 1. 什么是代理? 2. 什么是静态代理 3. 什么是动态代理 Spring AOP底层原理代理模式 一.什么是 AOP AOP 就是面向切面编程,是 OOP(面向对象编程)的延续. 利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序可用性,同时也提高了开发效率. 通俗一点说,不用修改原代码,可以给原代码增加新的功能. 二.AOP 底层原理 AOP 底层原理是使用动

随机推荐