题语:学习方法之多思考:正向、逆向、跳跃
作者:A哥(YourBatman)
wx号:fsx641385712(备注“Java群”字样)
公众号:BAT的乌托邦(ID:BAT-utopia)

代码下载地址:https://github.com/f641385712/netflix-learning

目录

    • 前言
    • 正文
      • Spring Boot整合Spring Cloud
      • 概念辨析
        • 应用 vs 上下文 vs 容器
          • 应用Application
          • 上下文Context
          • 容器
        • 父容器 vs 子容器
        • Environment环境
          • 属性源
            • 我该如何记忆Spring Boot属性优先级?
            • 附:Spring Boot所有版本外部化配置一览
        • 2020-11-22新增
        • application.yaml vs bootstrap.yaml
    • 总结
  • 关注A哥

前言

各位小伙伴大家好,我是A哥。通过上文 为何我决定写Spring Cloud专栏 一方面了解了A哥的“创作背景”;另一方面,当然也是最主要的便是我们已经初步了解了Spring Cloud Context工程,并且对它的spring.factories文件做了介绍,从中是能窥探出SC的核心组成“元素”的。

天若有情天亦老,人间正道是沧桑。接下来会进入到“枯燥乏味”的修行当中,坚持下来的都是英雄。准备深入去了解Spring Cloud,BootstrapApplicationListener无疑是它的第一入口,然而在这之前,我们依旧需要扫除一些“障碍”。


正文

关于Spring Boot整合,请看我在度娘上的搜索推荐结果:


Spring Boot整合Spring Cloud

众所周知,Spring Cloud是构建在一个Spring Boot应用的基础之上的,广义上说可以认为是SB应用把Spring Cloud整合进来了。谈到技术整合相信各位小伙伴轻车熟路:Redis整合、ElasticSearch整合、MyBatis整合…Spring Cloud的整合方式有点不太一样。SC它并非作为一个组件那么直接的加入到Spring Boot的ApplicationContext上下文/容器里即可,而是拥有自己一套独立的ApplicationContext上下文,然后通过上下文之间的关系(父子关系)完成和Spring Boot的“整合”。

如果说Mybatis、Redis这种整合方式是单个、直接方式;那么Spirng Cloud这种便是批量的、间接的方式,而正因为Spring Cloud有自己的Context上下文,所以它自己也就拥有整合其它组件的能力,这是非常重要的。

其实把Eureka、Hystrix、Ribbon等和Spring Boot直接整合也是可行的,但是这并不符合SB单应用的定位,并且Spring Framework和Spring Boot团队并不擅长解决和网络、云计算相关的技术,因此专门开设Spring Cloud子项目负责“接管”,保证了Spring Boot的纯粹性


概念辨析

在正式开始Spring Cloud内容学习之前,我觉得有几个概念性的知识点需要先辨析一下,这个工作很有必要。


应用 vs 上下文 vs 容器

作为一个Java coder,这三个概念应该是常绕耳边的。不可否认,这三个概念非常重要,它亦会在本系列文章中贯穿始终,因为它就是用来沟通的“语言”嘛。但是,常常听见并不代表真的理解,特别这种“近义词”,本处就对这几个概念作出辨析。

以个人理解作出的小总结,若有误请留言指正,A哥一直都是个虚心向任何人学习的好孩纸


应用Application

应用是个比较大概念,比如一个QQ、微信我们均可称为是一个应用,而此处我们一般指的是Spring应用。比如我们一个Spring Boot工程就是一个SpringApplication实例,也就是一个Spring应用,另外它也称为主应用,一个工程主应用只会有一个

通常来讲,一个应用只有一个上下文,所以应用和上下文这两个概念常常被误以为是对等的,其实非也,他俩并非同一层面的东东。举个例子:以Spring Boot为例,有些监听器注册在SpringApplication应用上作用于监听应用的变化(如生命周期监听器、初始化器等),它们并没有放进Spring容器内所以对上下文无感;而有些监听器是被放进容器里的,它的作用区域便就是和容器、Bean相关喽

另外,需要知道的是SB和SC的context上下文均是通过SpringApplication来构建的,但该SpringApplication实例在构建出Context后一般随即就“消失了”,这也是很多小伙伴误认为应用 == 上下文的原因之一吧;另外,父子容器概念属于context上下文级别非应用级别


上下文Context

同理,我们一般指的是Spring上下文,也就是ApplicationContext。在SB/SC里,实际使用的是ConfigurableApplicationContext的子类:AnnotationConfigServletWebServerApplicationContextAnnotationConfigApplicationContext(前者由Spring Boot提供,后者由Spring Framework提供)。ApplicationContext是具有层级关系(父子关系)的,ApplicationContext#getParent()证明了这一点。

