Spring lazy-Init 延迟加载原理和循环依赖问题处理

延迟加载

Spring在启动时,默认是将所有的singleton bean提前实例化,如果设置了lazy-init=”ture”的话,就可以设置这个bean在ApplicationContext启动服务器时不被实例化,在调用他的getBean索取bean时进行实例化,实现延迟加载。这么设置的目的是对不常用的bean设置延迟加载,避免一开始启动服务器占用资源。

延迟加载原理

Spring  lazy-Init 延迟加载原理和循环依赖问题处理
通过源码分析,在bean创建过程中中间环节有一个非抽象,非单例,非延迟加载的判断。如果是延迟加载就直接不处理,就不会完成该bean的创建。

循环依赖问题

循环依赖其实就是循环引⽤,也就是两个或者两个以上的 Bean 互相持有对⽅,最终形成闭环。⽐如A依赖于B,B依赖于C,C⼜依赖于A。注意,这⾥不是函数的循环调⽤,是对象的相互依赖关系。
场景:
构造器的循环依赖(构造器注⼊)
Field 属性的循环依赖(set注⼊)
其中,构造器的循环依赖问题⽆法解决,因为构造函数里面必须要有东西,但是根本没法完成A的实例化放入缓存中,只能拋出 BeanCurrentlyInCreationException 异常。在解决属性循环依赖时,spring采⽤的是提前暴露对象的⽅法。

Spring如何解决

假设Bean A 和Bean B 互相依赖,产生了循环依赖问题,那么Spring在Bean A在实例化后会将它放入三级缓存中,并且扩展后放入二级缓存。接着B创建的时候,会发现他依赖A,然后依次从一级缓存,二级缓存,三级缓存中查找实例化的依赖对象,找到后就拿来完成Bean B的装配并放入一级缓存中,接着删除二级缓存,三级缓存中的对象,而Bean A此时还没创建完成,就会直接从一级缓存中拿到Bean B来使用,解决了循环依赖问题。

上一篇:【洛谷P5305】旧词


下一篇:[数据结构入门]线段树plus - 区间乘法