> 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-72/spring/spring-ioc/spring-bean-de-sheng-ming-zhou-qi-si-chu-shi-hua-jie-duan.md).

# Spring Bean的生命周期(四) - 初始化阶段

上一章，我们从后置处理器的初始化开始，了解了 bean 在实例化前的一些处理，以及实例化过程中的一些逻辑。bean 对象实例化出来之后，下一步就要给 bean 的属性赋值，以及组件的依赖注入了。

本章主要会涉及到的原理部分：

* bean 的属性赋值 & 组件依赖注入
* bean 的初始化方法回调
* 重要的 `BeanPostProcessor` 功能解析

## 1. doCreateBean

上一章中我们只解析了 `doCreateBean` 方法中的第一小段，接下来我们继续往下读。

### 1.1 回调MergedBeanDefinitionPostProcessor

```java
    // ......
    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            }
            // catch ......
            mbd.postProcessed = true;
        }
    }
    // ......
```

这个阶段它会回调所有的 `MergedBeanDefinitionPostProcessor` ，这个阶段本身没什么好解释的，不过这里面有几个关键的 `MergedBeanDefinitionPostProcessor` 实现，咱在这里还是有必要展开讲一下的。

#### 1.1.1 InitDestroyAnnotationBeanPostProcessor

顾名思义，它是处理初始化和销毁注解的后置处理器，它的核心处理逻辑如下：

```java
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    LifecycleMetadata metadata = findLifecycleMetadata(beanType);
    metadata.checkConfigMembers(beanDefinition);
}
```

很明显，`findLifecycleMetadata` 方法是查找 bean 的生命周期元信息，进入到该方法中：

```java
private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
    if (this.lifecycleMetadataCache == null) {
        // Happens after deserialization, during destruction...
        return buildLifecycleMetadata(clazz);
    }
    // 构建缓存 ......
    return metadata;
}
```

这里又是用缓存机制，把 bean 的初始化和销毁注解信息都保存到 `lifecycleMetadataCache` 里了。咱主要关注的是 `buildLifecycleMetadata` 方法，看它都是怎么搞的。

```java
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
    if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
        return this.emptyLifecycleMetadata;
    }

    List<LifecycleElement> initMethods = new ArrayList<>();
    List<LifecycleElement> destroyMethods = new ArrayList<>();
    Class<?> targetClass = clazz;

    do {
        final List<LifecycleElement> currInitMethods = new ArrayList<>();
        final List<LifecycleElement> currDestroyMethods = new ArrayList<>();

        // 反射所有的public方法
        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            // 寻找所有被初始化注解标注的方法
            if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
                LifecycleElement element = new LifecycleElement(method);
                currInitMethods.add(element);
            }
            // 寻找所有被销毁注解标注的方法
            if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
                currDestroyMethods.add(new LifecycleElement(method));
            }
        });

        initMethods.addAll(0, currInitMethods);
        destroyMethods.addAll(currDestroyMethods);
        targetClass = targetClass.getSuperclass();
    } // 依次向上寻找父类
    while (targetClass != null && targetClass != Object.class);

    return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
            new LifecycleMetadata(clazz, initMethods, destroyMethods));
}
```

这段源码还是比较容易理解的，它会寻找这个 bean 所属的 `Class` 中是否有包含初始化注解和销毁注解的方法。而初始化注解、销毁注解分别是啥呢？在子类 `CommonAnnotationBeanPostProcessor` 中有指定：

```java
setInitAnnotationType(PostConstruct.class);
setDestroyAnnotationType(PreDestroy.class);
```

好吧，果然还是 JSR 250 的那一套。那合着说，`**InitDestroyAnnotationBeanPostProcessor**` **就是收集标注了** `**@PostConstruct**` **和** `**@PreDestroy**` **注解的后置处理器**呗。

#### 1.1.2 CommonAnnotationBeanPostProcessor

呦，马上就到这个子类了，咱看看这个类里有什么扩展：

```java
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    // 调用InitDestroyAnnotationBeanPostProcessor
    super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
    // 收集注入相关的信息
    InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
    metadata.checkConfigMembers(beanDefinition);
}
```

除了调用父类 `InitDestroyAnnotationBeanPostProcessor` 的收集动作之外，它在这里还要收集有关注入的注解信息。与上面的 `findLifecycleMetadata` 方法类似，它也是设置有缓存的机制，我们直接看实际干活的方法了：

```java
      do {
        final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

        ReflectionUtils.doWithLocalFields(targetClass, field -> {
            if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
                if (Modifier.isStatic(field.getModifiers())) {
                    throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
                }
                currElements.add(new WebServiceRefElement(field, field, null));
            }
            else if (ejbClass != null && field.isAnnotationPresent(ejbClass)) {
                if (Modifier.isStatic(field.getModifiers())) {
                    throw new IllegalStateException("@EJB annotation is not supported on static fields");
                }
                currElements.add(new EjbRefElement(field, field, null));
            }
            else if (field.isAnnotationPresent(Resource.class)) {
                if (Modifier.isStatic(field.getModifiers())) {
                    throw new IllegalStateException("@Resource annotation is not supported on static fields");
                }
                if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
                    currElements.add(new ResourceElement(field, field, null));
                }
            }
        });
```

