Spring 源码 -- Spring 初始化

本文最后更新于:4 个月前

入口代码

package ind;

import ind.config.SpringConfig;
import ind.dao.TestDao;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author yinchao
 */
public class Main {
    public static void main (String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
        /* refresh 方法用于初始化 Spring 容器 */
        annotationConfigApplicationContext.refresh();
        TestDao bean = annotationConfigApplicationContext.getBean(TestDao.class);
        bean.query();
    }
}

调用链

  1. AnnotationConfigApplicationContext

    这个类就完成了 Spring 的初始化

    1. 先执行他的父类 GenericApplicationContext 的构造方法

      这个类是 Spring 上下文的环境

      1. 构造函数中一个成员变量 DefaultListableBeanFactory 被初始化

        这个类是 Spring 的 Bean 工厂,里面有很多生成 Bean 所需要的原料

        例如:用于存放 BeanName 和 BeanDefinition [1] 的 beanDefinitionMap

        按照 Beam 的注册顺序组合的 BeanName 的 list

        其他成员不一一列举 …

    2. 继续在 AnnotationConfigApplicationContext 构造函数中有一个成员 AnnotatedBeanDefinitionReader 开始初始化

      这个 reader 的作用就是作为一个注册器来向 Spring 注册一个 bean

      AnnotatedBeanDefinitionReader1

      可以根据上图的 AnnotationConfigApplicationContext3 中看到,new AnnotatedBeanDefinitionReader(BeanDefinitionRegistry) 传入的参数是 this,即这个 AnnotationConfigApplicationContext 就是一个 BeanDefinitionRegistry,也可以通过图片 AnnotationConfigApplicationContext1 看到这个类本来就实现了 AnnotationConfigRegistry 接口 。

      1. 构造继续委托到 AnnotationConfigUtils 的 registerAnnotationConfigProcessors 方法

        AnnotatedBeanDefinitionReader2

    3. AnnotationConfigApplicationContext 构造函数中另一个成员 ClassPathBeanDefinitionScanner 开始初始化

      他能够扫描 BeanDefinition,能够扫描一个类或者包,并且转换成BeanDefinition

  2. AnnotationConfigApplicationContext 构造函数结束,完成类初始化之后,调用 register 方法

    进一步调用

  3. AnnotationConfigApplicationContext 调用 refresh() 方法

    这个方法主要是准备好 Bean 工厂,并实例化 Bean 对象

    1. prepareBeanFactory() 方法

      最后的 addBeanPostProcessor 方法只是把一个 BeanPostProcessor 实例加入到 BeanFactory 里面维护的一个 BeanPostProcessor 后置处理器 list 列表中

      在 Bean 的实例化过程中会依次循环调用这个 list 中的 BeanPostProcessor 对象的方法

    2. invokeBeanFactoryPostProcessors() 方法

      1. 最后循环调用接口的实现类的接口重写方法,例如对于 ConfigurationClassPostProcessor 类:

        主要函数逻辑:

        1. checkConfigurationClassCandidate 方法

        2. isLiteConfigurationCandidate 方法

        3. 又是一个空壳 parse 函数调用

          ConfigurationClassPostProcessor_parse

          被调函数:

          1. 继续调用 doProcessConfigurationClass 方法实现主要逻辑

            1. parse 方法处理 @ComponentScan 注解的属性信息,例如 basePackage 等

              1. doScan()

                1. findCandidateComponents 方法又调用 scanCandidateComponents,而这个方法最后实现了扫描 Bean 的主要逻辑,可以自己模拟一遍,此处不特别展示

                2. 其中调用的 registerBeanDefinition() 就是 BeanDefinitionReaderUtils 的 registerBeanDefinition 方法 (之前分析过),将 Bean 加入到工厂里面

附录: Spring 扩展点[2]


  1. BeanDefinition: 是用于描述 Bean 的类。例如我们用 User.java (userName,password …) 是现实世界中对 用户 这个对象的抽象描述,而用 Class.java 来描述各种各样的 Java 类 (name,classLoader,useCaches …),同理, BeanDefinition (isPrimary,isLazyInit,getFactoryBeanName …) 就是用来描述交给 Spring 管理的 Bean。 ↩︎

  2. Spring 扩展点:

    1. BeanPostProcessor
    2. BeanFactoryPostProcessor
    3. BeanDefinitionRegistryPostProcessor
    4. FactoryBean
    ↩︎