接上文中对调用点A和调用点B的调用方法进行了陈述。接下来,针对创建bean的不同顺序对调用点和调用方法进行分析。
在正常的情况下,调用顺序如下:以下有无,表示是否持有对指定Bean的引用
singletonFactories | earlySingletonObjects | singletonObjects | |
getSingleton(beanName, true) | 无 | 无 | 无 |
doCreateBean(beanName,mdb,args) | 有 | 无 | 无 |
getSingleton(beanName, true); | 有 | 无 | 无 |
addSingleton(beanName, singletonObject) | 无 | 无 | 有 |
但是出现循环引用之后呢,就会出现这种情况:
singletonFactories | earlySingletonObjects | singletonObjects | |
getSingleton(A, true); | A无B无 | A无B无 | A无B无 |
doCreateBean(A,mdb,args) | A有B无 | A无B无 | A无B无 |
populateBean(A, mbd, instanceWrapper) 解析B…… | |||
getSingleton(B, true) | A有B无 | A无B无 | A无B无 |
doCreateBean(B,mdb,args) | A有B有 | A无B无 | A无B无 |
populateBean(B, mbd, instanceWrapper)由B准备解析A…… | |||
getSingleton(A, true) | A无B有 | A有B无 | A无B无 |
完成populateBean(B, mbd, instanceWrapper)解析…… | |||
addSingleton(B, singletonObject) | A无B无 | A有B无 | A无B有 |
完成populateBean(A, mbd, instanceWrapper) | |||
A- = initializeBean(beanName, exposedObject, mbd)在initializeBean之后A变为A- | |||
getSingleton(A, false);验证 | |||
addSingleton(A, singletonObject) …… |
在上面这个过程中,在对A进行验证时,就会从earlySingletonObjects中取得一个A,但是这个A和后面的A-可能不是同一个对象,这是因为有了beanPostProcessor存在,它可以改变bean的最终值,比如对原始bean进行封装,代理等。在这个过程中,出现了3个对象A,A-,B,而B中所持有的A对象为原始的A。如果这里的A和A-不是同一个对象,即产生了beanA有了beanB的引用,但beanB并没有beanA的引用,而是另一个beanA的引用。这肯定不满足条件。