由这段节选的源码可见，它还能支持 JAVA EE 规范中的 `@WebServiceRef` 、`@EJB` 、`@Resource` 注解，并封装对应的注解信息。由于我们已经对 EJB 等家伙不关注了，所以这里小伙伴们只需要知道它相当于额外收集了 `@Resource` 注解的信息即可。

#### 1.1.3 AutowiredAnnotationBeanPostProcessor

有了前面两个后置处理器的知识，这个后置处理器的功能不用看也就能猜得到了吧：它应该是**收集自动注入的注解信息**的。底层的原理与前两者的逻辑设计一模一样，小册就不重复贴出了，这里重点说一下它支持的注解。

```java
public AutowiredAnnotationBeanPostProcessor() {
    this.autowiredAnnotationTypes.add(Autowired.class);
    this.autowiredAnnotationTypes.add(Value.class);
    try {
        this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
                ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
    }
 }
```

可以发现，`AutowiredAnnotationBeanPostProcessor` 在构造方法中，就已经指定好它默认支持 `@Autowired` 注解、`@Value` 注解，如果 classpath 下有来自 JSR 330 的 `@Inject` 注解，也会一并支持。

#### 1.1.4 注解后置处理器小结

从这几个后置处理器中，我们就可以发现，可以支持 bean 中标注的注解的后置处理器，它们的处理方式都是**先收集注解标注的信息，保存到缓存中，随后再处理时，只需要从缓存中取就可以**了。

### 1.2 早期bean对象引用的获取与缓存

```java
    // ......
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        // logger ......
        // 处理循环依赖的问题
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }
    // ......
```

这里有一个获取早期 bean 对象引用的动作，这一步是为了解决 bean 之间的循环依赖问题。这里我们只是说一下这个早期 bean 对象的引用是个什么东西。

从前面的逻辑中，**bean 被实例化出来之后还没有进行属性赋值和组件的依赖注入**，但此时的 **bean 对象已经实实在在的存在了**。如果在此期间，有另外的 bean 又需要创建它时，就**不应该再创建同样的一个 bean 对象，而是直接拿到该引用**即可，这个设计就是为了解决 bean 之间的循环依赖而用（从 `getEarlyBeanReference` 方法的 javadoc 上也能看到）。

