# Spring Boot - IOC(四) - 循环依赖与解决方案

## 1. 编写测试代码

为演示循环依赖的效果，咱来编写两个组件，模拟人与猫的关系：人养猫，猫依赖人。

```java
@Component
public class Person {
    @Autowired
    Cat cat;
}

@Component
public class Cat {
    @Autowired
    Person person;
}
```

之后使用包扫描来启动IOC容器：

```java
public class App {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext("com.example.demo.component");
        String[] beanDefinitionNames = ctx.getBeanDefinitionNames();
        Stream.of(beanDefinitionNames).forEach(System.out::println);
    }
}
```

运行，发现可以正常打印cat和dog：

```kotlin
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
person
cat
```

下面来结合上一篇中的bean创建流程，分析IOC容器是如何解决循环依赖的。

【下面的源码不再使用通篇+描述，而是使用步骤来一步步描述过程，小伙伴要跟上思路来一起分析】

## 2. 流程全分析 - 初始化IOC容器

### 2.1 new AnnotationConfigApplicationContext

```java
public AnnotationConfigApplicationContext(String... basePackages) {
    this();
    scan(basePackages);
    refresh();
}
```

前面的创建和包扫描部分，会把Cat和Dog都读进 `BeanFactory` 。

下面的refresh方法：

### 2.2 refresh

```java
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// ......
			try {
				// ......
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);
				// ...
			}
             // ......
		}
	}
```

最终会调用到11步：**初始化剩余的单实例Bean**。

### 2.3 finishBeanFactoryInitialization

```java
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // ...
    
    // Instantiate all remaining (non-lazy-init) singletons.
    beanFactory.preInstantiateSingletons();
}
```

直接走到最后一步：`preInstantiateSingletons` ：

### 2.4 DefaultListableBeanFactory#preInstantiateSingletons

```java
public void preInstantiateSingletons() throws BeansException {
    // ......
    
    // Trigger initialization of all non-lazy singleton beans...
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {
                // ......
            }
            else {
                getBean(beanName);
            }
        }
    }
    
    // Trigger post-initialization callback for all applicable beans...
    // ......
}
```

到此为止，开始进行真正的Bean创建。

Debug中可以看到，由于Cat在Person之前，所以先来创建Cat：

## 3. 流程全分析 - 初始化Cat

由上面的 `getBean`，跳转到 `AbstractBeanFactory` 的 `getBean` 方法：

```java
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}
```

紧接着调 `doGetBean`：

### 3.1 doGetBean(cat)

```java
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
                          @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
    
    // ......
    
    // Create bean instance.
    if (mbd.isSingleton()) {
        sharedInstance = getSingleton(beanName, () -> {
            try {
                return createBean(beanName, mbd, args);
            }
            catch (BeansException ex) {
                // Explicitly remove instance from singleton cache: It might have been put there
                // eagerly by the creation process, to allow for circular reference resolution.
                // Also remove any beans that received a temporary reference to the bean.
                destroySingleton(beanName);
                throw ex;
            }
        });
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }
    
    // ......
    return (T) bean;
}
```

在Lambda表达式中要调用 `createBean` ，但在调用之前先看一眼 `getSingleton` 方法：

### 3.2 【重要】getSingleton

这个方法来自 `**DefaultSingletonBeanRegistry**` ，这个类中有几个很重要的概念，就是它的几个成员（这几个成员都有文档注释）：

* `**singletonObjects**`：一级缓存，存放**完全初始化好的Bean**的集合，从这个集合中取出来的Bean可以立马返回
* `**earlySingletonObjects**`**：二级缓存，存放创建好但没有初始化属性的Bean**的集合，它用来解决循环依赖
* `**singletonFactories**`：三级缓存，存放**单实例Bean工厂**的集合
* `**singletonsCurrentlyInCreation**`：存放**正在被创建的Bean**的集合

```java
/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

/** Names of beans that are currently in creation. */
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
```

这几个成员相当重要，下面会慢慢看见他们。下面是 `getSingleton` 方法：

```java
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    // ......
    // 标记当前bean
    beforeSingletonCreation(beanName);
    // .....
    try {
        // 创建Bean
        singletonObject = singletonFactory.getObject();
        newSingleton = true;
    }
    // ......
}
```

`beforeSingletonCreation` 方法咱之前看过了：

```java
protected void beforeSingletonCreation(String beanName) {
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
        throw new BeanCurrentlyInCreationException(beanName);
    }
}
```

