多个对象之间互相引用形成环
如果使用普通new方法创建,对象之间会循环创建导致OOM
在创建对象时会按照:一级--->二级--->三级的顺序尝试获取对象
对于ClassPathXmlApplicationContext获取bean对象,前置有一系列方法初始化容器、定义BeanFactoryPostProcess、国际化、多播器等的准备工作。
核心对象创建对象方法:
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
堆栈信息:
之后将会循环遍历需要创建bean对象的列表,调用getBean方法
尝试从三级缓存中获取:
获取不到,只能创建对象:
将会调用lambda表达式中的createBean进行对象的创建
到此对象已经实例化完成,需要进行初始化,不过在调用populateBeanff初始化前,将调用addSingletonFactory方法将包含自身实例的objectFactory放入第三级缓存中。
具体的实现方法:
为了解决依赖的对象不存在的问题,同样是依靠getBean方法解决
不过这一次,在第三级缓存中可以获取到循环依赖的对象(假设是两个对象之间循环依赖,开始创建的是A对象,目前创建的是B对象,此时B对象可以从第三级缓存中获取到实例化的A对象,直接装配到B对象中)
此时获取到只实例化的A对象后,将第三级缓存中的A对象移除,放到二级缓存中,值得注意的是B对象在初始化前也会将自己放入三级缓存中,由于自身的依赖已经解决,B对象在getSingleton方法返回前又会将自己的从三级缓存中删除放到一级缓存中。
至此B对象已经初始化完成,只需将属性注入到A中即可,而A对象被初始化完成之后也会将自己从二三级缓存中删除,放入到一级缓存中,至此A对象创建完成。
在for循环遍历下一个需要创建的Bean时,会直接从缓存中获取,不需要再实例化、初始化。
整个过程的堆栈信息:
流程图:
原文:https://www.cnblogs.com/kmchen/p/14897410.html