Bean创建过程中的循环依赖的解决
准备
- 2个互相依赖的类。外加一个容器。
- 调用AbstractBeanFactory中的doGetBean,执行到getSingleton(beanName)方法,发现没有获取到。
getSingleton方法如下:
- 调用AbstractBeanFactory中的doGetBean,执行到getSingleton(beanName,ObjectFactory)方法,进行implA的创建。
- 进入了DeafultSingletonBeanRegistry的getSingleton(beanName,ObjectFactory)方法,执行到beforeSingletonCreation(beanName),将此bean设置为正在创建中
- 接着执行singletonFactory.getObject()。
- singletonFactory.getObject()内部执行的是AbstractAutowireCapableBeanFactory的createBean方法,现在执行到了doCreateBean(beanName, mbdToUse, args)。
- 然后又来到了AbstractAutowireCapableBeanFactory的doCreateBean方法,使用instanceWrapper = createBeanInstance(beanName, mbd, args);实例化了一个包装了implA的BeanWrapper,BeanWrapper是bean的一个包装类,可以更方便的给属性赋值。再调用instanceWrapper.getWrappedInstance();就能得到内部包装的implA。
- 经过此步骤后,implA就以及创建好了,只不过现在字段b还未null。
- 再执行下去,发现此bean是单例的允许获得早期对象的正在创建中的bean,就把现在的这个implA放到三级缓存中,可以用于解决循环依赖
- 继续执行下去,就到了填充implA的属性的时候了。
- 然后运行到AbstractAutowireCapableBeanFactory的populateBean方法,虽然前面进行了一些奇怪的postprocessor处理,但是我的bean好像并没有变得奇怪起来。然后就运行到了遍历执行InstantiationAwareBeanPostProcessor的时候了。属性的注入就是在这里进行的。
- 之后会执行到AutowiredAnnotationBeanPostProcessor的postProcessProperties方法的metadata.inject(bean, beanName, pvs)这一步,metadata.inject(bean, beanName, pvs)就是专门管autowired注入的。
- 然后在注入的时候,发现implA依赖implB,就去创建implB。
- 然后就和implA的创建过程差不多,然后又运行到了注入那一步。
- 然后在注入过程中,implB需要implA,肯定要调用getSingleton,然后就在getSingleton打了断点,然后跳了很多次,就跳到了使用第三级缓存的地方。此时就获取到了早期的implA。然后implB再注入了早期的implA后再经过一些步骤就被放入了一级缓存。
- 此时方法调用栈返回到implA再继续前面的注入方法的时候,此时就能注入implB了。然后implA就又被放入到了一级缓存,bean的创建过程就完成了。
- 此时循环依赖就解决完成了。a中有b,a中的b又有a,就像套娃一样。