Spring Bean 循环依赖
创建 A 实例时需要 B,创建 B实例时需要 A。
测试环境:https://gitee.com/jhxxb/MySpringBoot/tree/master/Spring-Base/src/test/java/BeanCircularDependency
Spring IOC 中 Bean 的作用域有多种:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-scopes
默认 Bean 作用域为单例模式,Spring 解决循环依赖只能解决单例模式下的,无法解决多实例循环依赖,因为每次都需要 new,无法使用缓存
单例模式下也无法解决构造器方式注入的循环依赖,必须要有一个 Bean 不是构造器注入
总的来说 Spring 只能解决单例模式下的非构造器注入的循环依赖问题
注:Spring Boot 2.6.0 开始循环引用默认是被禁用的(只是 Spring Boot 默认禁止了,Spring Framework 默认还是允许)
# 可以配置开启 spring.main.allow-circular-references=true
前置知识
先清楚 Spring 中的两个概念
- 实例化:就是 new 一个对象
- 初始化:给 new 的对象设置属性
还需要了解下 Spring IOC 中的三级缓存,平常所说的 IOC 容器就是一个 ConcurrentHashMap
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { /** * 一级缓存,单例对象的缓存:bean名称-bean实例,存放生成好的单例 Bean */ private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); /** * 三级缓存,单例工厂的缓存:bean名称-ObjectFactory,存放生成 bean 的工厂 */ private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); /** * 二级缓存,早期的单例对象的缓存:bean名称-bean实例,存放实例化但未初始化(Bean 的属性还未填充)的单例 bean */ private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
过程,分三步
- A 创建过程中需要 B,于是 A 将自己放到三级缓里面,去实例化 B
- B 实例化的时候发现需要 A,于是 B 先查一级缓存,没有,再查二级缓存,还是没有,再查三级缓存,找到了 A,然后把三级缓存里面的这个 A 放到二级缓存里面,并删除三级缓存里面的 A
- B 顺利初始化完毕,将自己放到一级缓存里面(此时 B 里面的 A 依然是创建中状态),然后回来接着创建 A,此时 B 已经创建结束,A 直接从一级缓存里面拿到 B,然后 A 完成创建,并将 A 自己放到一级缓存里面。
源码(已删除部分影响阅读的代码,主要看处理流程)
从获取对象开始,开始创建 A 对象,其实就是 IOC 的初始化流程:https://www.cnblogs.com/jhxxb/p/13609289.html
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { @Override public void preInstantiateSingletons() throws BeansException { List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { // 是否为工厂 Bean } else { getBean(beanName); // 获取 Bean 对象 } } }
进入到 getBean(beanName) 获取 Bean
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { @Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } @SuppressWarnings("unchecked") protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // 没有获取到 A 对象,会进入到这里 if (isPrototypeCurrentlyInCreation(beanName)) { // 检查正在创建中的 Bean 是否包含 A,如果是那就抛异常(循环依赖) throw new BeanCurrentlyInCreationException(beanName); } try {// 是否有 Bean 需要在 A 之前创建 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { } if (mbd.isSingleton()) { // 创建单例模式 Bean sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // 创建原型模式 Bean } else { // 其它 scope 类型的处理 } } } return adaptBeanInstance(name, beanInstance, requiredType); } public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { @Override @Nullable public Object getSingleton(String beanName) { // 去容器中拿 Bean,有则直接返回 return getSingleton(beanName, true); } @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); // 获取单例 Bean if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { // 是否正在创建中 } return singletonObject; // A 没有创建过,直接到这里 } public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { beforeSingletonCreation(beanName); // singletonsCurrentlyInCreation 把它添加进去,证明这个 Bean 正在创建中 boolean newSingleton = false; try { singletonObject = singletonFactory.getObject(); // 创建 Bean newSingleton = true; } catch (IllegalStateException ex) { singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } finally { afterSingletonCreation(beanName); } if (newSingleton) { addSingleton(beanName, singletonObject); } } return singletonObject; } }
进入到 createBean(beanName, mbd, args) 开始创建 Bean
public abstract class AbstractAutowireCapableBeanFactory extends org.springframework.beans.factory.support.AbstractBeanFactory implements AutowireCapableBeanFactory { @Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { try { // 给 Bean 一个返回代理对象的机会 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } try { Object beanInstance = doCreateBean(beanName, mbdToUse, args); // 创建 Bean return beanInstance; } } protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); // 创建 Bean 实例 } boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { // 放入三级缓存 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } try { populateBean(beanName, mbd, instanceWrapper); // 属性填充,其中会实例化 B exposedObject = initializeBean(beanName, exposedObject, mbd); } return exposedObject; } @SuppressWarnings("deprecation") protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { if (hasInstAwareBpps) { for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { // 关于 postProcessPropertyValues 的实现,有几个处理器是非常关键的: // 如 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor 等 pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } } } public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware { @Deprecated @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) { return postProcessProperties(pvs, bean, beanName); } @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); try { metadata.inject(bean, beanName, pvs); } return pvs; } private class AutowiredFieldElement extends InjectedElement { @Override protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Field field = (Field) this.member; Object value; if (this.cached) { value = resolvedCachedArgument(beanName, this.cachedFieldValue); } else { try { value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); // 获取 B 对象 } } if (value != null) { ReflectionUtils.makeAccessible(field); field.set(bean, value); // 设置实例对象 A 的属性 B } } } } public class InjectionMetadata { public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Collection<InjectedElement> checkedElements = this.checkedElements; Collection<InjectedElement> elementsToIterate = (checkedElements != null ? checkedElements : this.injectedElements); if (!elementsToIterate.isEmpty()) { for (InjectedElement element : elementsToIterate) { element.inject(target, beanName, pvs); // AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement#inject } } } } public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { @Override @Nullable public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { if (Optional.class == descriptor.getDependencyType()) { } else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) { } else if (javaxInjectProviderClass == descriptor.getDependencyType()) { } else { Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName); if (result == null) { result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); // 解析依赖 B } return result; } } @Nullable public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { try { Object shortcut = descriptor.resolveShortcut(this); if (shortcut != null) { return shortcut; } if (instanceCandidate instanceof Class) { instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this); // 获取依赖的实例对象 } Object result = instanceCandidate; return result; } } } public class DependencyDescriptor extends InjectionPoint implements Serializable { public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) throws BeansException { return beanFactory.getBean(beanName); // 又回到了 getBean 方法获取实例 B } }
创建 B 实例时同样会走到 DependencyDescriptor#resolveCandidate 来又创建 A,看 Spring 是怎么处理的
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { @Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } @SuppressWarnings("unchecked") protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { String beanName = transformedBeanName(name); Object beanInstance; Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { // 可以获取到 A 对象 beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { } return adaptBeanInstance(name, beanInstance, requiredType); } public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { @Override @Nullable public Object getSingleton(String beanName) { // 去容器中拿 Bean,有则直接返回 return getSingleton(beanName, true); } @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); // 从一级缓存中获取单例 Bean if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { // 是否正在创建中 // 会进入到这里,A 确实是正在创建中 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 = this.singletonFactories.get(beanName); // 从三级缓存中获取,显然可以获取到 if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); // 获取未赋属性值的 A 对象 this.earlySingletonObjects.put(beanName, singletonObject); // 将 A 加入到二级缓存 this.singletonFactories.remove(beanName); // 把 A 从三级缓存中移除 } } } } } } return singletonObject; // 返回未赋属性值的 A 对象 }
继续看 B 对象的创建,它会在 A 对象之前创建出来
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { beforeSingletonCreation(beanName); // singletonsCurrentlyInCreation 把它添加进去,证明这个 Bean 正在创建中 boolean newSingleton = false; try { singletonObject = singletonFactory.getObject(); // 创建 B 对象完成 newSingleton = true; } finally { afterSingletonCreation(beanName); // 从 singletonsCurrentlyInCreation 中移除 } // 若是新创建的 Bean,那就执行 addSingleton 方法 if (newSingleton) { addSingleton(beanName, singletonObject); } } return singletonObject; } } protected void addSingleton(String beanName, Object singletonObject) { // Bean 彻底创建完成,添加进 singletonObjects synchronized (this.singletonObjects) { this.singletonObjects.put(beanName, singletonObject); // 把实例 B 放入一级缓存,B 直接从三级缓存到了一级缓存 this.singletonFactories.remove(beanName); // 从三级缓存中删除 this.earlySingletonObjects.remove(beanName); // 从二级缓存中删除 this.registeredSingletons.add(beanName); // 记录已经创建好的 Bean 的名称,有顺序 } }
之后 A 会像 B 一样被创建出来。
回到最开始,A 创建完后会继续创建 B,但这时就不会再走创建流程了,直接可以获取到 B
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { @Override public void preInstantiateSingletons() throws BeansException { List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { // 是否为工厂 Bean } else { getBean(beanName); // 可以直接获取到 B 对象,没有了后续的创建流程 } } }
Spring 中加入三级缓存的代码
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } } protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { // 从创建工厂中获取实例对象,会对 Bean 进行一些处理 Object exposedObject = bean; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) { exposedObject = bp.getEarlyBeanReference(exposedObject, beanName); } } return exposedObject; } public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) { synchronized (this.singletonObjects) { if (!this.singletonObjects.containsKey(beanName)) { this.singletonFactories.put(beanName, singletonFactory); // 加入三级缓存,是创建工厂,并非实例对象 this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } }
图示
关闭 Spring 的循环依赖
查看源码可以发现有一个 allowCircularReferences 属性可以控制
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { /** Whether to automatically try to resolve circular references between beans. */ private boolean allowCircularReferences = true;