I have a Spring boot Web application. The application is configured via java classes using the @Configurable annotation. I have introduced two profiles: 'install', 'normal'. If the install profile is active, none of the Beans that require DB connection is loaded. I want to create a controller where the user can set up the db connection parameters and When it's done I want to switch the active profile from 'install' to 'normal' and refresh the application context, so the Spring can init every bean that needs DB data source.
I can modify the list of active profiles from code, without problems, but when i try to refresh the application context, i get the following exception:
`java.lang.IllegalStateException:
GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once`
This is how i boot my Spring boot app:
`new SpringApplicationBuilder().sources(MyApp.class)
.profiles("my-profile").build().run(args);`
Does anybody know how to initiate spring boot app that let's you refresh the app context multiple times ?
You can use: POST to /actuator/env to update the Environment and rebind @ConfigurationProperties and log levels. /actuator/refresh to re-load the boot strap context and refresh the @RefreshScope beans. /actuator/restart to close the ApplicationContext and restart it (disabled by default).
To change properties in a file during runtime, we should place that file somewhere outside the jar. Then we tell Spring where it is with the command-line parameter –spring. config. location=file://{path to file}.
ApplicationContext is a corner stone of a Spring Boot application. It represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the beans. The container gets its instructions on what objects to instantiate, configure, and assemble by reading configuration metadata.
You can't just refresh an existing context. You have to close the old one and create a new one. You can see how we do it in Spring Cloud here: https://github.com/spring-cloud/spring-cloud-commons/blob/master/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java. If you want to you can include that Endpoint
just by adding spring-cloud-context as a dependency, or you can copy the code I guess and use it in your own "endpoint".
Here's the endpoint implementation (some details missing in fields):
@ManagedOperation
public synchronized ConfigurableApplicationContext restart() {
if (this.context != null) {
if (this.integrationShutdown != null) {
this.integrationShutdown.stop(this.timeout);
}
this.application.setEnvironment(this.context.getEnvironment());
this.context.close();
overrideClassLoaderForRestart();
this.context = this.application.run(this.args);
}
return this.context;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With