Spring源码系列(十一)——Spring源码总结

一、引言

经过前面一系列文章对Spring的源码分析,终于知道Spring容器启动过程中做了哪些事情,下面就来最这个过程进行宏观上的总结。测试代码只需三行,就可以完成Spring容器的启动和扫描工作,下面对三行代码都做了哪些操作进行大概描述。

public static void main(String[] args) {
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
    ac.register(AppConfig.class);
    ac.refresh();
}

二、new AnnotationConfigApplicationContext()

创建AnnotationConfigApplicationContext容器,在这个过程中会做3件事情。

AnnotationConfigApplicationContext ac= new AnnotationConfigApplicationContext();
  • 这里会调用父类(GenericApplicationContext)的构造函数,创建一个DefaultListableBeanFactory容器工厂

  • 创建一个AnnotatedBeanDefinitionReader读取器,在这过程中会向Spring容器中填加了6个Spring的后置处理器:BeanFactoryPostProcessorBeanPostProcessor

    org.springframework.context.annotation.internalConfigurationAnnotationProcessor—>(BeanFactoryPostProcessor)

    org.springframework.context.annotation.internalAutowiredAnnotationProcessor—>(BeanPostProcessor)

    org.springframework.context.annotation.internalRequiredAnnotationProcessor—>(BeanPostProcessor)

    org.springframework.context.annotation.internalCommonAnnotationProcessor—>(BeanPostProcessor)

    org.springframework.context.event.internalEventListenerProcessor

    org.springframework.context.event.internalEventListenerFactory

  • 创建一个ClassPathBeanDefinitionScanner扫描器,这个扫描器可以用来扫描包或者类,将扫描到的类转换成BeanDefinition,但是实际上完成我们扫描包工作并不是这个scanner对象来完成的,而是Spring自己new的一个ClassPathBeanDefinitionScanner

三、register(AppConfig.class)

注册一个配置类,其实这步操作可以和上面创建容器操作合为一步。

annotationConfigApplicationContext.register(AppConfig.class);
  • 将配置类转化为一个BeanDefinition,给BeanDefinition里面的属性确定值

四、refresh()

这个容器刷新方法非常非常非常重要!!!也最难理解,总结不对的地方,请指正出来。

annotationConfigApplicationContext.refresh();
public void refresh() throws BeansException, IllegalStateException {

    // 准备工作,包括设置启动时间,是否激活标识位,初始化属性源(property source)配置
    prepareRefresh();

    // 返回一个factory 为什么需要返回一个工厂? 因为要对工厂进行初始化
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

    // 准备工厂
    prepareBeanFactory(beanFactory);

    // 这个方法在当前版本的spring是没用任何代码的,可能spring期待在后面的版本中去扩展吧
    postProcessBeanFactory(beanFactory);

    // 调用BeanFactoryPostProcessors的后置处理器
    invokeBeanFactoryPostProcessors(beanFactory);

    //-------------------到此spring工厂完成创建工作--------------------------

    // 注册BeanPostProcessor后置处理器
    registerBeanPostProcessors(beanFactory);

    initMessageSource();

    // 初始化应用事件广播器
    initApplicationEventMulticaster();

    onRefresh();

    registerListeners();

    finishBeanFactoryInitialization(beanFactory);

    finishRefresh();
}

