Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
757 views
in Technique[技术] by (71.8m points)

java - Modify active profiles and refresh ApplicationContext runtime in a Spring Boot application

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 ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...