AsyncAnnotationBeanPostProcessor
回顾
上篇文章,我们正在走robotServiceImpl
的生命周期,走到属性注入的时候,发现容器中没有taskServiceImpl
,于是去创建taskServiceImpl
,那就要走taskServiceImpl
的生命周期。
taskServiceImpl
实例化后也要属性注入robotServiceImpl
,发现容器中也没有,那就再去创建robotServiceImpl
,创建过程中发现robotServiceImpl
在singletonsCurrentlyInCreation
这样一个集合中,于是就从singletonFactories
取出来,因为刚开始创建robotServiceImpl
的时候我们有put
到这个map中:
时机是robotServiceImpl
实例化后提前暴露。
现在taskServiceImpl
的属性注入算是完成了,那就走初始化方法。
AsyncAnnotationBeanPostProcessor
我们只关注一个bpp,就那是AsyncAnnotationBeanPostProcessor
。
他先问我们的bean是不是被增强过,显然没有。
然后他要检查你bean的合法性。
我们在创建AsyncAnnotationBeanPostProcessor
的时候new了一个AysncAnnotationAdvisor
,并将其作为AsyncAnnotationBeanPostProcessor
的advisor
。
大概意思就是他循环你taskServiceImpl
的一个个方法,看你有没有@Aysnc
注解。
最终isEligible
返回的是true
。
接下来就是aop代理生成的部分,我们不管。
只需要知道他最后返回一个代理就行了。
一路返回出去,在真正return之前,再做一些事情:
将taskServiceImpl
从singletonsCurrentlyInCreation
中移除。
在singletonObjects
和registeredSingletons
中添加taskServiceImpl
。
并把taskServiceImpl
从singletonFactories
和earlySingletonObjects
中移除。
一路返回,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
:
相当于是说,我们给RobotServiceImpl
的TaskServiceImpl
一开始是原生的,后来又做了代理,人家拿到的TaskServiceImpl
变了。
那么我们就要研究dependentBeanMap
这个东西是在哪里维护的。