ApplicationContext上下文里的内容非常“丰富”,如Environment环境、BeanFactory工厂、协议解析器等等它都有,毕竟具备这些能力才算一个“合格的”上下文嘛。另外针对于在SC环境下的上下文情况需要有如下共识:

  • SB和SC各自拥有一个独立的上下文,它们之前互相隔离却又有联系:SC上下文是SB的父上下文

容器

容器这个概念就更抽象了,在Java界也有不少如web容器、servlet容器等等,但是大多数情况下(包括本系列文章)我们一般指的是IoC容器,也就是Spring容器。

说明:IoC容器的实现其实不仅仅只有Spring,还有也比较流行的Google的开源库Guice,也是个非常好用轻量级DI管理库,有一些第三方开源组件如Eureka、Ribbon、Druid等都是基于它构建的,有兴趣可自己玩玩,也可参考我文章有写到~

对于Spring容器,我们有时候也叫它Bean工厂,也即是BeanFactory嘛。实际上ApplicationContext继承了BeanFactory接口,所以也是个容器(高级别容器),因此在概念上:上下文和容器这两个概念一般是可以对等的

  • 槽点:Spring的Bean容器为毛命名为BeanFactory而不是BeanContainer呢?

对于一个应用(如SB应用),ApplicationContext上下文/容器是可以有多个的。上下文之间的“隔离性”是很好的,后面会看到Ribbon、Feign等它们均会有自己的上下文,也就是学SC一样,通过上下文级别间接的完成和Spring Boot应用的整合。

那么问题来了:何时直接整合?何时需要自己创建一个上下文来管理呢?该问题就作为课后作业,留给读者你自行思考哈~


父容器 vs 子容器

父子关系是一种分层思想,被广泛应用于Spring容器/上下文的组织中,如HierarchicalBeanFactoryApplicationContext#getParent()能证明Spring的上下文也是具有层级结构的。

同义词:父上下文、子上下文。但是切记不可说成父应用和子应用,因为一个Spring Boot工程只会有一个应用,而一个应用内可以有N多个上下文,它们之间可以有关,亦可无关,这是合理的。


Environment环境

一般我喜欢叫它Spring的环境抽象,该“实例”代表着上下文的运行环境,主要包含如下三部分内容:

  1. PropertySource:属性源。key-value属性对抽象。环境内会有多个属性源,使用MutablePropertySources来组织
  2. PropertyResolver:属性解析器。用于解析相应key的value,比如你熟悉的PropertySourcesPropertyResolver就是实现
  3. Profile:配置(资料里翻译为剖面、侧面,也是阔仪的)。只有激活的配置profile的组件/配置才会注册到Spring容器,类似于maven中profile

Environment抽象Spring一共提供了三个实现类:

  • 用于非web环境的:StandardEnvironment
  • 用于web环境的:StandardServletEnvironmentStandardReactiveWebEnvironment,他俩均为StandardEnvironment的子类。
    • 需要注意的是:后者StandardReactiveWebEnvironment由Spring Boot提供,而非Spring Framework源生

这里小带一句:很多同学把属性和配置傻傻分不清楚,其实他俩就是Properties(k-v)和Profile概念上的差异,但口头上经常混用,一般可认为讲的是同一回事,但是你心里必须清楚哈。毕竟和专业人士聊起来的时候,还是需要这些细节掌握的

尴尬爆料:今天猛然发现,之前好多文章里我把Environment单词写错了,写为了Enviroment,特此提醒各位不要“学我”哦


属性源

Spring通过Environment建模Spring应用运行的环境,这其中最为重要的非属性源莫属。一个属性源就是一个PropertySource,它可以来自任意地方,如常用的有:

  • systemProperties -> 来自 system.getProperties()
  • systemEnvironment -> system.getenv()
  • random -> 来自一个Random对象,可用于生成随机数(SB提供)
  • applicationConfig: [classpath:/application.yaml] -> SB主配置,这个太常见了吧

属性源的优先级决定了配置的优先级。Spring Boot对其外部化配置优先级有文档说明:Spring Boot外部化配置


我该如何记忆Spring Boot属性优先级?

答案:不要记。精确答案:不要强记,因为“记不住”的。我见过不少(非常多)小伙伴一遇到需要考虑Spring Boot属性优先级问题时,整头就大了,立马拿出自己的小本本,又或者去度娘里查,或许那会还在内心里骂自己:怎么老是记不住呢?甚至质疑自己:是不是真的老了?