每个方法做了哪些工作,下面逐一总结。

  • prepareRefresh()

    • 准备工作,包括设置启动时间,是否激活标识位,初始化属性源(property source)配置
  • ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()

  • prepareBeanFactory(beanFactory)

    • 添加一个后置管理器:ApplicationContextAwareProcessor,能够在Bean中获得到各种*AwareAware都有其作用),重要!!!【直接创建添加到BeanPostProcessors中】
    • 添加一个后置管理器:ApplicationListenerDetector,【直接创建添加到BeanPostProcessors中】
    • singletonObjects中添加了systemEnvironment
    • singletonObjects中添加了environment
  • singletonObjects中添加了systemProperties

  • postProcessBeanFactory(beanFactory)

    • 这个方法在当前版本的Spring是没用任何代码的,可能Spring期待在后面的版本中去扩展吧
  • invokeBeanFactoryPostProcessors(beanFactory)

    调用BeanFactoryPostProcessors的后置处理器,设置执行自定义的ProcessorBeanFactory和Spring内部自己定义的

    • 执行程序员自定义(手动add)的实现BeanDefinitionRegistryPostProcessor接口中的postProcessBeanDefinitionRegistry()【程序员自己手动add】
    • 执行Spring内部自己实现了BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry()—>【上面添加的6个中,只有这个ConfigurationClassPostProcessor,该类中完成了Spring的扫描工作】
    • 执行程序员自己实现BeanDefinitionRegistryPostProcessor接口的类postProcessBeanDefinitionRegistry(),被扫描进来的【用注解@Component修饰】
    • 执行BeanFactoryPostProcessor的子类BeanDefinitionRegistryPostProcessorpostProcessBeanFactory()Spring内部自己添加、或者扫描到的】
    • 执行程序员自定义(手动add)的BeanFactoryPostProcessor的中postProcessBeanFactory()
    • 执行Spring内部自己实现了BeanFactoryPostProcessor接口或扫描到实现该接口类中的postProcessBeanFactory()

------------------------------------到此Spring工厂完成创建工作------------------------------------

  • registerBeanPostProcessors(beanFactory)

    注册BeanPostProcessor后置处理器

    • 实例化所有BeanPostProcessor,放入到singletonObjects中和beanPostProcessors中【所有包括,Spring一开始自己添加的,程序员自己手动add,包扫描到的三种情况】
  • initMessageSource()

  • 实例化一个消息源,放入到singletonObjects

  • initApplicationEventMulticaster();

    初始化应用事件广播器

    实例化一个事件广播器applicationEventMulticaster,放入到singletonObjects

  • onRefresh()

    在SpringBoot中,这个方法中创建了Tomcat

  • registerListeners()

  • 将监听器添加到applicationEventMulticaster事件广播器中

  • finishBeanFactoryInitialization(beanFactory)

    实例化所有的单例的非懒加载的Bean

    • 遍历this.beanDefinitionNames,根据beanName获取BeanDefinition
      • singletonObjects中获取bean,如果不为空直接返回,不再进行初始化工作
      • 判断是不是FactoryBean,如果是,则直接创建FactoryBean,如果不是,则创建普通Bean【此处要注意获取FactoryBean中真实对象的情况,此处要注意!!!!
        • 如果给定Bean的定义是子Bean定义,则通过与父Bean合并,返回给定顶级BeanRootBeanDefinition
        • 获取所依赖的Bean,保证对当前Bean所依赖的Bean进行初始化【此处是递归调用getBean()方法】
        • createBean()
          • InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()【第一次调用BeanPostProcessor后置处理器】
          • doCreateBean()
            • createBeanInstance()

              • 使用适当的实例化策略,为指定的bean创建一个新实例:工厂方法、构造函数自动装配,简单实例化
              • SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors()【第二次调用BeanPostProcessor后置处理器】
              • 创建Bean实例
            • MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition()【第三次调用BeanPostProcessor后置处理器】

            • SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference()【第四次调用BeanPostProcessor后置处理器】

            • populateBean()设置属性

              • InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()【第五次调用BeanPostProcessor后置处理器】
              • InstantiationAwareBeanPostProcessor#postProcessPropertyValues()【第六次调用BeanPostProcessor后置处理器】
              • initializeBean()初始化
                • invokeAwareMethods()判断Bean是不是实现了Aware接口
                • BeanPostProcessor#postProcessBeforeInitialization()【第七次调用BeanPostProcessor后置处理器】
                • invokeInitMethods()调用初始化方法
                  • 实现InitializingBean接口的话,调用afterPropertiesSet()
                  • init-method方法的话,调用此自定义方法
                • BeanPostProcessor#postProcessAfterInitialization()【第八次调用BeanPostProcessor后置处理器】
  • finishRefresh()

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

止步前行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值