Spring解决Bean的循环依赖源码分析

循环依赖

PDF流程图
链接: https://pan.baidu.com/s/1lbf8rUF13VJer7tVwP3NIQ 提取码: 4kw2

基于2.4.5分析

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.10</version>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.4.5</version>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    <version>2.4.5</version>
  </dependency>
</dependencies>

jpg:


spring循环依赖.jpg

测试代码
class A

package org.neosoft.circle;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

@Service
@Lazy
public class A {
    @Autowired
    B b;

    public void sayHelloA() {
        System.out.println("testA");
    }

    @Value("${name}")
    String name;
    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }
}

class B

package org.neosoft.circle;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

@Service
//第一次使用bean的时候才加载
@Lazy
public class B {
    @Autowired
    A a;

    /**
     * 添加一个方法,才会触发动态代理
     */
    public void sayHello(){
        System.out.println("testB");
    }


    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }
}

AOP代理类

package org.neosoft.circle;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyAspect {

    @Before("execution(* org.neosoft.circle.*.*(..))")
    public void before1(){
        System.out.println("前置通知");
    }
}

测试入口

package org.neosoft.circle;

import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@ComponentScan
@EnableAspectJAutoProxy
public class CircleDependencyTest {

    @Test
    public void test() {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CircleDependencyTest.class);
        A a = context.getBean(A.class);
        System.out.println(a.getClass());
    }
}

整体执行顺序

// 第一次获取bean
1. AbstractBeanFactory#doGetBean("a")
// 从单例池singletonObjects中获取,没有并且bean在创建中才从半成品池earlySingletonObjects获取,
// 最后bean在创建中并且允许早期引用allowEarlyReference,
// 才从单例工厂singletonFactories创建(singletonFactory.getObject()),
// 实际调用的是AbstractAutowireCapableBeanFactory#doCreateBean
// {addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));},getEarlyBeanReference方法
2. DefaultSingletonBeanRegistry#getSingleton("a", true)
3. 获取到bean则执行后置处理getObjectForBeanInstance,与bean创建/循环依赖无关
4. 2未获取到,则进入DefaultSingletonBeanRegistry#getSingleton("a",() -> {createBean(beanName, mbd, args)}),
   实际的createBean是AbstractAutowireCapableBeanFactory#createBean("bean")
    4.1 AbstractAutowireCapableBeanFactory#doCreateBean("a")
    4.2 创建bean实例AbstractAutowireCapableBeanFactory#createBeanInstance
    4.3 如果是提前暴露earlySingletonExposure,则加入单例工厂
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    4.4 populateBean("a")填充属性
        4.4.1 Autowired填充B的时候,触发getBean("b")AutowiredAnnotationBeanPostProcessor#postProcessProperties
        4.4.2 b再次走一遍1,2,3,4,4.1,4.2,4.3,4.4,4.4.1,b填充属性填充到a的时候,此时单例工厂已经有了a和b,
              所以此时,通过单例工厂创建了代理的a,并填充到b的a属性中。同时把a加入到半成品池。
        4.4.3 b走4.5,完成bean的初始化
        4.4.4 b走4.6,如果earlySingletonExposure为true,则继续从单例池,半成品池,单例工厂池获取bean,
              因为此时allowEarlyReference为false,所以只从单例池和半成品池获取bean。而b并不在单例池和半成品池
              (只有通过lambda创建的对象才放入半成品池),所以返回null,最终返回代理的b。
        4.4.5 b完成5,6,之后回到a的调用链。即回到4.4,完成a的b属性填充,把代理后的b放到a的属性b中,然后进入4.5。
    4.5 initializeBean("a")初始化bean
    4.6 完成a的初始化之后,判断earlySingletonExposure,为true,继续getSingleton("a", false);
        由于在b的填充属性时,完成了a的代理创建,此时代理的a在半成品池中,所以获取到代理后的a。
        而4.5初始化后的a是未代理的(因为earlyProxyReferences里包含了a,所以不需要对a进行包装),
        与4.2创建的a相等,所以此时返回代理后的a。