它把当前的 **cat** 放入 `singletonsCurrentlyInCreation` \*\*（正在创建的Bean）\*\*中。

接下来准备调用 `singletonFactory.getObject()` ，也就是调用下面的 `createBean` 方法：

### 3.3 createBean(cat)

```java
// AbstractAutowireCapableBeanFactory
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {
    
    // ......
    try {
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }
    // ......
}
```

最终调到 `doCreateBean` 方法：

### 3.4 doCreateBean(cat) & createBeanInstance

```java
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {
    // ......
    // 创建Bean实例
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // ......
    
    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                                      isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName +
                         "' to allow for resolving potential circular references");
        }
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }
    
    // ......
    Object exposedObject = bean;
    try {
        // 属性赋值&自动注入
        populateBean(beanName, mbd, instanceWrapper);
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    //......
    return exposedObject;
}
```

Bean的实例化过程咱就不看了，当 `createBeanInstance` 方法运行完后，此时的cat中：

![img](https://cdn.nlark.com/yuque/0/2022/png/229542/1661695488849-918d250a-8387-402d-9f95-c27538468de1.png)

此时：这个cat被称为 **“早期Bean”** ，而且被包装为 `BeanWrapper` 。

继续往下走，中间有一个非常关键的步骤：`earlySingletonExposure` 的判断。

```java
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {
    // ......
    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                                      isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName +
                         "' to allow for resolving potential circular references");
        }
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }
    // ......
}
```

### 3.5 earlySingletonExposure的判断 & addSingletonFactory

这个判断非常关键，它要同时成立三个条件才能进if结构：

* 这个Bean是一个单实例Bean
* IOC容器允许循环依赖（默认是true）
* 正在创建的单实例Bean对象中有当前的这个Bean

由于在3.2环节中，`singletonsCurrentlyInCreation` 这个集合中已经把 **cat** 放进去了，此时这个判断也为**true**。

三个条件全为true，进入if结构中，它干了这么一件事：

```
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
```

来看 `addSingletonFactory` 的源码：

```java
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);
        }
    }
}
```

这一步的动作可以看出来，是**将当前正在创建的Bean保存到三级缓存中，并从二级缓存中移除**（由于本来二级缓存中没有，故可以只认定为放入三级缓存）。

***

下面的属性赋值&自动注入点：

```java
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {
    // ......
    try {
        // 属性赋值&自动注入
        populateBean(beanName, mbd, instanceWrapper);
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    //......
    return exposedObject;
}
```

### 3.6 populateBean(cat)

```java
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    // ......
    PropertyDescriptor[] filteredPds = null;
    if (hasInstAwareBpps) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                if (pvsToUse == null) {
                    if (filteredPds == null) {
                        filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                    }
                    pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        return;
                    }
                }
                pvs = pvsToUse;
            }
        }
    }
    //......
}
```

在这个 `InstantiationAwareBeanPostProcessor` 的for循环中，会调用 `AutowiredAnnotationBeanPostProcessor` 的 `postProcessProperties` 方法，触发自动注入。

### 3.7 AutowiredAnnotationBeanPostProcessor#postProcessProperties

```java
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
    try {
        metadata.inject(bean, beanName, pvs);
    }
    catch (BeanCreationException ex) {
        throw ex;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
    }
    return pvs;
}
```

在上面收集好要注入的属性后，下面的 `metadata.inject` 方法：

### 3.8 【注入】metadata.inject

跳转到 `AutowiredFieldElement#inject` 中：

```java
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    Field field = (Field) this.member;
    Object value;
    // ......
    try {
        value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
    }
    // ......
    if (value != null) {
        ReflectionUtils.makeAccessible(field);
        field.set(bean, value);
    }
}
```

一开始初始化的时候肯定找不到 Person ，要走 `beanFactory.resolveDependency` 方法：

### 3.9 beanFactory.resolveDependency

此时跳转到 `DefaultListableBeanFactory` 类中：

```java
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
                                @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
    // if-else ......
    else {
        Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
            descriptor, requestingBeanName);
        if (result == null) {
            result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
        }
        return result;
    }
}
```

来到最后的 `doResolveDependency` 方法中：

### 3.10 doResolveDependency

```java
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
                                  @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    
    // try ......
    if (instanceCandidate instanceof Class) {
        instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
    }
    // ......
}
```

Debug走到这一步，跳转进去的方法就是 `getBean`：

## 4. 流程全分析 - 初始化Person

### 4.1 getBean(person)

```java
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
    throws BeansException {
    return beanFactory.getBean(beanName);
}
```

继续往下走，回到 `AbstractBeanFactory` 了：

### 4.2 doGetBean(person) - getSingleton(person)

与上面的思路类似，不再贴源码，当执行到getSingleton方法时，要知道 beforeSingletonCreation 方法又执行了，此时正在创建的Bean有两个了：

![img](https://cdn.nlark.com/yuque/0/2022/png/229542/1661695598965-206dced5-5112-4a52-b0b5-f735dba52100.png)

### 4.3 createBean(person) - doCreateBean(person) -> addSingletonFactory

这几步操作最终完成的动作：**将person放入三级缓存，并从二级缓存中移除**。

### 4.4 populateBean(person)

跟上面一样，也是同样的执行后置处理器，走inject方法。

### 4.5 metadata.inject - resolveDependency - doResolveDependency

最终也会像上面一样，执行到这一步：

```java
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
                                  @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    
    // try ......
    if (instanceCandidate instanceof Class) {
        instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
    }
    // ......
}
```

进去会调getBean(cat)。

### 4.6 再次getBean(cat)

其实这里进的还是我们熟悉的那个getBean：

```java
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}
```

下面还是那一套，不过进入 `doGetBean` 方法后有一个很重要的环节：`**getSingleton**`

### 4.7 【二次获取】getSingleton(cat)

```java
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;
}
```

注意在这里第二次获取 **cat** 的时候，由于现在 **正在被创建的Bean** 中有 **cat** 了，所以 `isSingletonCurrentlyInCreation(cat)` 将返回true！会进入到下面的if结构体中！

进入之后，它要确定 `**earlySingletonObjects**` **二级缓存** 中是否有当前**创建好但没有赋值初始化的Bean**（当前cat），此时根据前面的步骤，person和cat均只在三级缓存，所以取出的 `singletonObject` 为null，进入第二层if的结构体中。再往下来，它又从 `**singletonFactories**` **三级缓存** 中取**当前正在创建的Bean**（cat），这次可以查到，于是进入第三层if的结构体。它干了两件事：**将这个 cat 放入二级缓存，并从三级缓存中移除**。

操作完成后的状态：

![img](https://cdn.nlark.com/yuque/0/2022/png/229542/1661695638114-0bf1d7ad-460f-424d-863d-342e1738d6eb.png)

那既然这里已经获取到了，那 `singletonObject` 自然有值，就可以正常返回那个 **正在创建，但还没有注入依赖项的cat** 。

### 4.8 回到doGetBean(cat)

```java
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
    // log ......
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
```

获取到 cat 后，下面会调用一个 `getObjectForBeanInstance` 方法：

### 4.9 getObjectForBeanInstance(cat)

```java
private final NamedThreadLocal<String> currentlyCreatedBean = new NamedThreadLocal<>("Currently created bean");

protected Object getObjectForBeanInstance(
    Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
    String currentlyCreatedBean = this.currentlyCreatedBean.get();
    if (currentlyCreatedBean != null) {
        registerDependentBean(beanName, currentlyCreatedBean);
    }
    
    return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
}
```

这里先通过 `this.currentlyCreatedBean.get()` 取到当前线程中正在创建的Bean的名称，发现为null（到目前为止也没发现谁在操作它，通过IDEA的提示，发现是 `obtainFromSupplier` 方法中有对它的操作，之前提过了我们不关心它），则直接调父类的 `getObjectForBeanInstance` 方法：

### 4.10 AbstractBeanFactory#getObjectForBeanInstance(cat)

```java
protected Object getObjectForBeanInstance(
    Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
    
    // Don't let calling code try to dereference the factory if the bean isn't a factory.
    // 如果Bean不是工厂，则不要让调用代码尝试取消引用工厂
    if (BeanFactoryUtils.isFactoryDereference(name)) {
        if (beanInstance instanceof NullBean) {
            return beanInstance;
        }
        if (!(beanInstance instanceof FactoryBean)) {
            throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
        }
    }
    
    // Now we have the bean instance, which may be a normal bean or a FactoryBean.
    // If it's a FactoryBean, we use it to create a bean instance, unless the
    // caller actually wants a reference to the factory.
    if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
        return beanInstance;
    }
    
    // ......
}
```

第一段if中，因为 cat 不是被工厂引用的Bean，这部分不进入。

第二段if中，因为 cat 不是一个工厂Bean，前半段返回true，直接返回cat。

这段方法走完后，cat还是那个cat。

回到doGetBean方法：

### 4.11 再回到doGetBean(cat)

```java
// Check if required type matches the type of the actual bean instance.
// 检查所需的类型是否与实际bean实例的类型匹配
if (requiredType != null && !requiredType.isInstance(bean)) {
    // ......
}
    return (T) bean;
```

这一段if判断是确定bean与返回的类型是否一致，这里很明显一致，直接强转返回即可。

### 4.12 回到注入的部分(person)

```java
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
                                  @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    
    // ......
    if (instanceCandidate instanceof Class) {
        instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
    }
    Object result = instanceCandidate;
    if (result instanceof NullBean) {
        if (isRequired(descriptor)) {
            raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
        }
        result = null;
    }
    if (!ClassUtils.isAssignableValue(type, result)) {
        throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
    }
    return result;
}
finally {
    ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
```

`descriptor.resolveCandidate` 方法执行完后，下面把bean交给result，确定没问题，返回出去。

### 4.13 回到resolveDependency(person)

```java
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
                                @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    // if-else ......
    else {
        Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
            descriptor, requestingBeanName);
        if (result == null) {
            result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
        }
        return result;
    }
}
```

这个方法也就成功返回cat了。

### 4.14 返回inject方法(person)

```java
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    // ......
    try {
        value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
    }
    // ......
}
if (value != null) {
    ReflectionUtils.makeAccessible(field);
    field.set(bean, value);
}
}
```

取到value，也就是那个cat的Bean后，最底下利用反射赋值，自动注入结束。

此时二级缓存和三级缓存中还是那个状态：

![img](https://cdn.nlark.com/yuque/0/2022/png/229542/1661695710729-5d8ebe0d-173f-4c42-8e32-8ee6bba0ae5a.png)

### 4.15 回到doCreateBean(person)

```java
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {
    // ......
    Object exposedObject = bean;
    try {
        populateBean(beanName, mbd, instanceWrapper);
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    //......
    return exposedObject;
}
```

person的属性赋值和自动注入完成后，执行初始化方法（没定义），最后返回出去。

### 4.16 回到createBean(person)

```java
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {
    // ......
    try {
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        // log ......
        return beanInstance;
    }
    // ......
}
```

也是直接返回出去。

### 4.17 回到DefaultSingletonBeanRegistry#getSingleton(person)

```java
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    // ......
    try {
        singletonObject = singletonFactory.getObject();
        newSingleton = true;
    }
    // catch ......
    finally {
        if (recordSuppressedExceptions) {
            this.suppressedExceptions = null;
        }
        afterSingletonCreation(beanName);
    }
    if (newSingleton) {
        addSingleton(beanName, singletonObject);
    }
}
return singletonObject;
}
}
```

`createBean` 返回后回到Lambda表达式，又回到 `getSingleton` 方法中。创建的这个单实例**Person**会被 `newSingleton` 标记为true，在下面的finally块中，要执行两个重要的方法：`afterSingletonCreation` 和 `addSingleton` ：

### 4.18 afterSingletonCreation

```java
protected void afterSingletonCreation(String beanName) {
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
        throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
    }
}
```

这部分的作用：**将创建好的Bean从“正在创建中的Bean”中移除**。

### 4.19 【重要】addSingleton

```java
protected void addSingleton(String beanName, Object singletonObject) {
    synchronized (this.singletonObjects) {
        this.singletonObjects.put(beanName, singletonObject);
        this.singletonFactories.remove(beanName);
        this.earlySingletonObjects.remove(beanName);
        this.registeredSingletons.add(beanName);
    }
}
```

这部分的作用：**将创建的这个Bean放入一级缓存，从二级缓存和三级缓存中移除，并记录已经创建了的单实例Bean**。

至此，Person的创建完全结束。

## 5. 回到Cat的创建

### 5.1 回到DependencyDescriptor#resolveCandidate(cat)

```java
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
    throws BeansException {
    return beanFactory.getBean(beanName);
}
```

这个 `getBean(person)` 结束了，真正完全创建好的Person也返回来了。下面的步骤就与上面一样了，快速过一遍。

### 5.2 返回注入的部分(cat)

```java
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
                                  @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    
    // ......
    if (instanceCandidate instanceof Class) {
        // person
        instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
    }
    Object result = instanceCandidate;
    // ......
    return result;
}
// ......
}
```

### 5.3 回到resolveDependency(cat)

```java
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
                                @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    // if-else ......
    else {
        Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
            descriptor, requestingBeanName);
        if (result == null) {
            // person
            result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
        }
        return result;
    }
}
```

### 5.4 返回inject方法(cat)

```java
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    // ......
    try {
        // person
        value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
    }
    // ......
}
if (value != null) {
    //缓存person
    ReflectionUtils.makeAccessible(field);
    field.set(bean, value);
}
}
```

### 5.5 回到doCreateBean(cat)

```java
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {
    // ......
    Object exposedObject = bean;
    try {
        // 自动注入完成
        populateBean(beanName, mbd, instanceWrapper);
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    //......
    return exposedObject;
}
```

### 5.6 回到createBean(cat)

```java
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {
    // ......
    try {
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        // log ......
        // 直接返回出去了
        return beanInstance;
    }
    // ......
}
```

### 5.7 回到DefaultSingletonBeanRegistry#getSingleton(cat)

```java
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    // ......
    try {
        singletonObject = singletonFactory.getObject();
        newSingleton = true;
    }
    // catch ......
    finally {
        if (recordSuppressedExceptions) {
            this.suppressedExceptions = null;
        }
        // 清除正在创建的缓存
        afterSingletonCreation(beanName);
    }
    if (newSingleton) {
        // 创建完cat后也要调这个方法
        addSingleton(beanName, singletonObject);
    }
}
return singletonObject;
}
}
```

### 5.8 afterSingletonCreation

```java
protected void afterSingletonCreation(String beanName) {
    // 清除正在创建的缓存
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
        throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
    }
}
```

### 5.9 【重要】addSingleton

```java
protected void addSingleton(String beanName, Object singletonObject) {
    synchronized (this.singletonObjects) {
        // 将cat放入一级缓存
        this.singletonObjects.put(beanName, singletonObject);
        // 从二级缓存和三级缓存中移除
        this.singletonFactories.remove(beanName);
        this.earlySingletonObjects.remove(beanName);
        // 记录已经创建了的cat
        this.registeredSingletons.add(beanName);
    }
}
```

至此，Cat的创建完全结束。

## 6. @Autowired解决循环依赖的核心思路

整个IOC容器解决循环依赖，用到的几个重要成员：

* `**singletonObjects**`：一级缓存，存放**完全初始化好的Bean**的集合，从这个集合中取出来的Bean可以立马返回
* `**earlySingletonObjects**`**：二级缓存，存放创建好但没有初始化属性的Bean**的集合，它用来解决循环依赖
* `**singletonFactories**`：三级缓存，存放**单实例Bean工厂**的集合
* `**singletonsCurrentlyInCreation**`：存放**正在被创建的Bean**的集合

咱来总结一下，IOC容器解决循环依赖的思路：

1. 初始化 Bean 之前，将这个 bean 的 name 放入**三级缓存**
2. 创建 Bean 将准备创建的 Bean 放入 **singletonsCurrentlyInCreation** （正在创建的 Bean ）
3. `createNewInstance` 方法执行完后执行 `addSingletonFactory`，将这个实例化但没有属性赋值的 Bean **放入三级缓存，并从二级缓存中移除**

一般情况下初次创建的 bean 不会存在于二级缓存，故该步骤可以简单理解为仅仅是放入了三级缓存而已

1. 属性赋值&自动注入时，引发关联创建
2. 关联创建时：
3. 1. 检查“正在被创建的 Bean ”中是否有即将注入的 Bean
   2. 如果有，检查二级缓存中是否有当前创建好但没有赋值初始化的 Bean
   3. 如果没有，检查三级缓存中是否有正在创建中的 Bean
   4. 至此一般会有，将这个 Bean **放入二级缓存，并从三级缓存中移除**
4. 之后 Bean 被成功注入，最后执行 `addSingleton`，将这个完全创建好的Bean**放入一级缓存，从二级缓存和三级缓存移除**，并记录已经创建了的单实例Bean

下面的这张图描述了上述的过程，图很大，建议用原图查看更佳：

![img](https://cdn.nlark.com/yuque/0/2022/png/229542/1661695841488-67942f77-873f-4d14-9337-396a0507fd0a.png)