我说的此现象,你是否躺枪?授之以鱼不如授之以渔,对于这种“高难度、易出错”的知识点,浮于表面总觉浅,掌握其本质才是永恒。当然我这里不会去详讲Spring Boot这块的知识点,但我还是呕心沥血的整理出一堆截图,告诉你为何你强行记忆是记不住的(如果你是“天才”你就可以跳过本文了):


附:Spring Boot所有版本外部化配置一览

Spring Boot从它的1.0.x版本到现在的2.2.x版本,对于外部化配置的支持几乎是一直在变化/增加的,这种不确定性也无疑在一定程度上增加了我们记忆的难度。下面我从其官方文档截图出了它所有版本(请忽略小版本号)对应的支持的外部化配置情况:

说明:以下所有截图都来自Spring Boot官方文档的外部化配置Externalized Configuration部分,优先级从高到低

1.0.0.RELEASE(7个):


1.1.0.RELEASE(9个):@PropertySource优先级有调整,增加了JNDI和random属性源支持

1.2.0.RELEASE(9个):


1.3.0.RELEASE(12个):增加了JSON格式配置、支持-{profile}.xxx格式的配置


1.4.0.RELEASE(15个):增加了@TestPropertySource支持、ServletConfig和ServletContext属性源的支持


1.5.0.RELEASE(17个):增加了对调试工具@Devtools配置的支持、@SpringBootTest#properties的支持


2.0.0.RELEASE(17个):

2.1.0.RELEASE(17个):

2.2.0.RELEASE(17个):从2.2.0版本后,官方文档采用H5来重写了,所以页面风格整体上有所改变(更高级些了有木有)

此处对@PropertySource属性源增加了文字解释:它在refresh()容器之前,该属性源是不会放进Environment里面的,也就是说在容器启动之前请不要使用它里面的k-v,这在日常使用请你务必注意~

从这能看出Spring Boot对外部化配置发展的脉络。即使从1.5.0版本后,外部化配置趋于稳定,但谁知道以后呢?对吧~况且,17个耶,你真记得住?最为致命的是:如果你的工程接入配置中心来获取配置,又或者你二次开发自定位你配置的位置,它们都还不在这17个行列里,那肿么办?怎么判断属性优先级呢?所以嘛,像这种case,不要强记,不要强记,不要强记。

2020-11-22新增

截至此时,Spirng Boot 2.4.0已经发布,它带来了全新的配置文件加载机制,不具备向下兼容性,因此本处特别的过来加上。

它官网对配置文件顺序描述也发生了变化,如下图:

阅读此部分配置项需要注意:

  1. 文档中排列顺序不同于以往,这里是倒序(既最后面的是优先级越高的),请查看时注意哦
  2. Config data(序号是3)被当作一个整体参与排序,它内部维持着自己的顺序,这样更方便理解了嘛
  3. 总的算下来还是17种方式(14 - 1(序号3) + 4(序号3的详细) = 17)

Spring Boot自2.4.0版本后对配置文件的加载方式完全不同于以往,具体原理分析、使用注意事项、迁移指导等,请参见此系列文章的详解:Spring Boot 2.4.0正式发布,全新的配置文件加载机制(不向下兼容)


application.yaml vs bootstrap.yaml

对于它俩的比较理应放在最后,但这里先睹为快。

  • application.yaml/properties被Spring Boot容器读取,也常常被我们称为主配置
  • bootstrap.yaml/properties被Spring Cloud容器读取,也常常被我们称为引导配置

bootstrap.yaml优先于application.yaml被加载。虽然前者是给Spring Cloud专用的,但是这个属性源最终也会“合并”到Spring Boot的属性源里面去,并且优先级高于application.yaml,所以Spring Boot里也可以使用。

说明:application.yaml里的属性,SC可是完全触碰不到的~


总结

本文有种复习Spring Framework的赶脚,因为大部分概念都是“老的”,但也是最为核心的。以上概念多多少少都会和整合扯上点关系,后面会有所体现。

为何我觉得概念理解如此重要?我觉得概念就像是用于沟通的语言,只有做到感念一致性沟通起来才能顺畅,因此我才觉得在系列开头穿插着书写本文是很有必要的,磨刀不误砍柴工嘛。

尴尬爆料:今天猛然发现,之前好多文章里我把Environment单词写错了,写为了Enviroment,特此提醒各位不要“学我”哦


关注A哥

