您当前的位置: 首页 >  spring

止步前行

暂无认证

  • 0浏览

    0关注

    247博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

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

止步前行 发布时间:2021-11-22 08:57:10 ,浏览量:0

文章目录
  • 一、引言
  • 二、new AnnotationConfigApplicationContext()
  • 三、register(AppConfig.class)
  • 四、refresh()

一、引言

经过前面一系列文章对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()

关注
打赏
1657848381
查看更多评论
立即登录/注册

微信扫码登录

0.0384s