Some changes a while back had switched off refreshing the bootstrap config (because of the way it was being detected in an existing environment to prevent an infinite loop). This change fixes that by adding a dummy property source during bootstrap and then removing it again.
Spring Platform Components
This project contains boilerplate patterns for distributed application components, making those patterns easy to implement with Spring (and Spring Boot in particular).
Spring Boot Features
Bootstrap Listener - A SpringApplication with the platform
components on its classpath will have an extended bootstrap phase,
allowing new strategies for configuration management and other
non-functional features to be added to the application before it is
initialized. The implementation is similar to
@EnableAutoConfiguration, allowing new jars to contribute additional
features by defining BootstrapConfiguration classes in the form of
@Configuration. Instead of being added to the application's context
they are added to a special "bootstrap" context, which is then used to
extract ApplicationContextInitializers to apply to the application
before it is created. A typical use case would be to locate and
install additional environment properties so that the application can
adapt to its environment in a completely flexible way.
Autoconfiguration - An application using
@EnableAutoConfiguration will pick up beans for the components
below, notably RefreshEndpoint, EnvironmentManager and
RefreshScope.
RefreshEndpoint
Re-initializes the bootstrap environment, and sends a
EnvironmentChangeEvent if any properties changed. Both the
RefreshScope and the ConfigurationPropertiesRebinder respond to
this event. Exposed at /refresh.
EnvironmentManager and EnvironmentManagerEndpoint
The EnvironmentManager allows you to modify the Spring Environment
in a running application. It adds a PropertySource with high
priority to the Environment (so properties set there will take
precedence). If you have the Actuator and are in a webapp then the
EnvironmentManagerEndpoint will also expose "/env" with POST for
updating the EnvironmentManager remotely. E.g. run the app locally:
@Configuration
@EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
then interact with the Environment:
$ curl localhost:8080/env/message
Hello
$ curl localhost:8080/env -d message=Foo
$ curl localhost:8080/env/message
Foo
Doing this (or the equivalent operation over JMX) will trigger an event
that leads to rebinding of @ConfigurationProperties (see below).
ConfigurationPropertiesRebinder
Spring beans that are @ConfigurationProperties can be rebound if the Environment changes. Example:
@ConfigurationProperties
protected static class ServiceProperties {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
then inject ServiceProperties into an application component using @Autowired and use it to govern the behaviour.
When the Environment changes do this
@Autowired
private ConfigurationPropertiesRebinder rebinder;
...
rebinder.rebind();
The ConfigurationPropertiesRebinder is also a @ManagedResource so you can ping the rebind() operation remotely.
RefreshScope
Spring beans in scope="refresh" are re-initialized on the next method call after a refresh. Example:
@Configuration
@EnableConfigurationProperties(TestProperties.class)
@EnableAutoConfiguration
protected static class TestConfiguration {
@Autowired
private TestProperties properties;
@Bean
@RefreshScope
public ExampleService service() {
ExampleService service = new ExampleService();
service.setMessage(properties.getMessage());
service.setDelay(properties.getDelay());
return service;
}
}
then update the TestProperties (e.g. via JMX or something), and
@Autowired
private RefreshScope scope;
...
// ...and then refresh, so the bean is re-initialized:
scope.refresh("service");