**有关 bean 的循环依赖，在本小册中不会有涉及，在我的**[**《SpringBoot 小册》第 15 章**](https://juejin.im/book/6844733814560784397/section/6844733814615326733) **有完整的讲过 SpringFramework 解决循环依赖的全流程，有需要的小伙伴们可以跳转过去学习哦。**

### 1.3 populateBean - 属性赋值+依赖注入

接下来的两步是挨着的：

```java
    // ......
    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
        populateBean(beanName, mbd, instanceWrapper);
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    // ......
```

这里我们先看 `populateBean` 这一步，由于这个方法中的内容还是比较多，我们拆解开来看。

#### 1.3.1 检查bean&准备

```java
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    if (bw == null) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        }
        else {
            // Skip property population phase for null instance.
            return;
        }
    }
    // ......
```

这个地方仅仅是为了检查 `BeanWrapper` 中是否存在而已，没什么好说的。

#### 1.3.2 回调InstantiationAwareBeanPostProcessor

```java
    // ......
    // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    // state of the bean before properties are set. This can be used, for example,
    // to support styles of field injection.
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    return;
                }
            }
        }
    }
    // ......
```

这个部分很明显就是回调所有的 `InstantiationAwareBeanPostProcessor` 而已，不过这上面有好长一段注释，我们来看看它讲了些啥：

Give any InstantiationAwareBeanPostProcessors the opportunity to modify the state of the bean before properties are set. This can be used, for example, to support styles of field injection.

在设置属性之前，让任何 `InstantiationAwareBeanPostProcessor` 都有机会修改 bean 的状态，例如支持属性字段的注入。

哦，合着 `postProcessAfterInstantiation` 方法也是干预 bean 的属性等东西的呀。而且有一个小细节注意一下，`postProcessAfterInstantiation` 方法返回的是 boolean 类型，当 `postProcessAfterInstantiation` 返回 **false** 时，会直接 **return** 出去，**不再执行下面的属性赋值 + 组件依赖注入的逻辑**！（通常这个方法一定是返回 true 的，底层默认也是返回 true ）

可能会有小伙伴产生疑惑，那这个回调有什么可以利用的吗？注意思考，当 bean 的创建来到这个位置的时候，此时 bean 的状态如何？还是所有属性都为空吧，而且还都没有执行任何初始化的逻辑吧。所以这个回调的位置，就是让咱**在 bean 已经初始化好，但还没有开始属性赋值和依赖注入时切入自定义逻辑**。

#### 1.3.3 自动注入支持

```java
    // ......
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    // 解析出当前bean支持的自动注入模式
    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        // Add property values based on autowire by name if applicable.
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        // Add property values based on autowire by type if applicable.
        if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }
    // ......
```

这一部分的逻辑是支撑 **“自动注入模式”** 功能的，我们在第 24 章已经简单的讲过了，这里我们简单地看一下源码的实现就好了。

在上面先把当前正在创建的 bean 的自动注入模式解析出来，之后根据自动注入模式，执行对应的逻辑。这里我们以 `byName` 为例看一下它里面的实现。

```java
protected void autowireByName(
        String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
    String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
    for (String propertyName : propertyNames) {
        // 存在bean，就获取出来，添加依赖关系
        if (containsBean(propertyName)) {
            Object bean = getBean(propertyName);
            pvs.add(propertyName, bean);
            registerDependentBean(propertyName, beanName);
        }
    }
}
```

可以发现，这个逻辑是相当的简单吧！就仅仅是**查出来，添加上依赖关系，就完事了**，没有任何的多余动作，这部分的逻辑也没什么好说的咯。

另外留意一点！在这段代码执行完毕后，有 `pvs = newPvs;` 的步骤，它将这个过程中需要组件依赖注入的信息也都封装进了 `PropertyValues` 中了，所以**此时** `**pvs**` **中就应该有一开始封装的信息，以及通过自动注入封装好的依赖信息**。

#### 1.3.4 又回调InstantiationAwareBeanPostProcessor

```java
    // ......
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

    PropertyDescriptor[] filteredPds = null;
    if (hasInstAwareBpps) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                // 【核心】回调postProcessProperties
                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` 了，不过注意这次回调的方法是 `**postProcessProperties**` 和 `postProcessPropertyValues` 方法了（ `postProcessPropertyValues` 方法在 SpringFramework 5.1 之后被废弃了）。注意 `postProcessProperties` 方法会传入 `PropertyValues` ，也会返回 `PropertyValues` ，所以**这个过程相当于反复给** `**PropertyValues**` **封装数据**。那这个封装的过程我们是有必要了解一下的。

之前在第 27 章我们已经知道，这个时机的回调是属性赋值和组件依赖注入的核心时机，所以我们需要关注这里面一个非常重要的后置处理器：`**AutowiredAnnotationBeanPostProcessor**` 。

**AutowiredAnnotationBeanPostProcessor#postProcessProperties**

`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 ......
    return pvs;
}
```

嗯，看到 `findAutowiringMetadata` 方法，是不是又想到了前面那个一模一样的套路呢？又是收集所有标注了 `@Autowired` 、`@Value`、`@Inject` 注解的信息，返回回来。不过这里不只是收集了，它要**真正的给 bean 对象的属性赋值**！

到这里，小伙伴是否有回想起在第 30 章中，我们说过的，在 `BeanFactoryPostProcessor` 或者 `BeanDefinitionRegistryPostProcessor` 中无法直接使用 `@Autowired` 直接注入 SpringFramework 中的内部组件（如 `Environment` ）？现在是否明白这个问题的答案了吗？**当** `**BeanDefinitionRegistryPostProcessor**` **在初始化的阶段，还不存在** `**BeanPostProcessor**` **呢，所以那些用于支持依赖注入的后置处理器（** `**AutowiredAnnotationBeanPostProcessor**` **）还没有被初始化，自然也就没办法支持注入了。正确的做法是借助** `**Aware**` **接口的回调注入。**

**metadata.inject**

```java
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) {
            // logger ......
            element.inject(target, beanName, pvs);
        }
    }
}
```

整体逻辑还是非常简单的哈，给一个 bean 进行注入，就相当于给这个 bean 中需要注入的元素依次注入。

继续往下进入到 `element.inject` 方法，这里面就比较复杂了（因为它有两个重写的复杂方法），我们只需要看一下它的核心工作机制就好了：

```java
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
        throws Throwable {
    if (this.isField) {
        // 反射注入字段
        Field field = (Field) this.member;
        ReflectionUtils.makeAccessible(field);
        field.set(target, getResourceToInject(target, requestingBeanName));
    }
    else {
        if (checkPropertySkipping(pvs)) {
            return;
        }
        try {
            // 反射调用setter方法
            Method method = (Method) this.member;
            ReflectionUtils.makeAccessible(method);
            method.invoke(target, getResourceToInject(target, requestingBeanName));
        } // catch ......
    }
}
```

嚯，这也太简单了吧，就仅仅是反射注入 / 调用呗？当然啦，太复杂的是这个方法重写的两个子类 `AutowiredFieldElement` 和 `AutowiredMethodElement` ，但它们处理的逻辑大同小异，只是处理步骤复杂了好多而已。小伙伴们没有必要深追这里面的实现细节，能对这个步骤的底层基本实现心领神会即可。

#### 1.3.5 属性赋值

到这里为止，`PropertyValues` 的内容都封装好了，来看最后一段源码：

```java
    // ......
    if (needsDepCheck) {
        if (filteredPds == null) {
            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        }
        checkDependencies(beanName, mbd, filteredPds, pvs);
    }

    if (pvs != null) {
        // 将PropertyValues应用给bean
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}
```

核心动作就只有 `applyPropertyValues` 这一个动作，而从方法名上就能 get 到，这个 `applyPropertyValues` 方法的作用，就是**把前面准备好的** `**PropertyValues**` **对象封装的内容，应用到当前正在创建的 bean 实例上**。

接下来咱进入到 `applyPropertyValues` 方法中一探究竟。。。呃，这个方法实在是太长了，我们依然是拆解来看吧。

**预检查和准备**

```java
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
    if (pvs.isEmpty()) {
        return;
    }

    if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
        ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
    }

    MutablePropertyValues mpvs = null;
    List<PropertyValue> original;
    // ......
}
```

这段很简单啦，如果直接没有要应用的 bean 属性，则直接返回就好，否则它就要准备处理 `PropertyValues` 了。

**重复解析的提前返回**

```java
    // ......
    if (pvs instanceof MutablePropertyValues) {
        mpvs = (MutablePropertyValues) pvs;
        // 判断PropertyValues是否已经解析过了
        if (mpvs.isConverted()) {
            try {
                bw.setPropertyValues(mpvs);
                return;
            } // catch ......
        }
        original = mpvs.getPropertyValueList();
    }
    else {
        original = Arrays.asList(pvs.getPropertyValues());
    }
    // ......
```

这部分很明显是一个提前返回的动作，`if (mpvs.isConverted())` 的动作很明显是检查 `PropertyValues` 是否已经解析过了，如果已经解析过，则直接应用就行，不需要重复解析。

**初始化BeanDefinitionValueResolver**

```java
    // ......
    TypeConverter converter = getCustomTypeConverter();
    if (converter == null) {
        converter = bw;
    }
    BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
    // ......
```

这一段非常短，但这个 `BeanDefinitionValueResolver` 却很重要！`BeanDefinitionValueResolver` 的初始化需要传入一个 `TypeConverter` ，而这个 `TypeConverter` 是 SpringFramework 中内部用于类型转换的核心 API 。简单的来说，**使用** `**TypeConverter**` **可以将一个 String 类型的数据，转换为特定的所需要的类型的数据**。而 `BeanDefinitionValueResolver` 就利用 `TypeConverter` ，完成对 bean 实例中需要注入的属性值进行解析，并适配为 bean 属性所需要的类型（如 String → int ，依赖 bean 的名称转为实际 bean 的引用）。

**类型转换**

这一部分小册就**不着重解释了**，类型转换不属于我们重点关心的东西，小册在源码的关键位置留了注释，小伙伴们看看就得了。

```java
    // ......
    // Create a deep copy, resolving any references for values.
    List<PropertyValue> deepCopy = new ArrayList<>(original.size());
    boolean resolveNecessary = false;

    // 迭代逐个解析PropertyValue
    for (PropertyValue pv : original) {
        // 已经解析过的直接添加
        if (pv.isConverted()) {
            deepCopy.add(pv);
        }
        else {
            String propertyName = pv.getName();
            // 此处取出的值是未经过转换的原始value
            Object originalValue = pv.getValue();
            // 此处是 5.2 的一个扩展，如果编程式使用BeanDefinitionBuilder添加自动注入的属性时，
            // 会使用类似于自动注入支持的方式处理该属性
            if (originalValue == AutowiredPropertyMarker.INSTANCE) {
                Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
                if (writeMethod == null) {
                    throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
                }
                originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
            }
            // 根据originalValue的类型，解析出bean依赖的属性值
            // 此处如果是bean的名称，则最终解析出来的是真正的bean对象
            Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
            Object convertedValue = resolvedValue;
            boolean convertible = bw.isWritableProperty(propertyName) &&
                    !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
            if (convertible) {
                convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
            }
            // 此处要对解析前和解析后的数据进行对比
            // 如果解析之前与解析之后的值完全一致，则代表不需要解析，或已经解析过了，直接保存
            if (resolvedValue == originalValue) {
                if (convertible) {
                    pv.setConvertedValue(convertedValue);
                }
                deepCopy.add(pv);
            }
            // 如果String类型转为其他类型（除了集合或数组），则认为它也不需要再解析了
            else if (convertible && originalValue instanceof TypedStringValue &&
                    !((TypedStringValue) originalValue).isDynamic() &&
                    !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
                pv.setConvertedValue(convertedValue);
                deepCopy.add(pv);
            }
            // 否则，该字段认定为每次都需要重新解析
            else {
                resolveNecessary = true;
                deepCopy.add(new PropertyValue(pv, convertedValue));
            }
        }
    }
    // 如果所有字段都解析完毕，则当前PropertyValues可以标记为已经解析完成，后续不需要重复解析
    if (mpvs != null && !resolveNecessary) {
        mpvs.setConverted();
    }
    // ......
```

实际在测试代码中，这个方法压根就没走，都被 `AutowiredAnnotationBeanPostProcessor` 处理完了，所以这个地方我们一带而过得了。

**PropertyValues应用到bean**

```java
    // ......
    // Set our (possibly massaged) deep copy.
    try {
        bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    }
    catch (BeansException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    }
}
```

最后一个步骤，这里要把 `PropertyValues` 中的属性值全部应用到 bean 对象中了。这一部分来回调的源码比较多，最终的落地在 `org.springframework.beans.AbstractNestablePropertyAccessor.PropertyHandler#setValue` 中，它的其中一个实现类 `FieldPropertyHandler` 的方法实现如下：

```java
public void setValue(@Nullable Object value) throws Exception {
    try {
        ReflectionUtils.makeAccessible(this.field);
        this.field.set(getWrappedInstance(), value);
    }
    // catch ......
}
```

简直简单的不要再简单，反射赋值，简单粗暴。

到这里，整个 `populateBean` 的属性赋值动作就全部完成了。

### 1.4 initializeBean

当 bean 的创建过程走到 `initializeBean` 方法时，此时 bean 中的属性都是齐全的了，但生命周期的回调都还没有回调，接下来我们研究这个部分。

先总体概览一下源码，这里面包含 4 个步骤，均在源码中加以标注：

```java
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        // ......
    }
    else {
        // 1.4.1 执行Aware回调
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    // 1.4.2 执行BeanPostProcessor的前置回调
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        // 1.4.3 执行生命周期回调
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    // catch ......
    // 1.4.4 执行BeanPostProcessor的后置回调
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}
```

下面我们分述这几个步骤。

#### 1.4.1 invokeAwareMethods - 执行Aware回调

`invokeAwareMethods(beanName, bean);` 这个方法中的定义相当简单，只是判断接口的定义，以及强转后的接口方法调用而已，非常容易理解：

```java
private void invokeAwareMethods(String beanName, Object bean) {
    if (bean instanceof Aware) {
        // 如果bean实现了BeanNameAware，则强转后调用setBeanName方法注入bean的名称
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
        // 如果bean实现了BeanClassLoaderAware，则强转后调用setBeanClassLoader方法注入当前的ClassLoader
        if (bean instanceof BeanClassLoaderAware) {
            ClassLoader bcl = getBeanClassLoader();
            if (bcl != null) {
                ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
            }
        }
        // 如果bean实现了BeanFactoryAware，则强转后调用setBeanFactory方法注入BeanFactory
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}
```

不过这里面有一个问题：有关 `ApplicationContext` 部分的处理，怎么一个也没有咧？？？有关这个问题，我们马上在下面就提到了，接着往下来看。

#### 1.4.2 applyBeanPostProcessorsBeforeInitialization

```java
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        // 此处做了一个分支控制：如果处理完的结果返回null，则认为停止BeanPostProcessor的处理，返回bean对象
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}
```

这个逻辑就很简单了，它会依次执行容器中所有 `BeanPostProcessor` 的 `postProcessBeforeInitialization` 方法。不过这里有一个分支控制处理：如果处理完的结果返回 null ，则不再执行后面剩余的 `BeanPostProcessor` ，直接返回上一个 `BeanPostProcessor` 处理之后的 bean 对象返回。由此我们可以在此处针对自己项目中某些特定的 bean 搞一些特殊的拦截的处理。

只看这个逻辑还是很简单的吧，所以我们要深入其中，看几个 `BeanPostProcessor` 的实现。

**InitDestroyAnnotationBeanPostProcessor**

又要看它了，既然它有收集 bean 的初始化和销毁信息，那这里就肯定有回调的时机咯。这个源码的写法我们在上面已经看过好几个差不多的了：

```java
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
    try {
        metadata.invokeInitMethods(bean, beanName);
    }
    // catch ......
    return bean;
}
```

根据上面分析的内容，我们已经知道，`findLifecycleMetadata` 方法可以把标注了 `@PostConstruct` 和 `@PreDestroy` 注解的方法都取出来，所以这里就相当于**回调** `**@PostConstruct**` **标注的方法**了！

进入到 `metadata.invokeInitMethod` 方法中：

```java
public void invokeInitMethods(Object target, String beanName) throws Throwable {
    Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
    Collection<LifecycleElement> initMethodsToIterate =
            (checkedInitMethods != null ? checkedInitMethods : this.initMethods);
    if (!initMethodsToIterate.isEmpty()) {
        for (LifecycleElement element : initMethodsToIterate) {
            // logger ......
            element.invoke(target);
        }
    }
}
```

又是熟悉的 `element.invoke` 操作，不过这里就没那么复杂了，点进去看：

```java
public void invoke(Object target) throws Throwable {
    ReflectionUtils.makeAccessible(this.method);
    this.method.invoke(target, (Object[]) null);
}
```

嚯，直接反射调用方法啊，也是非常简单粗暴咯。

另外，根据这个源码中的反射细节，我们也就知道一开始学习 bean 的初始化和销毁方法标注时的规定了：对于 `@PostConstruct` 和 `@PreDestroy` 标注的方法来讲，**方法的访问修饰符无所谓，但一定不能有方法参数**。

**ApplicationContextAwareProcessor**

呦，看到类名了，是不是突然明白前面的 `Aware` 回调为什么没有 `ApplicationContext` 相关的操作了？是的，这些回调都在这个 `ApplicationContextAwareProcessor` 中实现了。由此我们可以先得出一个结论：`**BeanFactory**` **的注入时机比** `**ApplicationContext**` **早。**

接下来我们看源码的实现：

```java
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
            bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
            bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
        return bean;
    }

    // ......
    else {
        invokeAwareInterfaces(bean);
    }
    return bean;
}
```

可以发现，这一个 `ApplicationContextAwareProcessor` 可以支持 6 个 `Aware` 接口的回调。至于回调的实现，`invokeAwareInterfaces` 的操作跟上面 `invokeAwareMethods` 一模一样，小册就不再贴出啦，小伙伴们可以自行去看一下。

#### 1.4.3 invokeInitMethods - 执行初始化生命周期回调

终于到了我们可能最熟悉的部分了，这里有 `InitializingBean` 接口的 `afterPropertiesSet` 方法回调，以及 `init-method` 的回调：

```java
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
        throws Throwable {

    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        // ......
        else {
            // 回调InitializingBean的afterPropertiesSet方法
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }

    if (mbd != null && bean.getClass() != NullBean.class) {
        String initMethodName = mbd.getInitMethodName();
        if (StringUtils.hasLength(initMethodName) &&
                !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                !mbd.isExternallyManagedInitMethod(initMethodName)) {
            // 回调init-method方法（同样是反射调用）
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}
```

这部分源码理解起来那是相当的容易了是吧！so 小册也不作过多解释咯。

#### 1.4.4 applyBeanPostProcessorsAfterInitialization

```java
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingB ean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}
```

处理逻辑与 `applyBeanPostProcessorsBeforeInitialization` 部分几乎一模一样，我们还是来关注几个重要的后置处理的实现。

**AbstractAutoProxyCreator**

```java
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            // 创建代理对象
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}
```

这就是之前我们在学习 `BeanPostProcessor` 中一直提到的创建代理的核心处理器了，它也是 **AOP** 创建代理对象的核心实现。由于这个逻辑属于 AOP 的内容，咱回头放到 AOP 章节详细展开。

**ApplicationListenerDetector**

```java
public Object postProcessAfterInitialization(Object bean, String beanName) {
    if (bean instanceof ApplicationListener) {
        Boolean flag = this.singletonNames.get(beanName);
        if (Boolean.TRUE.equals(flag)) {
            this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
        }
        // 异常分支处理 ......
    }
    return bean;
}
```

这个 `ApplicationListenerDetector` 我们在上一章的 `BeanPostProcessor` 初始化阶段还说过一次，它用来关联所有的监听器引用。同样的，监听器在创建的时候，也需要 `ApplicationListenerDetector` 把这些监听器挂进 `ApplicationContext` 中，这样这些监听器才可以被事件广播器使用。

### 1.5 注册销毁时的回调

如果一个 bean 定义的 class 有实现 `DisposableBean` 接口，或者声明了 `@PreDestroy` 注解，或者声明了 `destroy-method` 方法，则会在 `doCreateBean` 方法的最后一步，注册一个销毁 bean 的回调钩子：

```java
    // doCreateBean 最后 ......
    // Register bean as disposable.
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    // catch ......
    return exposedObject;
}
```

进入 `registerDisposableBeanIfNecessary` 方法：

```java
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
    // 不是原型bean，且有定义销毁类型的方法
    if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
        if (mbd.isSingleton()) {
            registerDisposableBean(beanName,
                    new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        }
        // 处理特殊的scope ......
    }
}
```

可见，通常情况下可以记录销毁 bean 的回调钩子的原则是：**单实例 bean ，并且有定义销毁类型的方法**，而这些销毁类型的方法，就是刚才提到的三种类型，也是早在第 13 章我们就学过的类型。

对于这些定义了销毁类型的方法的 bean ，会记录到一个 `disposableBeans` 的 `Map` 中：

```java
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();

public void registerDisposableBean(String beanName, DisposableBean bean) {
    synchronized (this.disposableBeans) {
        this.disposableBeans.put(beanName, bean);
    }
}
```

这个 `Map` 在下一章的 bean 销毁部分还会提及，小伙伴们可以先留意一下。

到这里，`doCreateBean` 方法全部执行完毕，一个 bean 已经被成功的创建出来了。

## 2. SmartInitializingSingleton

在上一章的第 2 节 `preInstantiateSingletons` 方法中，我们只做了 `getBean` 方法的全解析，当时在源码的注释中，小册在最后埋了一个伏笔：

```java
            else {
                // 普通的初始化，就是getBean方法
                getBean(beanName);
            }
        }
    }

    // 初始化的最后阶段 ......
}
```

这个初始化的最后阶段，是在 SpringFramework 4.1 之后才有的，而支撑这个阶段的核心接口是 `SmartInitializingSingleton` 。

这个接口在开发中的使用意义不是很大，小伙伴们简单了解下就可以了。

### 2.1 SmartInitializingSingleton的设计

在 `SmartInitializingSingleton` 接口的 javadoc 中，可以找到这样的一段话：

This callback variant is somewhat similar to org.springframework.context.event.ContextRefreshedEvent but doesn't require an implementation of org.springframework.context.ApplicationListener, with no need to filter context references across a context hierarchy etc. It also implies a more minimal dependency on just the beans package and is being honored by standalone ListableBeanFactory implementations, not just in an org.springframework.context.ApplicationContext environment.

这个回调变体有点类似于 `ContextRefreshedEvent` ，但是不需要 `ApplicationListener` 的实现，不需要在整个上下文层次结构中过滤上下文引用。这也意味着更多对 bean 包的依赖性最小，并且由独立的 `ListableBeanFactory` 实现兑现，而不仅仅是在 `ApplicationContext` 环境中。

从这段注释中，我们就可以知道，`**SmartInitializingSingleton**` **的设计是为了只让** `**BeanFactory**` **控制的，不需要** `**ApplicationContext**` **也能实现的 bean 的初始化后处理**。而且从包名上也能看得出来：`org.springframework.beans.factory` ，嗯，是 `beans` 包下的，与 `context` 没关联。

这个地方作者认为没有必要深究它的出现缘由，毕竟对于我们开发者来讲，可供切入框架中的时机越多，灵活度也就越高，重要的我们学习，不重要的我们知道一下就好了。

### 2.2 SmartInitializingSingleton的回调

```java
            else {
                getBean(beanName);
            }
        }
    }

    // Trigger post-initialization callback for all applicable beans...
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            // ......
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}
```

`SmartInitializingSingleton` 的回调时机，是所有的非延迟加载的单实例 bean 都初始化完成后，再挨个执行 `afterSingletonsInstantiated` 方法，调用的方式非常简单，逐个判断就完事了，也没什么好解释的。

## 3. Lifecycle的回调

在 `ApplicationContext` 的 `refresh` 方法最后，初始化完成所有非延迟加载的单实例 bean 之后，会执行 `finishRefresh` 方法：

```java
protected void finishRefresh() {
    // Clear context-level resource caches (such as ASM metadata from scanning).
    // 清除上下文级别的资源缓存
    clearResourceCaches();

    // Initialize lifecycle processor for this context.
    // 为当前ApplicationContext初始化一个生命周期处理器
    initLifecycleProcessor();

    // Propagate refresh to lifecycle processor first.
    // 将refresh的动作传播到生命周期处理器
    getLifecycleProcessor().onRefresh();

    // Publish the final event.
    // 广播事件
    publishEvent(new ContextRefreshedEvent(this));

    // Participate in LiveBeansView MBean, if active.
    LiveBeansView.registerApplicationContext(this);
}
```

可以发现，这里面的处理逻辑还是很有序的，首先把该读取的一些资源缓存都清除掉，然后它初始化了一个生命周期处理器，随后调用它的 `onRefresh` 方法，接下来广播 `ContextRefreshedEvent` 事件。而回调 `Lifecycle` 接口的动作，就发生在这个生命周期处理器中。

### 3.1 initLifecycleProcessor

```java
protected void initLifecycleProcessor() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
        this.lifecycleProcessor =
                beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
        // logger ......
    }
    else {
        DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
        defaultProcessor.setBeanFactory(beanFactory);
        this.lifecycleProcessor = defaultProcessor;
        beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
        // logger ......
    }
}
```

由此可以发现，无论 `BeanFactory` 中有没有 `LifecycleProcessor` ，它都会保证最终容器中会有，注意它的实现类是 `DefaultLifecycleProcessor` ，我们下面会进入它的内部实现。

### 3.2 onRefresh

```java
public void onRefresh() {
    startBeans(true);
    this.running = true;
}
```

`DefaultLifecycleProcessor` 的 `onRefresh` 方法非常简单，就是启动 bean 。继续往下进到源码中：

```java
private void startBeans(boolean autoStartupOnly) {
    Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
    Map<Integer, LifecycleGroup> phases = new HashMap<>();
    lifecycleBeans.forEach((beanName, bean) -> {
        // 注意此处，如果autoStartupOnly为true，则不会执行
        if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
            int phase = getPhase(bean);
            LifecycleGroup group = phases.get(phase);
            if (group == null) {
                group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                phases.put(phase, group);
            }
            group.add(beanName, bean);
        }
    });
    if (!phases.isEmpty()) {
        List<Integer> keys = new ArrayList<>(phases.keySet());
        Collections.sort(keys);
        for (Integer key : keys) {
            // 依次调用Lifecycle的start方法
            phases.get(key).start();
        }
    }
}
```

这里面就是一个一个调用 `Lifecycle` 的 `start` 方法的位置了，但请小伙伴们注意一点：由于 `onRefresh` 方法中调用的 `startBeans(true);` 传入的参数是 **true** ，`lifecycleBeans.forEach` 部分不会执行，所以在该阶段不会回调 `Lifecycle` 的 `start` 方法！

### 3.3 ApplicationContext#start

那这些 `Lifecycle` 的 `start` 方法什么时候才能被调用呢？我们回到测试代码中：

```java
ctx.refresh();
System.out.println("================IOC容器刷新完毕==================");
ctx.start();

// ---------AbstractApplicationContext----------
public void start() {
    getLifecycleProcessor().start();
    publishEvent(new ContextStartedEvent(this));
}

// ---------DefaultLifecycleProcessor-----------
public void start() {
    startBeans(false);
    this.running = true;
}
```

下面我们主动的调用了 `ctx.start()` 方法，而 `ApplicationContext` 的 `start` 方法中调用的 `LifecycleProcessor` ，会最终调用 `startBeans(false);` ，激活 `Lifecycle` 回调的逻辑。

好，了解到 `Lifecycle` 真正回调的时机，下面我们还是看看 SpringFramework 是如何回调 `Lifecycle` 的。

#### 3.3.1 startBeans

```java
private void startBeans(boolean autoStartupOnly) {
    Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
    Map<Integer, LifecycleGroup> phases = new HashMap<>();
    lifecycleBeans.forEach((beanName, bean) -> {
        if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
            // 此处的phase可类比Order
            int phase = getPhase(bean);
            LifecycleGroup group = phases.get(phase);
            if (group == null) {
                // 不同的phase分到不同的group中
                group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                phases.put(phase, group);
            }
            group.add(beanName, bean);
        }
    });
    // ......
```

我们把 `startBeans` 方法分为两部分来看，前半段的操作很明显是一个分组的动作。这里面的 `phase` 可以类比为 `Order` ，`LifecycleGroup` 可以简单的理解为 `List<Lifecycle>` 。所以这个过程很明显，就是**将所有的** `**Lifecycle**` **按照不同的** `**phase**` **分组**而已。

#### 3.3.2 start

```java
    // ......
    if (!phases.isEmpty()) {
        List<Integer> keys = new ArrayList<>(phases.keySet());
        Collections.sort(keys);
        for (Integer key : keys) {
            // 
            phases.get(key).start();
        }
    }
}
```

分组之后，它会根据不同的 `phase` 排序后依次执行，而执行的 `start` 方法看上去比较复杂，最终还是调用 `Lifecycle` 的 `start` 方法：

```java
public void start() {
    if (this.members.isEmpty()) {
        return;
    }
    // logger ......
    Collections.sort(this.members);
    for (LifecycleGroupMember member : this.members) {
        doStart(this.lifecycleBeans, member.name, this.autoStartupOnly);
    }
}

private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName, boolean autoStartupOnly) {
    Lifecycle bean = lifecycleBeans.remove(beanName);
    if (bean != null && bean != this) {
        String[] dependenciesForBean = getBeanFactory().getDependenciesForBean(beanName);
        for (String dependency : dependenciesForBean) {
            doStart(lifecycleBeans, dependency, autoStartupOnly);
        }
        if (!bean.isRunning() &&
                (!autoStartupOnly || !(bean instanceof SmartLifecycle) || ((SmartLifecycle) bean).isAutoStartup())) {
            // logger ......
            try {
                // 【调用实现了Lifecycle接口的bean】
                bean.start();
            }
            // catch ......
        }
    }
}
```

等所有 `Lifecycle` 都执行完毕，一个 bean 的完整初始化生命周期也就结束了。

## 4. 总结

**bean 对象创建完成后，会进行属性赋值、组件依赖注入，以及初始化阶段的方法回调。在** `**populateBean**` **属性赋值阶段，会事先收集好 bean 中标注了依赖注入的注解（** `**@Autowired**` **、**`**@Value**` **、**`**@Resource**` **、**`**@Inject**` **），之后会借助后置处理器，回调** `**postProcessProperties**` **方法实现依赖注入。**

**属性赋值和依赖注入之后，会回调执行 bean 的初始化方法，以及后置处理器的逻辑：首先会执行 Aware 相关的回调注入，之后执行后置处理器的前置回调，在后置处理器的前置方法中，会回调 bean 中标注了** `**@PostConstruct**` **注解的方法，所有的后置处理器前置回调后，会执行** `**InitializingBean**` **的** `**afterPropertiesSet**` **方法，随后是** `**init-method**` **指定的方法，等这些 bean 的初始化方法都回调完毕后，最后执行后置处理器的后置回调。**

**全部的 bean 初始化结束后，**`**ApplicationContext**` **的** `**start**` **方法触发时，会触发实现了** `**Lifecycle**` **接口的 bean 的** `**start**` **方法。**
