@Async失效及Spring循环依赖报错问题分析

今日写代码发现了@Async注解的方法放在@Service的类中,不能异步执行。于是排查找了下原因。我是直接在类中定义了一个异步方法。然后直接在该类中的其他方法调用。

问题分析:

跟spring注册bean的过程有很大关系,首先调用这个方法如果不是静态类的,肯定是有个隐式对象去调用。在这个类中(命名为A,实例对象为a)。则应该是a.issueRecharge()方法调用,这里的a其实就是spring管理的一个bean。相当于A类在spring容器初始化加载在设置属性是要把a设置进去,自己依赖自己就是循环依赖。在依赖的过程中,像@Async,@Transation都是基于动态代理实现的。在实例化时第一次实例a,应该已经在3级缓存中已存在。但没产出最终的原始对象。在进行动态代理实例代理对象时,发现容器已经暴露了实例a的一个对象。那么这个代理对象就会创建不成功。最终拿到的a就是A的原始对象,所以@Async修饰的方法相当于一个普通方法,用的是a的原始对象。没有被spring代理去管控。

 

解决方案:

将这种异步方法封装成一个新的类。重新作为一个bean进行管理。

 

改造封装成B类后再进行依赖注入,此时应该是

A{

B b;

B{

A,a;

}

问题分析:

发现这时出现了循环依赖的报错。按理说是spring是通过三级缓存默认解决了这类问题。出现问题的原因还是关于代理对象的创建。非最终版本的classA被注入到了循环依赖的classB。所以当出现动态代理而又出现循环依赖的时候,要注意这种情况。通过懒加载方法实例化bean,在一个完成实例注册成功就会去拿到最终版本的bean。

 

解决方案:

在引入的bean加上@Lazy注解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值