此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Cloud Commons 4.1.5spring-doc.cadn.net.cn

Spring Cloud 上下文:应用程序上下文服务

Spring Boot 对如何使用 Spring 构建应用程序有一种固执己见的看法。 例如,它具有用于常见配置文件的常规位置,并具有用于常见管理和监控任务的终端节点。 Spring Cloud 在此基础上构建,并添加了系统中许多组件会使用或偶尔需要的一些功能。spring-doc.cadn.net.cn

Bootstrap 应用程序上下文

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

引导程序上下文使用与主应用程序上下文不同的约定来查找外部配置。 而不是application.yml(或.properties),您可以使用bootstrap.yml,将 bootstrap 和 main 上下文的外部配置很好地分开。 下面的清单显示了一个示例:spring-doc.cadn.net.cn

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

如果您的应用程序需要来自服务器的任何特定于应用程序的配置,最好将spring.application.name(在bootstrap.ymlapplication.yml). 对于物业spring.application.name要用作应用程序的上下文 ID,您必须在bootstrap.[properties | yml].spring-doc.cadn.net.cn

如果要检索特定的配置文件配置,还应将spring.profiles.activebootstrap.[properties | yml].spring-doc.cadn.net.cn

您可以通过设置spring.cloud.bootstrap.enabled=false(例如,在 System Properties 中)。spring-doc.cadn.net.cn

应用程序上下文层次结构

如果您从SpringApplicationSpringApplicationBuilder时,Bootstrap 上下文将作为父项添加到该上下文。 Spring 的一个功能是子上下文从其父上下文继承属性源和配置文件,因此与在没有 Spring Cloud Config 的情况下构建相同的上下文相比,“主”应用程序上下文包含额外的属性源。 其他属性源包括:spring-doc.cadn.net.cn

  • “bootstrap”:如果有PropertySourceLocators在 Bootstrap 上下文中找到,如果它们具有非空属性,则可选的CompositePropertySource以高优先级显示。 一个例子是 Spring Cloud Config Server 中的属性。 有关如何自定义此属性源的内容,请参阅“自定义 Bootstrap 属性源”。spring-doc.cadn.net.cn

