ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

厚积薄发打卡Day81 :【MSUP】必会技术框架Spring(下)<从Spring初始化流程到SpringBoot>

2021-07-29 20:59:32  阅读:191  来源: 互联网

标签:初始化 SpringBoot beanFactory Spring Bean 接口 bean context 打卡


前言

在看狂神频道的时候偶然发现下图,感触颇深。特别在当今【程序 = 业务 + 框架】思想盛行的开发者中,夯实基础基础显得格外重要,因此开此专栏总结记录。
在这里插入图片描述

对于Spring框架的知识,已经在学习设计模式的时候练习过一轮,接下来不断温故而知新哈哈,学习记录回顾:

  1. 厚积薄发打卡Day47: [itcast] GoF23设计模式之<自定义SpringIOC>(上)
  2. 厚积薄发打卡Day48: [itcast] GoF23设计模式之<自定义SpringIOC>(下)

SpringContext初始化流程:(需阅读源码)

详见:

  1. Spring核心 ApplicationContext的加载过程
  2. 理解Spring容器、BeanFactory和ApplicationContext

在这里插入图片描述

  • 左上角是三种类型的context:

    • ClassPathXmlApplicationContext
    • SpringApplicationContext
    • WebApplicationContext

    在这里插入图片描述

  • 不论哪种context创建后都会调用AbstractApplicationContext 类的refresh 方法,这个方法是我们要重点分析的,在refresh 方法中:

    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();
            // Tell the subclass to refresh the internal BeanFactroy.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            // Prepare the BeanFactroy for use in this context.
            prepareBeanFactory(beanFactory);
            try {
                // Allows post-processing of the BeanFactroy in context subclasses.
                postProcessBeanFactory(beanFactory);
                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);
                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);
                // Initialize message source for this context.
                initMessageSource();
                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();
                // Initialize other special beans in specific context subclasses.
                onRefresh();
                // Check for listener beans and register them.
                registerListeners();
                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);
                // Last step: publish corresponding event.
                finishRefresh();
            }
            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                                "cancelling refresh attempt: " + ex);
                }
                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();
                // Reset 'active' flag.
                cancelRefresh(ex);
                // Propagate exception to caller.
                throw ex;
            }
            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
               ;
            }
        }
    }
    
    • 第一步,prepareRefresh();
      • 首先对刷新进行准备,包括设置开始时间,设置激活状态,初始化context 环境中的占位符,这个动作根据子类的需求由子类来执行,然后验证是否缺失必要的properties
    • 第二步,ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      • 刷新并获取内部的beanFactory
    • 第三步,prepareBeanFactory(beanFactory) 对Beanfactory 进行准备工作,
      • 比如设置类加载器和后置处理器,配置不能自动装配的类型,注册默认的环境Bean
    • 第四步,postProcessBeanFactory(beanFactory); 为context 的子类提供后置处理并factory 的扩展能力,
      • 如果子类想在并定义加载完成后,开始初始化上下文之前做一些特殊逻辑,可以复写这个方法
    • 第五步,invokeBeanFactoryPostProcessors(beanFactory) 执行context 中注册的BeanFactroy 后置处理器,这里有两种后置处理器:
      • 一种是可以注册bean 的后置处理器
      • 另一种是针对BeanFactroy 进行处理的后置处理器
      • 执行的顺序是先按优先级执行可注册并的处理器,然后再按优先级执行针对BeanFactroy 的处理器
      • 对SpringBoot来说这一步会进行注解bean definition 的解析,流程如右面的小框中所示
      • 由configuration class post processor 出发由classpathbeandefinitionscanner解析bean 注册到BeanFactroy
    • 第六步,registerBeanPostProcessors(beanFactory);
      • 按优先级顺序在BeanFactroy 中注册bean 的后置处理器,Bean后置处理器可以在Bean的初始化前后执行处理
    • 第七步,initMessageSource();
      • 初始化消息源,消息源用来支持消息的国际化
    • 第八步,initApplicationEventMulticaster();
      • 初始化应用事件广播器。事件广播器用来向application listener 通知各种应用产生的事件,是一个标准的观察者模式
    • 第九步,onRefresh();
      • 是留给子类的扩展步骤,用来让特定的context 子类来初始化其他的Bean
    • 第十步,registerListeners();
      • 把实现的application listener 的bean 注册到事件广播器,并对广播器中早期没有广播的事件进行通知
    • 第十一步,finishBeanFactorylnitialization(beanFactory);
      • 冻结所有的Bean人描述信息的修改实例化非延迟加载的单例Bean
    • 第十二步,finishRefresh();
      • 完成上下文的刷新工作,调用LifecycleProcessor 的on fresh 方法,以及发布context refresh 的event事件
    • 最后在finally 中执行第十三步,resetCommonCaches() 重置公共的缓存,
      • 比如ReflectionUtils中的缓存AnnotationUtils中的缓存等等
    • 至此,spring 的context 初始化就完成了,由于篇幅和时间的关系呢,这里介绍了最主要的流程,建议课后阅读源码来复习这个知识点,来补全细节

