网站开发自适应,福建建筑人才网档案关联,上海企业信息查询系统官网,软文广告示范什么是循环依赖
注册一个bean对象的过程#xff1a; Spring扫描class得到BeanDefinition – 根据得到的BeanDefinition去生成bean – 现根据class推断构造方法 – 根据推断出来的构造方法#xff0c;反射#xff0c;得到一个对象 – 填充初始对象中的属性(依赖注入) – 如果…什么是循环依赖
注册一个bean对象的过程 Spring扫描class得到BeanDefinition – 根据得到的BeanDefinition去生成bean – 现根据class推断构造方法 – 根据推断出来的构造方法反射得到一个对象 – 填充初始对象中的属性(依赖注入) – 如果原始对象种的某个方法被AOP了那么要根据原始对象生成一个代理对象 – 把最终生成的代理对象放入单例池(singletonObjects也叫一级缓存)中下次getBea你就直接从单例池拿
循环依赖就是在依赖注入的时候相互注入如
public class AService{Autowiredprivate BService bService;
}
public class BService{Autowiredprivate AService aService;
}三级缓存过程
Spring使用了三级缓存的策略来解决循环依赖问题过程大致如下 创建AService的bean 因为暂时还没有BService所以创建个BService 创建过程中因为AService已经在三级缓存中出现过所以会进行以下操作 因为BService的属性都已经赋值了所以BService的初始化就结束了可以直接放到一级缓存中完整过程为 此时BService已经实例化完成那么AService中的依赖就可以进行注入了 完整流程图如下
简单的源码解析
首先在AbstractAutowireCapabaleBeanFactory类里(我是用ctrlshiftaltn找到的)的doCreateBean 先创造了一个bean原始对象此时还没有依赖注入 BeanWrapper instanceWrapper null;if (mbd.isSingleton()) {instanceWrapper (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper null) {instanceWrapper this.createBeanInstance(beanName, mbd, args);}Object bean instanceWrapper.getWrappedInstance();然后将lambda表达式放入三级缓存中 if (earlySingletonExposure) {if (this.logger.isTraceEnabled()) {this.logger.trace(Eagerly caching bean beanName to allow for resolving potential circular references);}//放入三级缓存这个lambda表达式是为了执行aop生成代理对象用的如果有aop操作就会拿到代理对象出来this.addSingletonFactory(beanName, () - {return this.getEarlyBeanReference(beanName, mbd, bean);});}紧接着就是A的依赖填充 this.populateBean(beanName, mbd, instanceWrapper);在这个里面会走到一个getSingleton方法,也就是在缓存中找BService //allowEarlyReference是是否允许循环依赖Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {Object singletonObject this.singletonObjects.get(beanName);if (singletonObject null this.isSingletonCurrentlyInCreation(beanName)) {singletonObject this.earlySingletonObjects.get(beanName);if (singletonObject null allowEarlyReference) {synchronized(this.singletonObjects) {//一级缓存中找singletonObject this.singletonObjects.get(beanName);if (singletonObject null) {//二级缓存中找singletonObject this.earlySingletonObjects.get(beanName);if (singletonObject null) {//三级缓存中找ObjectFactory? singletonFactory (ObjectFactory)this.singletonFactories.get(beanName);if (singletonFactory ! null) { //找到了//这里相当于上面图文分析中BService在三级缓存中找到AService//直接用lambda表达式注册然后把他移动到二级缓存中singletonObject singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}}}return singletonObject;}
但是显然AService肯定不会找到然后就会重新走到createBean创建一个BService与A一样走到上述的getSingleton这时会在三级缓存中找到A然后注入
填充完成之后就会把BService放到一级缓存中,移除三级缓存中的B然后结束 exposedObject this.initializeBean(beanName, exposedObject, mbd);执行完整个BService的创建上面的A的依赖填充才会结束然后A也执行一遍exposedObject this.initializeBean(beanName, exposedObject, mbd);这行代码A也结束。
结合图文演示看代码更容易理解捏