Spring Cloud 2022.0.3 之前的版本PropertySourceLocators(包括 Spring Cloud Config 的 API 的 主应用程序上下文,而不是 Bootstrap 上下文中。您可以强制PropertySourceLocators在 通过设置 Bootstrap 上下文spring.cloud.config.initialize-on-context-refresh=truebootstrap.[properties | yaml].
  • “applicationConfig: [classpath:bootstrap.yml]”(如果 Spring 配置文件处于活动状态,则为相关文件):如果您有一个bootstrap.yml(或.properties),这些属性用于配置 Bootstrap 上下文。 然后,当设置其 parent 时,它们将被添加到 child context 中。 它们的优先级低于application.yml(或.properties)以及作为创建 Spring Boot 应用程序过程的正常部分添加到子级的任何其他属性源。 有关如何自定义这些属性源的内容,请参阅“更改 Bootstrap 属性的位置”。spring-doc.cadn.net.cn

由于属性源的排序规则,“bootstrap” 条目优先。 但是,请注意,这些不包含来自bootstrap.yml,它的优先级非常低,但可用于设置默认值。spring-doc.cadn.net.cn

您可以通过设置任何ApplicationContext您可以创建 — 例如,通过使用它自己的接口或使用SpringApplicationBuilder便捷方法 (parent(),child()sibling()). 引导程序上下文是您自己创建的最高级祖先的父级。 层次结构中的每个上下文都有自己的 “bootstrap” (可能为空) 属性源,以避免无意中将值从父级提升到其后代。 如果存在配置服务器,则层次结构中的每个上下文也可以(原则上)具有不同的spring.application.name因此,使用不同的远程属性源。 正常的 Spring 应用程序上下文行为规则适用于属性解析:子上下文中的属性会覆盖 父级、按名称以及按属性源名称。 (如果子项具有与父项同名的属性源,则父项的值不包含在子项中)。spring-doc.cadn.net.cn

请注意,SpringApplicationBuilder允许您共享Environment在整个层次结构中,但这不是默认设置。 因此,同级上下文 (特别是) 不需要具有相同的配置文件或属性源,即使它们可能与其父级共享公共值。spring-doc.cadn.net.cn

更改 Bootstrap 属性的位置

bootstrap.yml(或.properties) 位置可以通过设置spring.cloud.bootstrap.name(默认:bootstrap),spring.cloud.bootstrap.location(默认值:空)或spring.cloud.bootstrap.additional-location(默认值:空) — 例如,在 System properties 中。spring-doc.cadn.net.cn

这些属性的行为类似于spring.config.*变体。 跟spring.cloud.bootstrap.location默认位置将被替换,并且仅使用指定的位置。 要将位置添加到默认位置列表中,spring.cloud.bootstrap.additional-location可以使用。 实际上,它们用于设置 bootstrapApplicationContext通过在其Environment. 如果存在活动配置文件(来自spring.profiles.active或通过EnvironmentAPI),该配置文件中的属性也会加载,与常规 Spring Boot 应用程序中的属性相同 — 例如,从bootstrap-development.properties对于development轮廓。spring-doc.cadn.net.cn

覆盖 Remote Properties 的值

引导程序上下文添加到应用程序的属性源通常是“远程”(例如,来自 Spring Cloud Config Server)。 默认情况下,它们不能在本地覆盖。 如果你想让你的应用程序用它们自己的系统属性或配置文件覆盖远程属性,远程属性源必须通过设置spring.cloud.config.allowOverride=true(在本地设置此项不起作用)。 设置该标志后,两个更细粒度的设置将控制远程属性相对于系统属性和应用程序本地配置的位置:spring-doc.cadn.net.cn

  • spring.cloud.config.overrideNone=true:从任何本地属性源覆盖。spring-doc.cadn.net.cn

  • spring.cloud.config.overrideSystemProperties=false:只有系统属性、命令行参数和环境变量(但不包括本地配置文件)应覆盖远程设置。spring-doc.cadn.net.cn

自定义引导程序配置

引导上下文可以设置为执行任何您喜欢的作,方法是将条目添加到/META-INF/spring.factories在名为org.springframework.cloud.bootstrap.BootstrapConfiguration. 这包含以逗号分隔的 Spring 列表@Configuration用于创建上下文的类。 可以在此处创建任何希望可用于主应用程序上下文以进行自动装配的 bean。 有一个特殊的合同@Beans的类型ApplicationContextInitializer. 如果要控制启动顺序,可以使用@Orderannotation (默认顺序为last).spring-doc.cadn.net.cn

添加自定义BootstrapConfiguration,请注意您添加的类不是@ComponentScanned错误地进入您的 “main” 应用程序上下文,在那里可能不需要它们。 为引导配置类使用单独的软件包名称,并确保该名称尚未包含在@ComponentScan@SpringBootApplication带注释的配置类。

引导过程通过将初始化器注入 mainSpringApplication实例(这是正常的 Spring Boot 启动序列,无论它是作为独立应用程序运行还是部署在应用程序服务器中)。 首先,从spring.factories. 然后,所有@Beans的类型ApplicationContextInitializer添加到主SpringApplication在启动之前。spring-doc.cadn.net.cn

自定义 Bootstrap 属性源

引导过程添加的外部配置的默认属性源是 Spring Cloud Config Server,但您可以通过添加 bean 类型的 bean 来添加其他源PropertySourceLocator到 Bootstrap 上下文(通过spring.factories). 例如,您可以插入来自不同服务器或数据库的其他属性。spring-doc.cadn.net.cn

例如,请考虑以下自定义定位器:spring-doc.cadn.net.cn

@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,则传入的ApplicationContext即将创建 — 换句话说,我们为其提供其他属性源的那个。 它已经具有 Spring Boot 提供的常规属性源,因此您可以使用这些属性源来查找特定于此的属性源Environment(例如,通过将其键入spring.application.name,就像在默认的 Spring Cloud Config Server 属性源定位器中所做的那样)。spring-doc.cadn.net.cn

如果您创建一个包含此类的 jar,然后添加一个META-INF/spring.factories包含以下设置,customProperty PropertySource出现在在其 Classpath 中包含该 jar 的任何应用程序中:spring-doc.cadn.net.cn

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

从 Spring Cloud 2022.0.3 开始,Spring Cloud 现在将调用PropertySourceLocators两次。第一次 fetch 将检索不带任何配置文件的任何属性源。这些属性来源将有机会 使用以下方式激活配置文件spring.profiles.active.主应用程序上下文启动后PropertySourceLocators将再次调用,这一次任何活动配置文件都允许PropertySourceLocators查找 任何其他PropertySources与配置文件。spring-doc.cadn.net.cn

日志记录配置

如果使用 Spring Boot 配置日志设置,则应将此配置放在bootstrap.[yml | properties]如果您希望它适用于所有事件。spring-doc.cadn.net.cn

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

环境更改

应用程序侦听EnvironmentChangeEvent并以几种标准方式对更改做出反应(附加ApplicationListeners可以添加为@Beans以正常方式)。 当EnvironmentChangeEvent时,它有一个已更改的键值列表,应用程序使用这些值来:spring-doc.cadn.net.cn

请注意,默认情况下,Spring Cloud Config Client 不会轮询Environment. 通常,我们不建议使用这种方法来检测更改(尽管您可以使用@Scheduled注释)。 如果您有一个横向扩展的客户端应用程序,最好将EnvironmentChangeEvent到所有实例,而不是让它们轮询更改(例如,通过使用 Spring Cloud Bus)。spring-doc.cadn.net.cn

EnvironmentChangeEvent涵盖了一大类刷新用例,只要您实际上可以更改Environment并发布事件。 请注意,这些 API 是公共的,并且是核心 Spring 的一部分。 您可以验证更改是否绑定到@ConfigurationPropertiesbeans 通过访问/configpropsendpoint(Spring Boot Actuator 的标准功能)。 例如,DataSource可以具有其maxPoolSize在运行时更改(默认的DataSource由 Spring Boot 创建的是一个@ConfigurationPropertiesbean) 并动态增加容量。 重新绑定@ConfigurationProperties没有涵盖另一大类用例,在这些用例中,您需要对刷新进行更多控制,并且需要对整个ApplicationContext. 为了解决这些问题,我们采取了@RefreshScope.spring-doc.cadn.net.cn

注释为@ConfigurationProperties无法刷新。

刷新范围

当配置发生更改时,Spring@Bean标记为@RefreshScope得到特殊待遇。 此功能解决了有状态 Bean 仅在初始化时注入其配置的问题。 例如,如果DataSource在通过Environment,您可能希望这些连接的持有者能够完成他们正在执行的作。 然后,下次从池中借用连接时,它会获得一个具有新 URL 的连接。spring-doc.cadn.net.cn

有时,甚至可能强制应用@RefreshScope注解,这些 bean 只能初始化一次。 如果 bean 是 “不可变的”,则必须使用@RefreshScope或在 property 键下指定 classname:spring.cloud.refresh.extra-refreshable.spring-doc.cadn.net.cn

如果你有一个DataSourcebean 是一个HikariDataSource,则不能 刷新。它是spring.cloud.refresh.never-refreshable.选择一个 不同DataSourceimplementation (如果需要刷新)。

刷新范围 bean 是惰性代理,它们在使用时(即调用方法时)进行初始化,并且范围充当初始化值的缓存。 要强制 Bean 在下一次方法调用时重新初始化,必须使其高速缓存条目无效。spring-doc.cadn.net.cn

RefreshScope是上下文中的 Bean,并且具有公共refreshAll()方法通过清除目标缓存来刷新作用域中的所有 bean。 这/refreshendpoint 公开此功能(通过 HTTP 或 JMX)。 要按名称刷新单个 Bean,还有一个refresh(String)方法。spring-doc.cadn.net.cn

要公开/refreshendpoint,您需要将以下配置添加到您的应用程序中:spring-doc.cadn.net.cn

management:
  endpoints:
    web:
      exposure:
        include: refresh
@RefreshScope(技术上)在@Configuration类,但它可能会导致令人惊讶的行为。 例如,这并不意味着所有@Beans定义在那个类中,他们自己都在@RefreshScope. 具体来说,任何依赖于这些 bean 的东西都不能依赖于在启动刷新时更新它们,除非它本身在@RefreshScope. 在这种情况下,它会在刷新时重新构建,并且其依赖项会重新注入。 此时,它们将从刷新的@Configuration).
删除配置值,然后执行刷新不会更新配置值的存在。 必须存在 configuration 属性,才能在刷新后更新值。如果您依赖于 应用程序中的一个值,您可能希望切换逻辑以依赖它的缺失。另一种选择是依赖 值更改而不是不存在于应用程序的配置中。
Spring AOT 转换和本机映像不支持上下文刷新。对于 AOT 和本机映像,spring.cloud.refresh.enabled需要设置为false.

