1. 概述
在本教程中,我們將演示如何程序化地重啓 Spring Boot 應用程序。
重啓我們的應用程序在某些情況下非常實用:
- 在參數發生更改時重新加載配置文件
- 在運行時更改當前活動配置文件
- 出於任何原因重新初始化應用程序上下文
雖然本文檔涵蓋了重啓 Spring Boot 應用程序的功能,但我們也有一篇關於關閉 Spring Boot 應用程序的優秀教程。
現在,讓我們探索我們如何實現 Spring Boot 應用程序重啓的不同方法。
2. 通過創建新上下文重啓應用
我們可以通過關閉應用上下文並從頭創建一個新的上下文來重啓我們的應用程序。雖然這種方法相當簡單,但為了確保其正常工作,我們需要仔細注意一些細節。
下面是如何在 Spring Boot 應用的 main 方法中實現此操作的方法:
@SpringBootApplication
public class Application {
private static ConfigurableApplicationContext context;
public static void main(String[] args) {
context = SpringApplication.run(Application.class, args);
}
public static void restart() {
ApplicationArguments args = context.getBean(ApplicationArguments.class);
Thread thread = new Thread(() -> {
context.close();
context = SpringApplication.run(Application.class, args.getSourceArgs());
});
thread.setDaemon(false);
thread.start();
}
}如上例所示,重要的是在單獨的非守護線程中重建上下文——這樣可以防止由 close 方法觸發的 JVM 關閉導致我們的應用程序停止。否則,由於 JVM 不會等待守護線程完成,我們的應用程序將停止。
此外,讓我們通過 REST 端點來觸發重啓:
@RestController
public class RestartController {
@PostMapping("/restart")
public void restart() {
Application.restart();
}
}在這裏,我們添加了一個控制器,其中包含一個映射方法,該方法調用我們的 restart 方法。
然後,我們可以調用新的端點來重啓應用程序:
curl -X POST localhost:port/restart當然,如果在實際應用中添加這樣一個端點,我們還需要對其進行安全保護。
3. Actuator 的重啓端點
使用內置的 RestartEndpoint 從 Spring Boot Actuator 可以重啓我們的應用程序。
首先,讓我們添加所需的 Maven 依賴項:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>接下來,我們需要在我們的 application.properties文件中啓用內置的重啓端點:
management.endpoint.restart.enabled=true現在我們已經完成了所有設置,可以向我們的服務中注入重啓端點:
@Service
public class RestartService {
@Autowired
private RestartEndpoint restartEndpoint;
public void restartApp() {
restartEndpoint.restart();
}
}在上述代碼中,我們使用 RestartEndpoint Bean 來重啓我們的應用程序。 這是一個方便的重啓方式,因為我們只需要調用一個方法來完成所有工作。
正如我們所見,使用 RestartEndpoint 是一種簡單的方式來重啓我們的應用程序。 然而,這種方法也有缺點,因為它需要我們添加指定的庫。 如果我們尚未使用它們,這可能會對該功能造成過多的開銷。 在這種情況下,我們可以堅持上一節中手動的方法,因為它只需要幾行代碼。
4. 刷新應用程序上下文
在某些情況下,我們可以通過調用其 refresh 方法來重新加載應用程序上下文。
儘管這個方法聽起來很有前景,但只有某些應用程序上下文類型支持重新刷新已經初始化過的上下文。例如,FileSystemXmlApplicationContext、GroovyWebApplicationContext以及少數其他類型支持此功能。
不幸的是,如果在 Spring Boot Web 應用程序中嘗試這樣做,將會得到以下錯誤:
java.lang.IllegalStateException: GenericApplicationContext does not support multiple refresh attempts:
just call 'refresh' once最後,雖然某些上下文類型支持多次刷新,但我們應該避免這樣做。原因在於 refresh 方法被設計為框架內部的方法,用於初始化應用程序上下文。
結論
在本文中,我們探討了多種通過編程方式重啓 Spring Boot 應用程序的方法。