zoukankan      html  css  js  c++  java
  • spring-boot源码分析之ConfigurableApplicationContext

    前言

    昨天我们说spring boot启动过程中有两块比较核心的内容,一个是监听器,一个就是spring boot容器(上下文),今天我们就先来看下springboot的容器,因为spring boot提供多个容器比较多,所以我们今天先来解下容器的基类(接口)——ConfigurableApplicationContext

    ConfigurableApplicationContext就是我们spring-boot最核心的内容——应用容器,run方法内部也基本都是针对它进行的各种初始化操作,运行完成后返回的也是它的实例,下面我们就梳理下它的属性和方法,对它做一个简单的了解。

    ConfigurableApplicationContext

    ConfigurableApplicationContext是一个基础接口,它是03.11.2003引入的(好早呀),内部包括7个静态常量,13给接口方法,同时它还继承了ApplicationContextLifecycleCloseable

    ApplicationContext是所有容器的基类,spring boot提供了很多容器的实现,这里我们目前只看默认的容器;Lifecycle是和类生命周期有关的接口,它的内部提供了三个方法,startstopisRunning

    静态常量

    • CONFIG_LOCATION_DELIMITERS:配置文件路径分隔符,主要用来分割各个配置文件路径的
    • CONVERSION_SERVICE_BEAN_NAME:转换服务的bean name,通过这个服务,我们则可以实现类型转换操作
    • LOAD_TIME_WEAVER_BEAN_NAMEspring boot加载期代码织入器的bean name,这个组件的作用主要是为spring boot自定义类加载器提供支持的
    • ENVIRONMENT_BEAN_NAME:环境的bean name
    • SYSTEM_PROPERTIES_BEAN_NAME:系统配置的bean name
    • SYSTEM_ENVIRONMENT_BEAN_NAME:系统环境变量bean name
    • SHUTDOWN_HOOK_THREAD_NAME:关闭钩子函数线程名称

    接口方法

    • setId:设置应用容器的唯一id
    • setParent:设置父级容器(上下文)
    • setEnvironment:设置当前容器环境变量
    • getEnvironment:返回此应用程序上下文的环境,允许进一步自定义
    • addBeanFactoryPostProcessor:添加BeanFactoryPostProcessorBeanFactoryPostProcessor功能比较强大,它可以修改容器的内部bean factory,改变bean的创建
    • addApplicationListener:添加容器监听器,主要是指继承了ApplicationListener的监听器
    • setClassLoader:设置类加载器
    • addProtocolResolver:注册协议解析器。协议解析器的作用就是根据指定的地址和资源加载期,解析资源并将资源返回
    • refresh:加载或者刷新配置持久化代理,它的来源可以是java基础配置、 xml文件、属性文件、数据库或者其他文件格式。根据官方文档描述,refresh是一个启动方法,如果执行失败,它会销毁已经创建的单例,以避免悬空资源。也就是说,在调用这个方法之后,要么全部实例化,要么根本不实例化。
    • registerShutdownHook:注册关闭钩子函数
    • close:关闭容器
    • isActive:获取容器是否活跃
    • getBeanFactory:获取bean factory

    父类方法

    • getId:获取容器id
    • getApplicationName:获取应用名称
    • getDisplayName:获取应用展示名称
    • getStartupDate:获取启动时间
    • getParent:获取父类容器
    • getAutowireCapableBeanFactory:获取自动装备bean工厂,根据官方给出的解释,这个方法主要给spring boot外部使用的,便于我们将非spring bootbean装配进spring boot容器中。

    下面我们简单调几个方法看下效果:

    然后我们再调一下close方法看下:

    根据输出的日志我们可以看出来,执行完close方法之后,容器成功关闭,关闭之前isActivetrue,关闭之后变成了false。我们调用close方法实际上调用的是关闭的钩子函数:

    另外,在测试过程中,我发现bean注入容器是在refresh方法中进行的,但是目前还没有梳理清楚。

    总结

    今天这些内容搞完之后,我发现我有点懵逼了,spring boot的启动过程还是很复杂的,特别是容器的初始化过程,虽然看起来就只是基于ConfigurableApplicationContext,但事实上涉及到的内容特别多,比如BeanFactoryPostProcessorApplicationListenerProtocolResolver等,这些组件每一个都是有着比较复杂的实现,以前真的只考虑用了,也从来不考虑它的内部是如何实现的,只有实际去看源码的时候,才发现类与类、类与接口、接口与接口关系原来是如此的复杂,感觉想梳理清楚真的好难。

    不过幸运的是,经过这几天的摸索,阅读晦涩的源码,debug代码,我发现一天要比一天容易一点。我现在就感觉自己好像在挖宝藏,只能一点一点刨,但是目前刨出来东西还不足以让我看清spring boot的全貌,不过我相信随着不断的深入探索和研究,未来一切都会更清晰,当然后面我应该是不会再贪多了,分析源码本来就是一个费力花时间还不出活的过程,只能一点点地啃了。

    最后,我特别想知道各位小伙伴最希望我分享哪方面的知识,可以给我私信或者留言,我现在基本上都是自己想到哪分享到那,所以内容上可能不一定符合各位小伙伴的口味和节奏,如果你能说出自己的需求或者想法,那这个学习过程才意思,你说呢?

    好了,今天就先到这里吧!

  • 相关阅读:
    Linux学习50 进程优先级、网络客户端工具、shell循环(续Linux学习49)
    Linux学习51 CentOS系统启动流程介绍
    Linux学习49 资源管理三板斧-htop、vmstat、dstat实战
    【Kafka】CAP理论以及CAP定律
    【Kafka】Flume整合Kafka
    【Kafka】配置文件说明
    【Kafka】JavaAPI操作
    【Kafka】Stream API
    【Kafka】Consumer API
    【Kafka】Producer API
  • 原文地址:https://www.cnblogs.com/caoleiCoding/p/15232221.html
Copyright © 2011-2022 走看看