转载

spring的加载(spring系列文章入口)

描述

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个

spring的加载(spring系列文章入口)

观察后处理器个数:2个

spring的加载(spring系列文章入口)

已经创建的bean:0个

spring的加载(spring系列文章入口)

到第5步:调用bean工厂的后处理器invokeBeanFactoryPostProcessors(beanFactory);

观察bean定义个数:9个

spring的加载(spring系列文章入口)

观察后处理器个数:3个

spring的加载(spring系列文章入口)

已经创建的bean:2个

spring的加载(spring系列文章入口)

调用完成之后bean定义变多了,说明在这个步骤新增了bean定义。实际上spring在这个步骤处理了配置类,根据配置类中的配置将所有的bean定义注册到bean工厂中。

invokeBeanFactoryPostProcessors(beanFactory)方法详解

第6步: 调用bean的后处理器,将所有的后处理器添加到beanfactory中

registerBeanPostProcessors(beanFactory);

观察bean定义个数:9个

spring的加载(spring系列文章入口)

观察后处理器个数:8个

spring的加载(spring系列文章入口)

已经创建的bean:5个

spring的加载(spring系列文章入口)

在这个步骤完成了后处理器的注册和部分bean的创建。

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

执行前

spring的加载(spring系列文章入口)

执行后

spring的加载(spring系列文章入口)

这一步结束了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后处理器

原文  https://segmentfault.com/a/1190000022534665
正文到此结束
Loading...