Author A哥(YourBatman)
个人站点 www.yourbatman.cn
E-mail yourbatman@qq.com
微 信 fsx641385712
活跃平台
公众号 BAT的乌托邦(ID:BAT-utopia)
知识星球 BAT的乌托邦
每日文章推荐 每日文章推荐

  • Netflix OSS套件一站式学习驿站
  • Netflix OSS套件一站式学习驿站
  • 一、为何我决定写Spring Cloud专栏

二、何为Spring Boot整合Spring Cloud?相关推荐

  1. 认证与授权流程与spring boot整合 spring security(1)

    一   spring security 1.1 spring security的作用 Spring Security所解决的问题就是安全访问控制,而安全访问控制功能其实就是对所有进入系统的请求进行拦截 ...

  2. spring boot整合spring security笔记

    最近自己做了一个小项目,正在进行springboot和spring Security的整合,有一丢丢的感悟,在这里分享一下: 首先,spring boot整合spring security最好是使用T ...

  3. springboot整合hibernate_峰哥说技术系列-17 .Spring Boot 整合 Spring Data JPA

    今日份主题 Spring Boot 整合 Spring Data JPA JPA(Java Persistence API)是用于对象持久化的 API,是Java EE 5.0 平台标准的 ORM 规 ...

  4. Spring boot 整合Spring Security Jwt

    记录学习Spring boot 整合Spring Security Jwt 学习参考 – 慢慢的干货 https://shimo.im/docs/OnZDwoxFFL8bnP1c/read 首先创建S ...

  5. Spring Boot 整合——Spring batch重试和回滚

    关于版本 依赖 版本 springboot 2.4.0 spring batch 2.4.0 代码地址 因为每个例子涉及代码较多,且包含测试用例,如果都贴到文章中内容过多,所以只贴出了部分代码.全部的 ...

  6. spring boot 整合 spring cache 简单使用

    spring boot 整合 spring cache 简单使用 spring cache简介 使用spring cache spring cache简介 Spring 3.1起,提供了基于注解的对C ...

  7. Spring Boot 整合——Spring Boot整合kafka整合

    Spring Boot 整合之前的内容 项目名称 描述 地址 base-data-mybatis 整合mybatis-plus(实际上官方教程已经很多,只做了自定义插件) 未完成 base-jpa J ...

  8. Spring Boot整合Spring Data JPA操作数据

    一. Sping Data JPA 简介 Spring Data JPA 是 Spring 基于 ORM 框架.JPA 规范的基础上封装的一套 JPA 应用框架,底层使用了 Hibernate 的 J ...

  9. Spring Boot 整合 Spring Security 示例

    点击关注公众号,Java干货及时送达 一.说明 SpringSecurity是一个用于Java 企业级应用程序的安全框架,主要包含用户认证和用户授权两个方面.相比较Shiro而言,Security功能 ...

最新文章

  1. 终端多窗口管理旗舰------screen
  2. Jquery中怎样判断是否有网络
  3. 转载:Linux命令之查看文件占用空间大小-du,df
  4. 【故障诊断分析】基于matlab FFT轴承故障诊断【含Matlab源码 1397期】
  5. php7 switch,Switch autocommit on or off - PHP 7 中文文档
  6. Android 四大组件
  7. html 内容写入数据库中,FoxPro数据库写入html文件中
  8. PFC离散元仿真核心技术与应用
  9. CodeForces - 1299B. Aerodynamic
  10. 《RISC-V架构与嵌入式开发快速入门_胡振波著》学习笔记
  11. 久邦GOMO总裁朱志在2018校招生交流会分享
  12. SpringBoot实现QQ邮箱注册和登录
  13. Linux命令学习总结
  14. 数据标注是做什么的?
  15. TVB经典电视剧--《创世纪》回忆
  16. Visual Studio 2019解决右侧工具栏消失
  17. 详解软件无线电(SDR)架构
  18. ModStartBlog 现代化个人博客系统 v5.2.0 源码下载
  19. 《计算机图形学编程(使用OpenGL和C++)》
  20. SpringBoot中使用AMQ的两种方式二(Java配置、注解方式)

热门文章

  1. android 寺库trytry_git 学习
  2. JMS JMS背景 概述 JMS术语
  3. Wordpress中文章的特色图像Featured Image究竟存在哪里?
  4. ROS2-Foxy-配置
  5. 国内有哪些较好的Java开源CMS建站系统?
  6. 《Python深度学习》读书笔记:第1章 什么是深度学习
  7. Git 回退撤销相关命令,毫无保留,都在这里了!!!
  8. 团队项目用户验收评审
  9. h5实现类似淘宝评价选择标签
  10. python中应对各种机制