SpringCloud入门之应用程序上下文服务(Spring Cloud Context)详解

构建分布式系统很是复杂且容易出错。Spring Cloud为最多见的分布式系统模式提供了简单易用的编程模型,帮助开发人员构建弹性,可靠和协调的应用程序。Spring Cloud构建于Spring Boot之上,使开发人员能够轻松入门并快速提升工做效率。Spring Boot对于如何使用Spring构建应用程序有一个见解:例如它具备常规配置文件的常规位置,以及用于常见管理和监视任务的端点。Spring Cloud创建在此之上,并添加了一些可能系统中全部组件将使用或偶尔须要的功能。html

引导应用程序上下文

一个Spring Cloud应用程序经过建立一个“引导”上下文来进行操做,这个上下文是主应用程序的父上下文。开箱即用,负责从外部源加载配置属性,还解密本地外部配置文件中的属性。这两个上下文共享一个Environment,这是任何Spring应用程序的外部属性的来源。Bootstrap属性的优先级高,所以默认状况下不能被本地配置覆盖。java

引导上下文使用与主应用程序上下文不一样的外部配置约定,所以使用bootstrap.yml application.yml(或.properties)代替引导和主上下文的外部配置。关于配置文件bootstrap.yml与application.yml区别的深刻分析详见SpringCloud入门之经常使用的配置文件 application.yml和 bootstrap.yml区别spring

例:数据库

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

若是您的应用程序须要服务器上的特定于应用程序的配置,那么设置spring.application.name(在bootstrap.ymlapplication.yml)中是个好主意。编程

您能够经过设置spring.cloud.bootstrap.enabled=false(例如在系统属性中)来彻底禁用引导过程。bootstrap

应用程序上下文层次结构

若是您从SpringApplicationSpringApplicationBuilder构建应用程序上下文,则将Bootstrap上下文添加为该上下文的父级。这是一个Spring的功能,即子上下文从其父进程继承属性源和配置文件,所以与不使用Spring Cloud Config构建相同上下文相比,“主”应用程序上下文将包含其余属性源。额外的资产来源是:缓存

  • 若是您从SpringApplication或SpringApplicationBuilder构建应用程序上下文,则将Bootstrap上下文添加为该上下文的父级。Spring的一个特性是子上下文从其父级继承属性源和配置文件,所以与构建没有Spring Cloud Config的相同上下文相比,“主”应用程序上下文包含其余属性源。其余财产来源是:安全

    • “bootstrap”:若是PropertySourceLocators在Bootstrap上下文中找到任何内容,而且它们具备非空属性,CompositePropertySource则会显示具备高优先级的可选项一个例子是Spring Cloud Config Server的属性。
    • “applicationConfig:[classpath:bootstrap.yml]”(以及相关文件,若是Spring配置文件处于活动状态):若是您有bootstrap.yml(或.properties),则使用这些属性配置Bootstrap上下文。而后,在设置其父级时,它们将添加到子上下文中。它们的优先级低于application.yml(或.properties)以及做为建立Spring Boot应用程序过程的正常部分添加到子级的任何其余属性源。有关如何自定义这些属性源的内容的说明

因为属性源的排序规则,“引导”条目优先,但请注意,这些条目不包含来自bootstrap.yml的任何数据,它具备很是低的优先级,但可用于设置默认值。服务器

您能够经过简单地设置您建立的任何ApplicationContext的父上下文来扩展上下文层次结构,例如使用本身的界面,或使用SpringApplicationBuilder方便方法(parent()child()sibling())。引导环境将是您建立本身的最高级祖先的父级。层次结构中的每一个上下文都将有本身的“引导”属性源(可能为空),以免无心中将值从父级升级到其后代。层次结构中的每一个上下文(原则上)也能够具备不一样的spring.application.name,所以若是存在配置服务器,则不一样的远程属性源。普通的Spring应用程序上下文行为规则适用于属性解析:子环境中的属性经过名称和属性源名称覆盖父项中的属性(若是子级具备与父级名称相同的属性源,一个来自父母的孩子不包括在孩子中)。并发

请注意,SpringApplicationBuilder容许您在整个层次结构中共享Environment,但这不是默认值。所以,兄弟情境尤为不须要具备相同的资料或财产来源,尽管它们与父母共享共同点。

改变引导位置Properties

可使用spring.cloud.bootstrap.name(默认“引导”)或spring.cloud.bootstrap.location(默认为空)指定bootstrap.yml(或.properties)位置,例如在系统属性中。这些属性的行为相似于具备相同名称的spring.config.*变体,实际上它们用于经过在其Environment中设置这些属性来设置引导ApplicationContext若是在正在构建的上下文中有活动的配置文件(来自spring.profiles.active或经过Environment API)),则该配置文件中的属性也将被加载,就像常规的Spring Boot应用程序,例如来自bootstrap-development.properties的“开发”简介。

覆盖远程Properties的值

经过引导上下文添加到应用程序的属性源一般是“远程”(例如从配置服务器),而且默认状况下,不能在本地覆盖,除了在命令行上。若是要容许您的应用程序使用本身的系统属性或配置文件覆盖远程属性,则远程属性源必须经过设置spring.cloud.config.allowOverride=true(在本地设置自己不起做用)授予权限。一旦设置了该标志,就会有一些更精细的设置来控制远程属性与系统属性和应用程序本地配置的位置:spring.cloud.config.overrideNone=true覆盖任何本地属性源,spring.cloud.config.overrideSystemProperties=false若是只有系统属性和env var应该覆盖远程设置,而不是本地配置文件。

自定义引导配置

