接上文中对调用点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的引用。这肯定不满足条件。