重新启动时刷新范围

重新启动时无缝刷新 bean 对于使用 JVM Checkpoint Restore 运行的应用程序(例如 Project CRaC)特别有用。为了实现此功能,我们现在实例化一个RefreshScopeLifecycle在重新启动时触发上下文刷新的 bean,从而导致重新绑定配置属性并刷新任何带有 Comments 的 bean@RefreshScope.您可以通过设置spring.cloud.refresh.on-restart.enabledfalse.spring-doc.cadn.net.cn

加密和解密

Spring Cloud 有一个Environment用于在本地解密属性值的预处理器。 它遵循与 Spring Cloud Config Server 相同的规则,并通过encrypt.*. 因此,您可以使用{cipher}*,并且只要存在有效密钥,它们就会在主应用程序上下文获取Environment设置。 要在应用程序中使用加密功能,您需要在类路径中包含 Spring Security RSA(Maven 坐标:org.springframework.security:spring-security-rsa),并且您还需要在 JVM 中提供全功能 JCE 扩展。spring-doc.cadn.net.cn

如果由于“非法密钥大小”而出现异常,并且使用 Sun 的 JDK,则需要安装 Java 加密扩展 (JCE) 无限强度管辖策略文件。 有关更多信息,请参阅以下链接:spring-doc.cadn.net.cn

