@Async注解引发的报错之AsyncAnnotationBeanPostProcessor

AsyncAnnotationBeanPostProcessor

回顾

上篇文章,我们正在走robotServiceImpl的生命周期,走到属性注入的时候,发现容器中没有taskServiceImpl,于是去创建taskServiceImpl,那就要走taskServiceImpl的生命周期。

taskServiceImpl实例化后也要属性注入robotServiceImpl,发现容器中也没有,那就再去创建robotServiceImpl,创建过程中发现robotServiceImplsingletonsCurrentlyInCreation这样一个集合中,于是就从singletonFactories取出来,因为刚开始创建robotServiceImpl的时候我们有put到这个map中:

在这里插入图片描述
在这里插入图片描述

时机是robotServiceImpl实例化后提前暴露。

现在taskServiceImpl的属性注入算是完成了,那就走初始化方法。

AsyncAnnotationBeanPostProcessor

在这里插入图片描述
我们只关注一个bpp,就那是AsyncAnnotationBeanPostProcessor

在这里插入图片描述
他先问我们的bean是不是被增强过,显然没有。

然后他要检查你bean的合法性。

在这里插入图片描述
我们在创建AsyncAnnotationBeanPostProcessor的时候new了一个AysncAnnotationAdvisor,并将其作为AsyncAnnotationBeanPostProcessoradvisor

在这里插入图片描述

大概意思就是他循环你taskServiceImpl的一个个方法,看你有没有@Aysnc注解。

在这里插入图片描述
最终isEligible返回的是true

接下来就是aop代理生成的部分,我们不管。

在这里插入图片描述
只需要知道他最后返回一个代理就行了。

在这里插入图片描述
一路返回出去,在真正return之前,再做一些事情:

在这里插入图片描述
taskServiceImplsingletonsCurrentlyInCreation中移除。

在这里插入图片描述
singletonObjectsregisteredSingletons中添加taskServiceImpl

并把taskServiceImplsingletonFactoriesearlySingletonObjects中移除。

在这里插入图片描述
一路返回,taskServiceImpl的生命周期走完了。

那么就要回到robotServiceImpl了。别忘了我们是在给robotServiceImpl完成属性注入的时候才去实例化taskServiceImpl的。

然后robotServiceImpl地属性注入也完成。

然后,然后就没有报错。

WTF!

原来,我把controller给干掉了:

在这里插入图片描述
再次打开后,我看了一下报错:

Error creating bean with name 'taskController'
Unsatisfied dependency expressed through field 'taskService'
...

原来是创建controller的时候报的错。我原本以为循环依赖加上@Async注解就会出问题。

现在要重新debug了。

重新梳理

那么一切从TaskController开始:

在这里插入图片描述

我们最好再看看依赖关系:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
我们可以这么去猜测:创建TaskController的时候发现容器中没有TaskServiceImpl,然后去创建TaskServiceImpl,创建TaskServiceImpl的过程中发现容器中没有RobotServiceImpl,然后去创建RobotServiceImpl,创建RobotServiceImpl又要去容器中找TaskServiceImpl

可是,容器中有TaskServiceImpl吗?显然没有,但是他正在创建,所以,我们还是可以拿出来:

在这里插入图片描述

那此时我们拿出来的TaskServiceImpl是怎么样的呢?

在这里插入图片描述

还是他的raw version

在这里插入图片描述
然后RobotServiceImpl完成属性注入。

在这里插入图片描述
然后RobotServiceImpl加入到容器中。

在这里插入图片描述
此时,轮到TaskServiceImpl完成属性注入了,一切都和RobotServiceImpl一样。

在这里插入图片描述
但是,在TaskServiceImpl的初始化过程中,我们知道他被AsyncAnnotationBeanPostProcessor搞成了代理对象:

在这里插入图片描述
然后,然后就报错了:

在这里插入图片描述
我们的TaskServiceImpl确实是做过代理了,所以要走else if。我们不考虑allowRawInjectionDespiteWrapping这个字段的维护,报错的原因是dependentBeanMap有值,值是RobotServiceImpl

在这里插入图片描述
相当于是说,我们给RobotServiceImplTaskServiceImpl一开始是原生的,后来又做了代理,人家拿到的TaskServiceImpl变了。

那么我们就要研究dependentBeanMap这个东西是在哪里维护的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值