> For the complete documentation index, see [llms.txt](https://ldbmcs.gitbook.io/java/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ldbmcs.gitbook.io/java/java-frameworks-49/spring/spring-boot/spring-boot-ioc-si-xun-huan-yi-lai-yu-jie-jue-fang-an.md).

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


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ldbmcs.gitbook.io/java/java-frameworks-49/spring/spring-boot/spring-boot-ioc-si-xun-huan-yi-lai-yu-jie-jue-fang-an.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