Spring中Bean生命周期:(需阅读源码)

在这里插入图片描述

面试中经常会问到Bean人的生命周期,我们先看绿色的部分:

  • Bean的创建过程:
    • 首先调用Bean的构造方法创建bean,然后通过反射调用setter 方法进行属性的依赖注入,
    • 第三步,如果实现了BeanNameAware接口的话,会设置Bean the name
    • 第四步,如果实现了BeanfactoryAware接口,会把Beanfactory 设置给bean
    • 第五步,如果实现ApplicationContextAware接口会给bean 设置application context
    • 第六步,如果实现了BeanPostProcessor 接口,则执行前置的处理方法
    • 第七步,实现了initialize bean 接口的话会执行after property set方法
    • 第八步,执行自定义的init的方法
    • 第九步,执行bean post processor 接口的后置处理方法
  • 这时就完成了bean 的创建过程,那么在使用完bean 需要销毁的时候,会先执行disposable bean 接口的destroy 方法
  • 然后再执行自定义的destroy 方法

这部分也建议你阅读源码来加深理解

Spring扩展接口:

这一页介绍对spring 进行定制化功能扩展时,可以选择的一些扩展点:

在这里插入图片描述

  • BeanFactoryPostProcessor是Beanfactory 的后置处理器
    • 支持在Beanfactory 标准初始化完成后,对并factory 进行一些额外处理
    • 我们在讲context 初始化流程时介绍过这,这时所有的Bean的描述信息已经加载完毕
    • 但是还没有进行Bean的初始化,例如,我前面提到的property placeholder configure 就是在这个扩展点上对bean 属性中的站位服务进行替换的
  • BeanDefinitionRegistryPostProcessor
    • 它扩展自BeanPostProcessor,在执行BeanPostProcessor的功能前提供了可以添加并定义的能力
    • 允许在初始化一般的Bean前注册额外的Bean
    • 例如可以在这里根据Bean的scope 创建一个新的代理Bean
  • BeanPostProcessor
    • 提供了在bean 初始化的之前和之后,插入自定义逻辑的能力
    • 与BeanFactoryPostProcessor的区别主要是处理对象不同,BeanFactoryPostProcessor是Beanfactory 进行处理
    • BeaPostProcessor是对Bean进行处理
  • 上面这三个扩展点可以通过实现ordered 或者priority ordered 接口来指定执行顺序,实现priority order 接口的processor 会先于实行order 接口的执行
  • ApplicationContextAware
    • 可以获得application context,以及其中的Bean当需要在代码中动态获取Bean时,可以通过实现这个接口来实现
  • InitializingBean
    • 可以在bean 初始化完成,所有属性设置完成后执行特定的逻辑
    • 例如对自动装配的属性进行验证等等
  • DisposableBean
    • 用于在并销毁前执行特定的逻辑
    • 例如做一些回收工作等等
  • ApplicationListener
    • 用来监听spring 的标准事件以及自定义的事件

SpringBoot扩展:

在这里插入图片描述

  • SpringBoot启动流程:

    • 首先要配置environment
    • 然后准备context 上下文
    • 包括执行application context 的后置处理器
    • 初始化initialize,通知listener 处理context prepared 和contextloaded 事件
    • 最后执行refresh context
    • 也就是我们前面介绍过的AbstractApplicationContext 类的refresh 方法
  • SpringBoot中有两种上下文:

    • 一种是bootstrap
      • bootstrap 是应用程序的父上下文,也就是说bootstrap 会先于application 加载
      • bootstrap 主要用于从额外的资源来加载配置信息,还可以从本地外部配置文件中解密属性
      • bootstrap 里面的属性会优先加载,默认也不能被本地相同的配置覆盖
    • 另一种是application
  • Springboot 的注解

    • 需要知道 SpringBootApplication,包含了三个注解:

      •   @SpringBootConfiguration
        
      •   @EnableAutoConfiguration
        
      •   @ComponentScan
        

      在这里插入图片描述

    • @SpringBootConfiguration注解里面包含了configuration 注解,也就是SpringBoot的自动配置功能
      在这里插入图片描述

    • conditional 注解是控制自动配置的生效条件的注解

      • 例如bean 或class 的存在或不存在时进行配置,当满足条件时进行配置等等
  • SpringBoot的几个特色模块:

    • starter 是SpringBoot提供的无缝集成功能的一种方式,使用某个功能时,开发者不需要关注各种依赖库的处理,不需要具体的配置信息,由SpringBoot的自动配置进行bean 的创建:
      • 例如需要使用web 功能时,只需要在依赖中引入SpringBootstarter web 即可
    • actuator 是用来对应用程序进行监控和管理,通过restful API 请求,来监管审计,收集应用的运行情况
      提供了一系列开发工具的支持来提高开发效率,
      • 例如热部署能力等等
    • cli 就是命令行接口,是一个命令行工具,支持使用groovy脚本,可以快速搭建spring 原型项目

标签:初始化,SpringBoot,beanFactory,Spring,Bean,接口,bean,context,打卡
来源: https://blog.csdn.net/qq_42191980/article/details/119220366

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有