diff --git a/docs/src/main/asciidoc/spring-cloud-config.adoc b/docs/src/main/asciidoc/spring-cloud-config.adoc index 99bb5df7..b6f74970 100644 --- a/docs/src/main/asciidoc/spring-cloud-config.adoc +++ b/docs/src/main/asciidoc/spring-cloud-config.adoc @@ -358,97 +358,6 @@ behavior, set the bootstrap configuration property `spring.cloud.config.failFast=true` and the client will halt with an Exception. -=== Environment Changes - -The application will listen for an `EnvironmentChangedEvent` and react -to the change in a couple of standard ways (additional -`ApplicationListeners` can be added as `@Beans` by the user in the -normal way). When an `EnvironmentChangedEvent` is observed it will -have a list of key values that have changed, and the application will -use those to: - -* Re-bind any `@ConfigurationProperties` beans in the context -* Set the logger levels for any properties in `logging.level.*` - -Note that the Config Client does not by default poll for changes in -the `Environment`, and generally we would not recommend that approach -for detecting changes (although you could set it up with a -`@Scheduled` annotation). If you have a scaled-out client application -then it is better to broadcast the `EnvironmentChangedEvent` to all -the instances instead of having them polling for changes (e.g. using -the https://github.com/spring-cloud/spring-cloud-bus[Spring Cloud -Bus]). - -The `EnvironmentChangedEvent` covers a large class of refresh use -cases, as long as you can actually make a change to the `Environment` -and publish the event (those APIs are public and part of core -Spring). You can verify the changes are bound to -`@ConfigurationProperties` beans by visiting the `/configprops` -endpoint (normal Spring Boot Actuator feature). For instance a -`DataSource` can have its `maxPoolSize` changed at runtime (the -default `DataSource` created by Spring Boot is an -`@ConfigurationProperties` bean) and grow capacity -dynamically. Re-binding `@ConfigurationProperties` does not cover -another large class of use cases, where you need more control over the -refresh, and where you need a change to be atomic over the whole -`ApplicationContext`. To address those concerns we have -`@RefreshScope`. - -=== Refresh Scope - -A Spring `@Bean` that is marked as `@RefreshScope` will get special -treatment when there is a configuration change. This addresses the -problem of stateful beans that only get their configuration injected -when they are initialized. For instance if a `DataSource` has open -connections when the database URL is changed via the `Environment`, we -probably want the holders of those connections to be able to complete -what they are doing. Then the next time someone borrows a connection -from the pool he gets one with the new URL. - -Refresh scope beans are lazy proxies that initialize when they are -used (i.e. when a method is called), and the scope acts as a cache of -initialized values. To force a bean to re-initialize on the next -method call you just need to invalidate its cache entry. - -The `RefreshScope` is a bean in the context and it has a public method -`refreshAll()` to refresh all beans in the scope by clearing the -target cache. There is also a `refresh(String)` method to refresh an -individual bean by name. This functionality is exposed in the -`/refresh` endpoint (over HTTP or JMX). - -NOTE: `@RefreshScope` works (technically) on an `@Configuration` -class, but it might lead to surprising behaviour: e.g. it does *not* -mean that all the `@Beans` defined in that class are themselves -`@RefreshScope`. Specifically, anything that depends on those beans -cannot rely on them being updated when a refresh is initiated, unless -it is itself in `@RefreshScope` (in which it will be rebuilt on a -refresh and its dependencies re-injected, at which point they will be -re-initialized from the refreshed `@Configuration`). - -=== Encryption and Decryption - -The Config Client has an `Environment` pre-processor for decrypting -property values locally. It follows the same rules as the Config -Server, and has the same external configuration via `encrypt.\*`. Thus -you can use encrypted values in the form `{cipher}*` and as long as -there is a valid key then they will be decrypted before the main -application context gets the `Environment`. To use the encryption -features in a client you need to include Spring Security RSA in your -classpath (Maven co-ordinates -"org.springframework.security:spring-security-rsa") and you also need -the full strength JCE extensions in your JVM (google it and download -from Oracle). - -=== Endpoints - -For a Spring Boot Actuator application there are some additional management endpoints: - -* POST to `/env` to update the `Environment` and rebind `@ConfigurationProperties` and log levels -* `/refresh` for re-loading the boot strap context and refreshing the `@RefreshScope` beans -* `/restart` for closing the `ApplicationContext` and restarting it (disabled by default) -* `/pause` and `/resume` for calling the `Lifecycle` methods (`stop()` and `start()` on the `ApplicationContext`) - - === Locating Remote Configuration Resources The Config Service serves property sources from `/{name}/{env}/{label}`, where the default bindings in the @@ -464,173 +373,6 @@ rolling back to previous versions of configuration; with the default Config Server implementation it can be a git label, branch name or commit id. -=== The Bootstrap Application Context - -The Config Client operates by creating a "bootstrap" application -context, which is a parent context for the main application. Out of -the box it is responsible for loading configuration properties from -the Config Server, and also decrypting properties in the local -external configuration files. The two contexts share an `Environment` -which is the source of external properties for any Spring -application. Bootstrap properties are added with high precedence, so -they cannot be overridden by local configuration. - -The bootstrap context uses a different convention for locating -external configuration than the main application context, so instead -of `application.yml` (or `.properties`) you use `bootstrap.yml`, -keeping the external configuration for bootstrap and main context -nicely separate. Example: - -.bootstrap.yml ----- -spring: - application: - name: foo - cloud: - config: - uri: ${SPRING_CONFIG_URI:http://localhost:8888} ----- - -It is a good idea to set the `spring.application.name` (in -`bootstrap.yml` or `application.yml`) if your application needs any -application-specific configuration from the server. - -You can disable the bootstrap process completely by setting -`spring.cloud.bootstrap.enabled=false` (e.g. in System properties). - -=== Application Context Hierarchies - -If you build an application context from `SpringApplication` or -`SpringApplicationBuilder`, then the Bootstrap context is added as a -parent to that context. It is a feature of Spring that child contexts -inherit property sources and profiles from their parent, so the "main" -application context will contain additional property sources, compared -to building the same context without Spring Cloud Config. The -additional property sources are: - -* "bootstrap": an optional `CompositePropertySource` appears with high -priority if any `PropertySourceLocators` are found in the Bootstrap -context, and they have non-empty properties. An example would be -properties from the Spring Cloud Config Server. See -link:#customizing-bootstrap-property-sources[below] for instructions -on how to customize the contents of this property source. - -* "applicationConfig: [classpath:bootstrap.yml]" (and friends if -Spring profiles are active). If you have a `bootstrap.yml` (or -properties) then those properties are used to configure the Bootstrap -context, and then they get added to the child context when its parent -is set. They have lower precedence than the `application.yml` (or -properties) and any other property sources that are added to the child -as a normal part of the process of creating a Spring Boot -application. See link:#customizing-bootstrap-properties[below] for -instructions on how to customize the contents of these property -sources. - -Because of the ordering rules of property sources the "bootstrap" -entries take precedence, but note that these do not contain any data -from `bootstrap.yml`, which has very low precedence, but can be used -to set defaults. - -You can extend the context hierarchy by simply setting the parent -context of any `ApplicationContext` you create, e.g. using its own -interface, or with the `SpringApplicationBuilder` convenience methods -(`parent()`, `child()` and `sibling()`). The bootstrap context will be -the parent of the most senior ancestor that you create yourself. -Every context in the hierarchy will have its own "bootstrap" property -source (possibly empty) to avoid promoting values inadvertently from -parents down to their descendants. Every context in the hierarchy can -also (in principle) have a different `spring.application.name` and -hence a different remote property source if there is a Config -Server. Normal Spring application context behaviour rules apply to -property resolution: properties from a child context override those in -the parent, by name and also by property source name (if the child has -a property source with the same name as the parent, the one from the -parent is not included in the child). - -Note that the `SpringApplicationBuilder` allows you to share an -`Environment` amongst the whole hierarchy, but that is not the -default. Thus, sibling contexts in particular do not need to have the -same profiles or property sources, even though they will share common -things with their parent. - -[[customizing-bootstrap-properties]] -=== Changing the Location of Bootstrap Properties - -The `bootstrap.yml` (or `.properties) location can be specified using -`spring.cloud.bootstrap.name` (default "bootstrap") or -`spring.cloud.bootstrap.location` (default empty), e.g. in System -properties. Those properties behave like the `spring.config.*` -variants with the same name, in fact they are used to set up the -bootstrap `ApplicationContext` by setting those properties in its -`Environment`. If there is an active profile (from -`spring.profiles.active` or through the `Environment` API in the -context you are building) then properties in that profile will be -loaded as well, just like in a regular Spring Boot app, e.g. from -`bootstrap-development.properties` for a "development" profile. - -=== Customizing the Bootstrap Configuration - -The bootstrap context can be trained to do anything you like by adding -entries to `/META-INF/spring.factories` under the key -`org.springframework.cloud.bootstrap.BootstrapConfiguration`. This is -a comma-separated list of Spring `@Configuration` classes which will -be used to create the context. Any beans that you want to be available -to the main application context for autowiring can be created here, -and also there is a special contract for `@Beans` of type -`ApplicationContextInitializer`. - -The bootstrap process ends by injecting initializers into the main -`SpringApplication` instance (i.e. the normal Spring Boot startup -sequence, whether it is running as a standalone app or deployed in an -application server). First a bootstrap context is created from the -classes found in `spring.factories` and then all `@Beans` of type -`ApplicationContextInitializer` are added to the main -`SpringApplication` before it is started. - -[[customizing-bootstrap-property-sources]] -=== Customizing the Bootstrap Property Sources - -The default property source for external configuration added by the -bootstrap process is the Config Server, but you can add additional -sources by adding beans of type `PropertySourceLocator` to the -bootstrap context (via `spring.factories`). You could use this to -insert additional properties from a different server, or from a -database, for instance. - -As an example, consider the following trivial custom locator: - -[source,java] ----- -@Configuration -public class CustomPropertySourceLocator implements PropertySourceLocator { - - @Override - public PropertySource locate(Environment environment) { - return new MapPropertySource("customProperty", - Collections.singletonMap("property.from.sample.custom.source", "worked as intended")); - } - -} ----- - -The `Environment` that is passed in is the one for the -`ApplicationContext` about to be created, i.e. the one that we are -supplying additional property sources for. It will already have its -normal Spring Boot-provided property sources, so you can use those to -locate a property source specific to this `Environment` (e.g. by -keying it on the `spring.application.name`, as is done in the default -Config Server property source locator). - -If you create a jar with this class in it and then add a -`META-INF/spring.factories` containing: - ----- -org.springframework.cloud.bootstrap.BootstrapConfiguration=sample.custom.CustomPropertySourceLocator ----- - -then the "customProperty" `PropertySource` will show up in any -application that includes that jar on its classpath. - === Security If you use HTTP Basic security on the server then clients just need to diff --git a/spring-cloud-config-client/pom.xml b/spring-cloud-config-client/pom.xml index f77a276c..c68f3cd0 100644 --- a/spring-cloud-config-client/pom.xml +++ b/spring-cloud-config-client/pom.xml @@ -30,6 +30,10 @@ org.springframework.cloud spring-cloud-commons + + org.springframework.cloud + spring-cloud-context + org.springframework spring-web