Spring AopContext.currentProxy 遇到 JDK动态代理

在实际开发中,我们经常需要在同一个类中嵌套调用事物方法,由于spring aop原理,只有在代理类调用层面的方法才会解析事物,方法内部嵌套调用,无法解析事物注解。所以这时我们就需要修改嵌套调用方式,用AopContext.currentProxy 获取当前类的代理类来调用嵌套调用的方法,这样spring aop就会解析方法事物注解标记。但是如果当前类实现了接口,spring默认会使用JDK动态代理,依赖注入需要改成接口注入方式,AopContext.currentProxy 需要强转成接口,这时非接口方法就无法识别。

在spring中,如果bean没有实现接口,默认会采用CGLIB代理,代理类就是当前类的子类;如果bean实现了接口,spring默认会采用JDK动态代理,这个代理类实际是接口的实现类。JDK动态代理 是spring推荐的注入方式,因为他遵循了面向接口编程的模式,开发中更加灵活。下面的代码中可以看到两种代理在依赖注入时的区别。

构建一个接口

public interface ITransactionService {
public void outTransaction();
public void innerTransaction();
}

构建一个接口实现

@Service
public class TransactionService implements ITransactionService{
@Transactional
public void outTransaction() {
System.out.println("*******************outTransaction start****************");
((ITransactionService) AopContext.currentProxy()).innerTransaction();
System.out.println("*******************outTransaction end****************");
// throw new NullPointerException("报错啦");
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void innerTransaction() {
System.out.println("*************innerTransaction***********");
}
}

构建一个测试类

public class TransactionTest extends BaseTest {
//TransactionService 实现接口时如下注入
@Autowired
private ITransactionService transactionService;
//TransactionService 未实现接口如下注入
//@Autowired
//private ITransactionService transactionService;
@Test
public void outTransaction(){
transactionService.outTransaction();
}
}

但是实际开发中,偶尔需要打破这种模式,如果 ITransactionService 接口中并不包含innerTransaction 方法,AopContext.currentProxy 将无法获取该方法。幸好spring 支持通过aop:config 强制使用CGLIB ,这样就解决了AopContext.currentProxy 获取不到非接口函数的问题。

aop:config proxy-target-class 设置为true

<aop:config expose-proxy="true" proxy-target-class="true" />

修改注入方式

public class TransactionTest extends BaseTest {
@Autowired
private TransactionService transactionService;
@Test
public void outTransaction(){
transactionService.outTransaction();
}
}

修改AopContext.currentProxy强制类型指向实现类

((TransactionService) AopContext.currentProxy()).innerTransaction();​​​​​​​

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值