001. Spring 是如何解决循环依赖的?
答:
什么是循环依赖?
循环依赖指两个或多个 Bean 相互依赖(如 A 依赖 B,B 依赖 A)。
在创建A时,初始化A时需要注入B,那么就需要去创建B;
在创建B时,初始化B时需要注入A,那么就需要去创建A;
此时就形成了循环依赖(程序会死等),最终导致 Bean 创建失败。
如何解决循环依赖问题?
Spring 通过拆分Bean的创建过程,将实例化和初始化分开。
- 当创建A时,先实例化A,再对A进行初始化,此时发现需要注入实例B;
- Spring此时会将实例化但未完成初始化的A存到缓存中(此处引入三级缓存概念),此时的A是可以被引用的,但并不完整(因为没有完成初始化,b还没有注入);
- 此时Spring会去创建B,先实例化B,然后再对B进行初始化,此时发现需要注入实例A;
- 此时Spring会把存入缓存的A注入B中(虽然A未完成初始化,但是可以先行注入B,后面再完成A的初始化也是可以的),此时B就创建完成了;
- 当B的实例创建完成后,Spring会回到对A实例的初始化步骤来,将成功创建的B注入到A中,此时A也完成了初始化。
- 即此时完成了对A和B的实例化和初始化操作,成功解决了循环依赖的问题。
三级缓存是什么?如何被使用的?
这里存在三级缓存的概念,Spring寻找实例化好的bean时会按照一级、二级、三级的顺序依次查找。
注意:三级缓存中不会出现相同名称的bean,当上一级存入相同名称的bean时,下一级同名的bean会被自动删除。
一级缓存存放的是:实例化完成且初始化完成的实例;
二级缓存存放的是:实例化完成但初始化未完成的实例;
三级缓存存放的是:存放Bean 的工厂对象(ObjectFactory),用来生成早期的bean或其代理对象,同时保证三级缓存中不会出现同名的bean实例。

国内还是各种 java 招聘。
但是竞争更激烈了,就业环境也更难了。
今天刚失业,没办法,只能把八股文再拾起来了。
是的,挺难的。我也在写 java。