将文件解压缩到您使用的任何 JRE/JDK x64/x86 版本的 JDK/jre/lib/security 文件夹中。spring-doc.cadn.net.cn

端点

对于 Spring Boot Actuator 应用程序,可以使用一些额外的 Management 端点。您可以使用:spring-doc.cadn.net.cn

  • POST/actuator/env要更新Environment并重新绑定@ConfigurationProperties和日志级别。 要启用此终端节点,您必须设置management.endpoint.env.post.enabled=true.spring-doc.cadn.net.cn

  • /actuator/refresh要重新加载引导带上下文并刷新@RefreshScope豆。spring-doc.cadn.net.cn

  • /actuator/restart以关闭ApplicationContext并重新启动它(默认处于禁用状态)。spring-doc.cadn.net.cn

  • /actuator/pause/actuator/resume调用的Lifecycle方法 (stop()start()ApplicationContext).spring-doc.cadn.net.cn

启用POSTmethod 的/actuator/envendpoint 可以为管理应用程序环境变量提供灵活性和便利性, 确保端点受到保护和监控以防止潜在的安全风险至关重要。 添加spring-boot-starter-securitydependency 为 Actuator 的端点配置访问控制。
如果禁用/actuator/restart端点,则/actuator/pause/actuator/resume端点 也会被禁用,因为它们只是/actuator/restart.