那么大家为什么会经常提到spring循环依赖呢,我认为主要有两个原因:
spring的核心思想同样是:先实例化,后设置属性。它内部维护了三个map,就是网上常说的三级缓存。
一个是 singletonObjects map ,也就是我们说的单例池,它存放的是已经完成实例化的完成的bean;
一个是 singletonFactories map,二级缓存,它是解决循环依赖的关键,也就是存放未完全创建的对象工厂ObjectFactory
,它持有原对象的引用;
一个是 earlySingletonObjects map,三级缓存,它是存放经过ObjectFactory.getObject
,生成的早期单例对象存在这个map中,这里面的对象可能是个代理类。
singletonFactories 、 earlySingletonObjects
注:很多文章会称 singletonFactories 为三级缓存, earlySingletonObjects 为二级缓存,这里其实没有谁对谁错,只是个叫法,不用纠结。
说明:原型(Prototype)的场景、通过构造方法进行依赖注入,这两种情况循环依赖都没有解决
spring的解决循环依赖的大概过程
创建A,先把A通过构造方法反射实例化得到一个空的对象,然后根据是否单例,是否允许循环引用,如果是的话,包装一个 ObjectFactory 对象,加到 singletonFactories map中,然后进行A的属性设置,这时候发现A的属性B还没创建,转而先去创建B,同样的,先把B加到 singletonFactories map中,设置B的属性的时候,发现A还没创建,又转而去创建A,此时A已经在 singletonFactories ,然后调用A的ObjectFactory
中的getObject
方法,获取A的早期引用(生成的可能是个代理对象,此时A还没实例完全,属性还没设置),然后会把A转移到earlySingletonObjects
为什么第二级缓存要使用ObjectFactory?
为了这个bean能够被一些beanPostProcessor处理,使其能够创建为代理对象。
三级缓存earlySingletonObjects
的作用是什么?
存储ObjectFactory.getObject()
之后生成的半成品对象(这个对象只是原本的实例化,或者代理对象,没有经历过属性注入与初始化过程),用于保存真实的对象引用,因为真正要放到单例池中的对象可能是个代理对象。
postProcessAfterInitialization也可以生成代理,ObjectFactory.getObject()生成代理后,再执行postProcessAfterInitialization,岂不是会执行两遍生成代理流程?
debug发现,ObjectFactory.getObject()返回的确实是代理对象(如果需要的话),后续在执行postProcessAfterInitialization的时候,会有个earlyProxyReferences
的判断,直接返回原对象,在后面流程中,会从earlySingletonObjects
中取代理后的对象,放到单例池中。
- 如果A不需要生成代理对象,那么关系就是 A->B->A->B....,形成循环依赖
关键源码:
注:只列出与循环依赖相关的关键代码
// org.springframework.beans.factory.support.AbstractBeanFactory protected <T> T doGetBean( String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { // 获取单例bean,首次进来为null Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { ... } else { ... // Create bean instance. if (mbd.isSingleton()) { // 获取单例对象,没有则执行创建,第二个参数为ObjectFactory sharedInstance = getSingleton(beanName, () -> { try { // 创建bean return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); } } }
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { ... if (instanceWrapper == null) { // 实例化bean instanceWrapper = createBeanInstance(beanName, mbd, args); } ... // 是否单例,是否可以循环引用,是否是正在创建中的单例对象 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { // 提前暴露工厂对象,将ObjectFactory添加到singletonFactories中 // getEarlyBeanReference返回的对象会经过一些BeanPostProcessor的处理,可能生成对应的代理对象,如果不需要代理,则基本都是原对象 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } ... // 属性注入,如果发现有依赖的bean,并且未创建,回去先创建依赖的bean populateBean(beanName, mbd, instanceWrapper); // 初始化回调流程 exposedObject = initializeBean(beanName, exposedObject, mbd); ... if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) // 这个地方会把原对象,替换成代理对象 exposedObject = earlySingletonReference; } } }
// org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator // 上面的getEarlyBeanReference方法中调用的 @Override public Object getEarlyBeanReference(Object bean, String beanName) { Object cacheKey = getCacheKey(bean.getClass(), beanName); this.earlyProxyReferences.put(cacheKey, bean); return wrapIfNecessary(bean, beanName, cacheKey); } // bean生命周期中initializeBean方法中的流程,一般AOP代理也在这边生成 @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); // 代理对象的话,这边不会进入if if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { /**(一级缓存)已经完成加载的单例缓存.*/ private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); /**(三级缓存)早期的单例对象缓存集合. 存储二级缓存加工过的对象,此时该Bean还未构建完成 */ private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); /**(二级缓存)单例的工厂Bean缓存集合. */ private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { ... singletonObject = singletonFactory.getObject(); newSingleton = true; ... if (newSingleton) { // 添加到单例池中 addSingleton(beanName, singletonObject); } } // 加到二级缓存 protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null"); synchronized (this.singletonObjects) { if (!this.singletonObjects.containsKey(beanName)) { this.singletonFactories.put(beanName, singletonFactory); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } } ...... // 注:高版本的spring,这个方法会稍有不同(有double check的逻辑),思路是一样的 protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; } }