Spring Boot有一个关于如何使用Spring构建应用程序的主见,例如,它具备通用配置文件的常规位置,并具备用于通用管理和监控任务的端点,Spring Cloud在此基础上构建并添加了一些功能,这些功能多是系统中的全部组件都会使用或偶尔须要的。html
Spring Cloud应用程序经过建立“bootstrap”上下文来运转,该上下文是主应用程序的父上下文,它负责从外部源加载配置属性以及用于解密本地外部配置文件中的属性,这两个上下文共享一个Environment
,它是任何Spring应用程序的外部属性来源。默认状况下,bootstrap属性(不是bootstrap.properties
,而是在引导阶段加载的属性)以高优先级添加,所以本地配置没法覆盖它们。java
bootstrap上下文使用与主应用程序上下文不一样的约定来定位外部配置,你可使用bootstrap.yml
而不是application.yml
(或.properties
),保持bootstrap和主上下文的外部配置很好地分开,如下清单显示了一个示例:web
spring: application: name: foo cloud: config: uri: ${SPRING_CONFIG_URI:http://localhost:8888}
若是你的应用程序须要来自服务器的任何特定于应用程序的配置,则最好设置spring.application.name
(在bootstrap.yml
或application.yml
中)。spring
你能够经过设置spring.cloud.bootstrap.enabled=false
来彻底禁用引导过程(例如,在系统属性中)。sql
若是你从SpringApplication
或SpringApplicationBuilder
构建应用程序上下文,那么Bootstrap上下文将添加为该上下文的父级。Spring的一个特性是子上下文从其父级继承属性源和配置文件,所以与不使用Spring Cloud Config构建相同的上下文相比,“主”应用程序上下文包含额外的属性源,额外的属性源是:数据库
PropertySourceLocators
,而且它们具备非空属性,则会出现具备高优先级的可选CompositePropertySource
,一个例子是Spring Cloud Config Server的属性。bootstrap.yml
(或.properties
),则这些属性用于配置Bootstrap上下文,而后,当设置了其父级时,它们将添加到子上下文中。它们的优先级低于application.yml
(或.properties
)以及做为建立Spring Boot应用程序过程的正常部分添加到子级的任何其余属性源。因为属性源的排序规则,“bootstrap”条目优先,但请注意,这些不包含来自bootstrap.yml
的任何数据,它具备很是低的优先级,但可用于设置默认值。bootstrap
你能够经过设置你建立的任何ApplicationContext
的父上下文来扩展上下文层次结构 — 例如,经过使用它本身的接口或SpringApplicationBuilder
便捷方法(parent()
、child()
和sibling()
),bootstrap上下文是你本身建立的最高级祖先的父级。层次结构中的每一个上下文都有本身的“bootstrap”(多是空的)属性源,以免无心中把父级的值传给后代。若是存在Config Server,则层次结构中的每一个上下文(原则上)也能够具备不一样的spring.application.name
,所以具备不一样的远程属性源。普通的Spring应用程序上下文行为规则适用于属性解析:来自子上下文的属性按名称和属性源名称覆盖父级中的属性(若是子项具备与父项具备相同名称的属性源,则父项中的值不包括在子项中)。segmentfault
请注意,SpringApplicationBuilder
容许你在整个层次结构中共享Environment
,但这不是默认设置,所以,兄弟上下文尤为不须要具备相同的配置文件或属性源,即便他们可能与父上下文共享共同的值。缓存
能够经过设置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 Server),默认状况下,它们没法被本地覆盖。若是要让应用程序使用本身的系统属性或配置文件覆盖远程属性,远程属性源必须经过设置spring.cloud.config.allowOverride=true
来授予它权限(它不能在本地设置它),设置该标志后,两个更细粒度的设置将控制远程属性相对于系统属性和应用程序本地配置的位置:
spring.cloud.config.overrideNone=true
:从任何本地属性源覆盖。spring.cloud.config.overrideSystemProperties=false
:只有系统属性、命令行参数和环境变量(但不是本地配置文件)才应覆盖远程设置。经过向/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
中。
引导过程添加的外部配置的默认属性源是Spring Cloud Config Server,但你能够经过将类型为PropertySourceLocator
的bean添加到bootstrap上下文中来添加其余来源(经过spring.factories
),例如,你能够从不一样的服务器或数据库插入其余属性。
例如,请考虑如下自定义locator
:
@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属性源定位器中所作的那样)。
若是在其中建立包含此类的jar,而后添加包含如下内容的META-INF/spring.factories
,则customProperty
PropertySource
将出如今其类路径中包含该jar的任何应用程序中:
org.springframework.cloud.bootstrap.BootstrapConfiguration=sample.custom.CustomPropertySourceLocator
若是要使用Spring Boot配置日志设置,则应将此配置放在‘bootstrap.[yml | properties]
’,若是你但愿它适用于全部事件。
要使Spring Cloud正确初始化日志记录配置,你不能使用自定义前缀,例如,初始化日志记录系统时,使用
custom.loggin.logpath
不被Spring Cloud识别。
应用程序侦听EnvironmentChangeEvent
并以几种标准方式对更改作出反应(用户能够正常方式将其余ApplicationListener
添加为@Beans
),当观察到EnvironmentChangeEvent
时,它有一个已更改的键值列表,应用程序使用它们:
@ConfigurationProperties
beanlogging.level.*
中的任何属性设置记录器级别请注意,默认状况下,Config Client不会轮询Environment
中的更改,一般,咱们不建议使用这种方法来检测更改(尽管你可使用@Scheduled
注解进行设置)。若是你有一个扩展的客户端应用程序,最好将EnvironmentChangeEvent
广播到全部实例,而不是让它们轮询更改(例如,经过使用Spring Cloud Bus)。
EnvironmentChangeEvent
涵盖了一大类刷新用例,只要你能够实际更改环境并发布事件便可,请注意,这些API是公共的,而且是核心Spring的一部分。你能够经过访问/configprops
端点(一个正常的Spring Boot Actuator功能)来验证更改是否绑定到@ConfigurationProperties
bean。例如,DataSource
能够在运行时更改其maxPoolSize
(Spring Boot建立的默认DataSource
是@ConfigurationProperties
bean)并动态增长容量。从新绑定@ConfigurationProperties
不包括另外一大类用例,这类用例你须要更多地控制刷新,而且须要对整个ApplicationContext
进行原子性更改,为了解决这些问题,咱们有@RefreshScope
。
当配置发生变化时,标记为@RefreshScope
的Spring @Bean
会获得特殊处理,该特性解决了只有在初始化状态bean时才注入配置的有状态bean的问题。例如,若是DataSource
在经过Environment
更改数据库URL时具备打开的链接,你可能但愿这些链接的持有者可以完成他们正在作的事情,而后,下次从池中借用某个链接时,它会得到一个带有新URL的链接。
有时,甚至可能必须在某些只能初始化一次的bean上应用@RefreshScope
注解,若是bean是“不可变的”,则必须使用@RefreshScope
注解bean,或者在属性键spring.cloud.refresh.extra-refreshable
下指定classname
。
若是你本身建立一个DataSource
bean而且该实现是一个HikariDataSource
,则返回最具体的类型,在本例中为HikariDataSource
,不然,你须要设置spring.cloud.refresh.extra-refreshable=javax.sql.DataSource
。
刷新做用域bean是在使用它们时初始化的惰性代理(即,在调用方法时),而且做用域充当初始化值的缓存,要强制bean在下一个方法调用上从新初始化,必须使其缓存条目无效。
RefreshScope
是上下文中的一个bean,它有一个公共refreshAll()
方法,经过清除目标缓存来刷新做用域中的全部bean,/refresh
端点公开此功能(经过HTTP或JMX),要按名称刷新单个bean,还有一个refresh(String)
方法。
要公开/refresh
端点,你须要将如下配置添加到你的应用程序:
management: endpoints: web: exposure: include: refresh
@RefreshScope
(在技术上)在@Configuration
类上工做,但它可能会致使使人惊讶的行为。例如,它并不意味着该类中定义的全部@Beans
自己都在@RefreshScope
中,具体来讲,依赖于那些bean的任何东西都不能依赖于在启动刷新时更新它们,除非它自己在@RefreshScope
中。在这种状况下,它会在刷新时重建,并从新注入其依赖项,此时,它们将从刷新的@Configuration
从新初始化。
Spring Cloud有一个Environment
预处理器,用于在本地解密属性值,它遵循与Config Server相同的规则,并经过encrypt.*
具备相同的外部配置。所以,你可使用{cipher}*
形式的加密值,只要有有效密钥,它们就会在主应用程序上下文获取Environment
设置以前被解密。要在应用程序中使用加密功能,你须要在类路径中包含Spring Security RSA(Maven:"org.springframework.security:spring-security-rsa
"),而且你还须要JVM中的全强度JCE扩展。
若是因为“Illegal key size”而致使异常,而且你使用Sun的JDK,则须要安装Java加密扩展(JCE)无限制强度权限策略文件,有关更多信息,请参阅如下连接:
不管你使用哪一种版本的JRE/JDK x64/x86,都要将文件解压缩到JDK/jre/lib/security
文件夹中。
对于Spring Boot Actuator应用程序,可使用一些其余管理端点,你可使用:
POST
到/actuator/env
以更新Environment
并从新绑定@ConfigurationProperties
和日志级别。/actuator/refresh
从新加载引导上下文并刷新@RefreshScope
bean。/actuator/restart
关闭ApplicationContext
并从新启动它(默认状况下禁用)。/actuator/pause
和/actuator/resume
用于调用Lifecycle
方法(ApplicationContext
上的stop()
和start()
)。若是禁用/actuator/restart
端点,则/actuator/pause
和/actuator/resume
端点也将被禁用,由于它们只是/actuator/restart
的特殊状况。