描述

resource:资源,程序员做的配置。
beanDefinition:bean定义,spring内部描述bean的对象。
bean:对象
beanfactory:也是一个对象,可以理解为做管理工作的对象。

开始了

spring代码中注解方式初始化上下文的方式,传入一个配置类,spring的大门就从这个地方打开。

        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MainConfig.class);

具体的构造函数

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//调用另外一个构造方法,注册一个reader和scanner
        this();
        //把传入的配置类注册为一个bean
        register(annotatedClasses);
        //refresh方法
        refresh();
    }

无参构造函数this();

public AnnotationConfigApplicationContext() {
        this.reader = new AnnotatedBeanDefinitionReader(this);
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }
  1. 注册了一个reader和scanner用于扫描类和加载类(资源扫描和加载)
  2. register方法把传入的配置类注册为一个bean定义(这是一个入口)。先注册配置类,然后一配置类为入口开始解析,一步接一步地将所有的bean定义解析出来。
详细分析部分

refresh()方法,refresh方法开始一步一步解析。贴上代码,方便观看理解把原英文注释删除掉了。

public void refresh() {
        //1. 准备刷新上下文,bean工厂的初始化工作
            prepareRefresh();
        //2. 得到一个bean工厂
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        //3. 对bean工厂进行数据填充
            prepareBeanFactory(beanFactory);
        //4. 允许在上下文子类中对bean工厂进行后处理。
            postProcessBeanFactory(beanFactory);
        //5. 调用bean工厂的后处理器
            invokeBeanFactoryPostProcessors(beanFactory);
        //6. 调用bean的后处理器
            registerBeanPostProcessors(beanFactory);
        //7. 初始化国际化资源处理器
            initMessageSource();
         //6. 初始化事件多播器   
            initApplicationEventMulticaster();
         //7. 初始化一些特殊的bean
            onRefresh();
         //8.注册监听器       
            registerListeners();
         //9.完成所有bean的初始化,(@lazy注解的除开)
            finishBeanFactoryInitialization(beanFactory);
         //10.最后一步,发布相应的事件
            finishRefresh();
    }

通过观察beanFactory的状态开始分析,beanfactory中有很多的属性,每个步骤只截取需要关注的,以下步骤截图都来自debug模式观察beanfactory的属性。

1-4步都是在准备beanfactory,beanfactory中有初始的6+1个bean定义,6个初始的加上我们传入的config类。
观察bean定义个数:7个
image.png
观察后处理器个数:2个
image.png
已经创建的bean:0个
image.png

到第5步:调用bean工厂的后处理器invokeBeanFactoryPostProcessors(beanFactory);
观察bean定义个数:9个
image.png
观察后处理器个数:3个
image.png
已经创建的bean:2个
image.png
调用完成之后bean定义变多了,说明在这个步骤新增了bean定义。实际上spring在这个步骤处理了配置类,根据配置类中的配置将所有的bean定义注册到bean工厂中。
invokeBeanFactoryPostProcessors(beanFactory)方法详解


第6步: 调用bean的后处理器,将所有的后处理器添加到beanfactory中
registerBeanPostProcessors(beanFactory);
观察bean定义个数:9个
image.png
观察后处理器个数:8个
image.png
已经创建的bean:5个
image.png
在这个步骤完成了后处理器的注册和部分bean的创建。

第10步:finishBeanFactoryInitialization(beanFactory); 完成所有bean的初始化,(@lazy注解的除开),bean定义和后处理器在这个步骤都不会变化,观察已经创建的bean。
执行前
image.png
执行后
image.png

这一步结束了beanfactory的初始化。beanfactory是spring的管理容器,容器里面装了很多的东西。结束beanfactory的初始化之后,意味着spring的大部分初始化工作,需要加载的bean就完成了。

第11步:finishRefresh(); 最后一步,发布相应的事件。

完成!

spring的整体工作简要描述:

  1. 将资源文件转换为bean定义。(从配置->spring内部描述的转变BeanDefinition)
  2. bean定义转换为bean。(内部描述->实际的对象)
  3. 后处理器。(处理事情的入口)
    3.1 bean工厂的后处理器。
    3.2 bean的后处理器。
  4. 监听器和多播器系统。(事件发布和事件广播)

总结

spring将程序员配置的信息转换为一个富含很多功能的对象(上下文/beanfactory),并把对象提供给程序员使用。

继续理解bean后处理器

李沁春
17 声望1 粉丝

喜欢运动,骑行、打羽毛球、打乒乓球等。也喜欢打桌游,玩狼人杀、剧本杀等烧脑游戏。