【秒懂·云原生】微服务篇 —— Spring Cloud Context:应用上下文

2年前 (2022) 程序员胖胖胖虎阿
344 0 0

【秒懂·云原生】微服务篇 —— Spring Cloud Context:应用上下文

🔎这里是【秒懂·云原生】,关注我学习云原生不迷路
👍如果对你有帮助,给博主一个免费的点赞以示鼓励
欢迎各位🔎点赞👍评论收藏⭐️

👀专栏介绍

【秒懂·云原生】 目前主要更新微服务,一起学习一起进步。

👀本期介绍

主要介绍Spring Cloud Context:应用上下文

文章目录

  • 👀专栏介绍
  • 👀本期介绍
    • 🍖Bootstrap 上下文
    • 🍖应用上下文层级
    • 🍖更改Bootstrap属性的位置
    • 🍖重载远程属性
    • 🍖自定义Bootstrap配置
    • 🍖自定义Bootstrap属性源
    • 🍖日志记录配置
    • 🍖Environment变化
    • 🍖刷新作用域

🍖Bootstrap 上下文

Spring Cloud应用程序通过创建“bootstrap”上下文来运转,该上下文是主应用程序的父上下文,它负责从外部源加载配置属性以及用于解密本地外部配置文件中的属性,这两个上下文共享一个Environment,它是任何Spring应用程序的外部属性来源。默认情况下,bootstrap属性(不是bootstrap.properties,而是在引导阶段加载的属性)以高优先级添加,因此本地配置无法覆盖它们。

bootstrap上下文使用与主应用程序上下文不同的约定来定位外部配置,你可以使用bootstrap.yml而不是application.yml(或.properties),保持bootstrap和主上下文的外部配置很好地分开,以下清单显示了一个示例:

bootstrap.yml