能够经过在org.springframework.cloud.bootstrap.BootstrapConfiguration键下添加条目/META-INF/spring.factories来训练引导上下文来执行任何您喜欢的操做。这是用于建立上下文的Spring @Configuration类的逗号分隔列表。您能够在此处建立要用于自动装配的主应用程序上下文的任何bean,而且还有ApplicationContextInitializer类型的@Beans的特殊合同。若是要控制启动顺序(默认顺序为“最后”),可使用@Order标记类。

警告
添加自定义BootstrapConfiguration时,请注意,您添加的类不是错误的@ComponentScanned到您的“主”应用程序上下文中,可能不须要它们。对于您的@ComponentScan@SpringBootApplication注释配置类还没有涵盖的启动配置类,请使用单独的包名称。

引导过程经过将初始化器注入主SpringApplication实例(即正常的Spring Boot启动顺序,不管是做为独立应用程序运行仍是部署在应用程序服务器中)结束。首先,从spring.factories中找到的类建立引导上下文,而后在ApplicationContextInitializer类型的全部@Beans添加到主SpringApplication开始以前。

自定义引导属性源

引导过程添加的外部配置的默认属性源是Config Server,但您能够经过将PropertySourceLocator类型的bean添加到引导上下文(经过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是要建立的ApplicationContextEnvironment,即为咱们提供额外的属性来源的。它将已经具备正常的Spring Boot提供的资源来源,所以您可使用它们来定位特定于此Environment的属性源(例如经过将其绑定在spring.application.name上,如在默认状况下所作的那样Config Server属性源定位器)。

若是你在这个类中建立一个jar,而后添加一个META-INF/spring.factories包含:

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

那么“customProperty”PropertySource将显示在其类路径中包含该jar的任何应用程序中。

环境变化

应用程序将收听EnvironmentChangeEvent,并以几种标准方式进行更改(用户能够以常规方式添加ApplicationListeners附加ApplicationListeners)。当观察到EnvironmentChangeEvent时,它将有一个已更改的键值列表,应用程序将使用如下内容:

  • 从新绑定上下文中的任何@ConfigurationProperties bean

  • logging.level.*中的任何属性设置记录器级别

请注意,配置客户端不会经过默认轮询查找Environment中的更改,一般咱们不建议检测更改的方法(尽管可使用@Scheduled注释进行设置)。若是您有一个扩展的客户端应用程序,那么最好将EnvironmentChangeEvent广播到全部实例,而不是让它们轮询更改

EnvironmentChangeEvent涵盖了大量的刷新用例,只要您真的能够更改Environment并发布事件(这些API是公开的,部份内核为Spring)。您能够经过访问/configprops端点(普通Spring Boot执行器功能)来验证更改是否绑定到@ConfigurationProperties bean。例如,DataSource能够在运行时更改其maxPoolSize(由Spring Boot建立的默认DataSource是一个@ConfigurationProperties bean),而且动态增长容量。从新绑定@ConfigurationProperties不会覆盖另外一大类用例,您须要更多的控制刷新,而且您须要更改在整个ApplicationContext上是原子的。为了解决这些担心,咱们有@RefreshScope

刷新范围

当配置更改时,标有@RefreshScope的Spring @Bean将获得特殊处理。这解决了状态bean在初始化时只注入配置的问题。例如,若是经过Environment更改数据库URL时DataSource有开放链接,那么咱们可能但愿这些链接的持有人可以完成他们正在作的工做。而后下一次有人从游泳池借用一个链接,他获得一个新的URL。

刷新范围bean是在使用时初始化的懒惰代理(即当调用一个方法时),而且做用域做为初始值的缓存。要强制bean从新初始化下一个方法调用,您只须要使其缓存条目无效。

RefreshScope是上下文中的一个bean,它有一个公共方法refreshAll()来清除目标缓存中的范围内的全部bean。还有一个refresh(String)方法能够按名称刷新单个bean。此功能在/refresh端点(经过HTTP或JMX)中公开。

注意
@RefreshScope(技术上)在@Configuration类上工做,但可能会致使使人惊讶的行为:例如,这并不 意味着该类中定义的全部@Beans自己都是@RefreshScope具体来讲,任何取决于这些bean的东西都不能依赖它们在刷新启动时被更新,除非它自己在@RefreshScope(在其中将从新刷新并从新注入其依赖关系),那么它们将从刷新的@Configuration)从新初始化。

加密和解密

Spring Cloud具备一个用于在本地解密属性值的Environment预处理器。它遵循与Config Server相同的规则,并经过encrypt.*具备相同的外部配置。所以,您可使用{cipher}*格式的加密值,只要有一个有效的密钥,那么在主应用程序上下文获取Environment以前,它们将被解密。要在应用程序中使用加密功能,您须要在您的类路径中包含Spring安全性RSA(Maven协调“org.springframework.security:spring-security-rsa”),而且还须要全面强大的JCE扩展你的JVM

若是因为“非法密钥大小”而致使异常,而且您正在使用Sun的JDK,则须要安装Java加密扩展(JCE)无限强度管理策略文件。有关详细信息,请参阅如下连接:

将文件解压缩到JDK / jre / lib / security文件夹(不管您使用的是哪一个版本的JRE / JDK x64 / x86)。

端点

端点

对于Spring Boot Actuator应用程序,可使用一些其余管理端点。您可使用:

  • POST/actuator/env更新Environment并从新绑定@ConfigurationProperties并记录水平。
  • /actuator/refresh从新加载引导带上下文并刷新@RefreshScopebean。
  • /actuator/restart关闭ApplicationContext并从新启动它(默认状况下禁用)。
  • /actuator/pause/actuator/resume调用的Lifecycle方法(stop()start()ApplicationContext)。
[Note]

若是禁用/actuator/restart端点,那么端点/actuator/pause/actuator/resume端点也将被禁用,由于它们只是一个特例/actuator/restart

相关文章
相关标签/搜索