5. 同样4bean创建成功后执行getObjectForBeanInstance
6. 最后adaptBeanInstance

关键源码

  1. AbstractBeanFactory#doGetBean("a")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

        final String beanName = transformedBeanName(name);
        Object bean;

        // 快速检查单例池中是否存在
        // 1.singletonObjects单例池
        // 2.创建中的,earlySingletonObjects半成品池
        // 3.允许提前引用allowEarlyReference,从单例工厂池创建singletonFactory.getObject()
        //   AbstractAutowireCapableBeanFactory#doCreateBean
        //     addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        //   实际调用的是AbstractAutowireCapableBeanFactory#getEarlyBeanReference
        //   AbstractAutoProxyCreator#createProxy
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            // 辅助检查等等后置处理
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
        else {
                // Create bean instance.
                if (mbd.isSingleton()) {
                    // 1.beforeSingletonCreation
                    //  1.1.singletonsCurrentlyInCreation.add(beanName)标记bean创建中
                    // 2.singletonFactory.getObject()
                    //  2.1.AbstractAutowireCapableBeanFactory#createBean实际的创建方法
                    // 3.afterSingletonCreation
                    //  3.1.singletonsCurrentlyInCreation.remove(beanName)删除标记
                    // 4.addSingleton
                    //  4.1.this.singletonObjects.put(beanName, singletonObject);加入单例池
                    //  4.2.this.singletonFactories.remove(beanName);从单例工厂删除
                    //  4.3.this.earlySingletonObjects.remove(beanName);从半成品池删除
                    //  4.4.this.registeredSingletons.add(beanName);按顺序存放已注册的单例
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            // 实际调用的是 AbstractAutowireCapableBeanFactory#createBean
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                else if (mbd.isPrototype()) {
                }
                else {
                }
            }
        }
        return (T) bean;
    }
  1. DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)
@Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // 快速查询单例池
        Object singletonObject = this.singletonObjects.get(beanName);
        // 如果单例池里没有,并且bean在创建中,则从半成品池查询
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            singletonObject = this.earlySingletonObjects.get(beanName);
            // 如果半成品池没有并且允许提前引用,则从单例工厂创建
            if (singletonObject == null && allowEarlyReference) {
                synchronized (this.singletonObjects) {
                    // Consistent creation of early reference within full singleton lock
                    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) {
                                // 单例工厂创建,实际调用的是AbstractAutowireCapableBeanFactory#getEarlyBeanReference
                                singletonObject = singletonFactory.getObject();
                                // 放入半成品池
                                this.earlySingletonObjects.put(beanName, singletonObject);
                                this.singletonFactories.remove(beanName);
                            }
                        }
                    }
                }
            }
        }
        return singletonObject;
    }
  1. AbstractAutowireCapableBeanFactory#createBean("a")
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
            ……
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            ……
    }
  1. AbstractAutowireCapableBeanFactory#doCreateBean("a")
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
        ……
            // 创建bean实例
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        ……
        // 单例&&允许循环引用$$正在创建中(singletonsCurrentlyInCreation)
        // 提前暴露的单例
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            // 添加到单例工厂池
            // this.singletonFactories.put(beanName, singletonFactory);
            // this.earlySingletonObjects.remove(beanName);
            // this.registeredSingletons.add(beanName);
            // getEarlyBeanReference里this.earlyProxyReferences.put(cacheKey, bean)
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }
        ……
        try {
            // 填充属性
            // 实例使用的是Autowired,所以在遍历到b属性时,触发b的创建,见5.
            populateBean(beanName, mbd, instanceWrapper);
            // 初始化
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
        ……
        if (earlySingletonExposure) {
            // 此处B先进来,B在initializeBean时已经替换为代理对象,单例池&半成品池里没有,直接返回
            // A进来的时候,initializeBean时,exposedObject未代理,获取到原始对象
            Object earlySingletonReference = getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                // A进来后,A替换为工厂创建的代理对象
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                }
                ……
            }
        }

        // Register bean as disposable.
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        return exposedObject;
    }
  1. AbstractAutowireCapableBeanFactory#populateBean("a")
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        ……
        PropertyDescriptor[] filteredPds = null;
        if (hasInstAwareBpps) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
            for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
                // 此处遍历到 AutowiredAnnotationBeanPostProcessor#postProcessProperties时,会 doGetBean("b"),触发B的创建流程
                // B再次运行到此处的时候,触发doGetBean("a")
                // 此时,单例工厂池singletonFactories中有a和b的单例工厂(getEarlyBeanReference),创建了A的代理类,B的A属性也指向了A的代理类,这样B的属性填充完毕,进行下一步初始化AbstractAutowireCapableBeanFactory#initializeBean
                PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                if (pvsToUse == null) {
                    if (filteredPds == null) {
                        filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                    }
                    pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        return;
                    }
                }
                pvs = pvsToUse;
            }
        }
        ……
    }
  1. 递归到1,AbstractBeanFactory#doGetBean("b"),2("b"),3("b"),4("b"),5("b")
  2. AbstractAutowireCapableBeanFactory#initializeBean("b")
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        ……
            // 填充beanName
            invokeAwareMethods(beanName, bean);
        ……
            // 前置处理
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        ……
            // 初始化方法
            invokeInitMethods(beanName, wrappedBean, mbd);
        ……
            // 后置处理
            // 在后置处理中,判断是否需要AOP代理applyBeanPostProcessorsAfterInitialization
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        ……
        return wrappedBean;
    }
  1. AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization("b")
@Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            // AbstractAutoProxyCreator#postProcessAfterInitialization
            Object current = processor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }
  1. AbstractAutoProxyCreator#postProcessAfterInitialization("b")
@Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            // earlyProxyReferences 里不存在才包装
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                // 是否有必要包装
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }
  1. AbstractAutoProxyCreator#wrapIfNecessary("b")
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        ……
        // 判断是否有通知创建动态代理类
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            // 动态创建B
            Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }

        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

创建完成后返回3:AbstractAutowireCapableBeanFactory#doCreateBean,B的动态代理实例赋值给exposedObject,继续完成A的后续操作,initializeBean等,注意A是不需要包装的,A在earlyProxyReferences里。

动态代理封装

1. getEarlyBeanReference方式

1.1. 创建bean之前,通过lambda表达式放入单例工厂

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
           throws BeanCreationException {
           ……
           // 放入单例工厂
           addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
           ……
       }

1.2. 获取bean,DefaultSingletonBeanRegistry#getSingleton

@Nullable
   protected Object getSingleton(String beanName, boolean allowEarlyReference) {
                               ……
                               // 工厂创建[代理]bean
                               singletonObject = singletonFactory.getObject();
                               ……
   }

2. postProcessAfterInitialization方式

2.1. 初始化bean后置处理器中处理

@Override
   public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
           throws BeansException {

       Object result = existingBean;
       for (BeanPostProcessor processor : getBeanPostProcessors()) {
            // postProcessAfterInitialization入口
           Object current = processor.postProcessAfterInitialization(result, beanName);
           if (current == null) {
               return result;
           }
           result = current;
       }
       return result;
   }         

2.2. earlyProxyReferences存在bean,则包装

@Override
   public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
       if (bean != null) {
           Object cacheKey = getCacheKey(bean.getClass(), beanName);
            // earlyProxyReferences存在,进行bean的包装,即AOP处理
           if (this.earlyProxyReferences.remove(cacheKey) != bean) {
               return wrapIfNecessary(bean, beanName, cacheKey);
           }
       }
       return bean;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容