spring:
  application:
    name: foo
  cloud:
    config:
      uri: ${SPRING_CONFIG_URI:http://localhost:8888}

如果你的应用程序需要来自服务器的任何特定于应用程序的配置,则最好设置spring.application.name(在bootstrap.yml或application.yml中)。

你可以通过设置spring.cloud.bootstrap.enabled=false来完全禁用引导过程(例如,在系统属性中)。

🍖应用上下文层级

Spring的上下文有一个特性:子级上下文将从父级中继承属性源和配置文件。如果通过SpringApplication或者SpringApplicationBuilder来构建应用程序上下文,那么Bootstrap上下文将会成为该应用程序上下文的父级上下文。

在Bootstrap上下文中扫描到的非空的PropertySourceLocators会以高优先级添加到CompositePropertySource中。如果通过bootstrap.yml来配置Bootstrap上下文,且在设定好父级上下文的情况下,bootstrap.yml中的属性会添加到子级的上下文。它们的优先级低于application.yml和其他添加到子级中作为创建Spring Boot应用的属性源。

基于属性源的排序规则,Bootstrap上下文中的属性优先,但是需要注意这些属性并不包含任何来自bootstrap.yml的数据。bootstrap.yml中的属性具备非常低的优先级,因此可以作为默认值。

可以简单地将父级上下文设置为应用上下文来扩展上下文的层次结构。Bootstrap上下文将会是最高级别上下文的父级。每一个在层次结构中的上下文都有它自己的Bootstrap属性源(可能为空),来避免无意中将父级上下文中的属性传递到它的后代中。层次结构中的每一个上下文原则上应该拥有自己不同的spring.application.name,以便在有配置中心的时候也能有不同的远程属性源。来自子级上下文的属性可以覆盖父级中的具有相同名称和属性源名称的属性。

🍖更改Bootstrap属性的位置

可以通过设置spring.cloud.bootstrap.name(默认值:bootstrap)或spring.cloud.bootstrap.location(默认值为空)来指定bootstrap.yml(或.properties)位置 — 例如,在系统属性中。这些属性的行为类似于具有相同名称的spring.config.*变体,实际上,它们用于通过在其Environment中设置这些属性来设置bootstrap ApplicationContext。如果存在活动配置文件(来自spring.profiles.active或通过你正在构建的上下文中的Environment API),则该配置文件中的属性也会加载,与常规Spring Boot应用程序相同 — 例如,来自bootstrap-development.properties的development配置文件

🍖重载远程属性

通过Bootstrap上下文添加到应用程序的属性源通常是远程的,例如来自配置中心,通常本地的配置文件不能覆盖这些远程属性源。一般来说过,启动命令行参数的优先级高于远程配置,可以通过设定启动命令行参数的方式覆盖远程配置。

如果想使用应用程序的系统属性或者配置文件覆盖远程属性,那么远程属性源必须设置为spring.cloud.config.allowOverride=true (这个配置在本地设置不会生效)。在远程属性源中设定上述配置后,就可以通过更为细粒度的设置来控制远程属性是否能被重载,具体配置如下所示。

spring:
cloud:
config:
overrideNone: true #本地属性覆盖所有的远程属性源
overrideSystemProperties: false#仅覆盖远程属性源中的系统属性和环境变量

🍖自定义Bootstrap配置

通过向/META-INF/spring.factories下添加键名为org.springframework.cloud.bootstrap.BootstrapConfiguration的条目,可以将bootstrap上下文设置为执行任何操作。它包含一个以逗号分隔的用于创建上下文的Spring @Configuration类列表,你可以在此处创建你希望可用于主应用程序上下文以进行自动装配的任何Bean。ApplicationContextInitializer类型的@Beans有一个特殊的合约,如果要控制启动顺序,可以使用@Order注解标记类(默认顺序为last)。

添加自定义BootstrapConfiguration时,请注意你添加的类不是@ComponentScanned错误地进入你的“主”应用程序上下文,可能不需要它们。为引导配置类使用单独的包名称,并确保@ComponentScan或@SpringBootApplication注解的配置类尚未涵盖该名称。

引导过程通过将初始化器注入主SpringApplication实例(这是正常的Spring Boot启动顺序,无论是作为独立应用程序运行还是部署在应用程序服务器中)而结束,首先,从spring.factories中的类创建bootstrap上下文,然后,所有类型为ApplicationContextInitializer的@Beans在它启动之前都会添加到主SpringApplication中。

🍖自定义Bootstrap属性源

默认的Bootstrap外部配置属性源是Spring Cloud Config Server,即使用配置中心加载外部属性。但是用户也可以通过将PropertySourceLocator类型的Bean实例添加到Bootstrap上下文(在spring.factories添加对应的配置类)来添加额外的属性来源。通过这种方法可以从不同的服务器或者数据库中加载额外的属性,如下所示:

@Configuration
public class CustomPropertySourceLocator implements PropertySourceLocator {

    @Override
    public PropertySource<?> locate(Environment environment) {
        return new MapPropertySource("customProperty",
                Collections.<String, Object>singletonMap("property.from.sample.custom.source", "worked as intended"));
    }

}

上述代码中传入的Environment参数用于创建应用上下文,它具有Spring Boot提供的属性源,可以使用它们来加载特定的属性源(例如重新设置
spring.application.name)。可以在META-INF/spring.factories文件中添加如下记录来配置属性源:

org.springframework.cloud.bootstrap.BootstrapConfiguration=sample.custom.CustomPropertySourceLocator

上述配置令应用程序可以使用CustomPropertySourceLocator作为其属性源。

🍖日志记录配置

如果要使用Spring Boot配置日志设置,则应将此配置放在‘bootstrap.[yml | properties]’,如果你希望它适用于所有事件。

要使Spring Cloud正确初始化日志记录配置,你不能使用自定义前缀,例如,初始化日志记录系统时,使用custom.loggin.logpath不被Spring Cloud识别

🍖Environment变化

Config Client应用程序会监听EnvironmentChangeEvent事件,当监听到一个EnvironmentChangeEvent时,它将持有一个被改变的键值对列表,应用程序使用这些值来:

  • 重新绑定所有的@ConfigurationProperties的Bean实例,更新本地的配置属性。
  • ·为在logging.level.*的所有属性设置日志的等级。

一般来讲,Config Client默认不会使用轮询方法来监听Environment中的改变。在Spring Cloud中,Spring Cloud Config Server使用Spring Cloud Bus将EnvironmentChangeEvent广播到所有的Config Client中,通知它们Environment发生变化。

EnvironmentChangeEvent是一个事件类,用于在Environment发生修改时发布事件。开发者可以通过访问/configprops端点(常规的Spring Boot Actuator端点)来验证这些更改是否绑定到@ConfigurationProperties的Bean实例上。例如一个
DataSource的最大连接数量在运行时被改变了(DataSource默认由Spring Boot创建,属于@ConfigurationProperties的Bean)并且动态增加容量,可以通过查看ConfigClient应用程序的/configprops端点来验证DataSource的最大连接池数量是否发生变化。

🍖刷新作用域

一个被标记为@RefreshScope的Spring Bean实例在配置发生变更时可以重新进行初始化,即动态刷新配置,这是为了解决状态Bean实例只能在初始化的时候才能进行属性注入的问题。

被@RefreshScope修饰的Bean实例是懒加载的,即当它们被使用的时候才会进行初始化(方法被调用的时候),想要在下次方法调用前强制重新初始化一个Bean实例,只需要将它的缓存失效即可。

RefreshScope是上下文中的一个Bean实例,它有一个公共方法refreshAll,该方法可以通过清除目标缓存来刷新作用域中的所有Bean实例。RefreshScope也有一个
refresh方法来按照名字刷新单个Bean。

相关文章

暂无评论

暂无评论...