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);

过程,分三步

  1. A 创建过程中需要 B,于是 A 将自己放到三级缓里面,去实例化 B
  2. B 实例化的时候发现需要 A,于是 B 先查一级缓存,没有,再查二级缓存,还是没有,再查三级缓存,找到了 A,然后把三级缓存里面的这个 A 放到二级缓存里面,并删除三级缓存里面的 A
  3. 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;

 


https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-dependency-resolution

https://blog.csdn.net/f641385712/article/details/92801300

posted @ 2021-02-22 00:50  江湖小小白  阅读(361)  评论(0编辑  收藏  举报