プログラムによるSpring Bootアプリケーションの再起動
1概要
このチュートリアルでは、Spring Bootアプリケーションをプログラム的に再起動する方法を説明します。
場合によっては、アプリケーションを再起動すると非常に便利です。
-
いくつかのパラメータを変更した際の設定ファイルの再読み込み
-
実行時に現在アクティブなプロファイルを変更する
-
何らかの理由でアプリケーションコンテキストを再初期化する
この記事ではSpring Bootアプリケーションを再起動する機能について説明していますが、https://www.baeldung.com/spring-boot-shutdown[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アクチュエータの再起動エンドポイント
アプリケーションを再起動するもう1つの方法は、
httpsから組み込みの
RestartEndpoint__を使用することです。
まず、必要な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
これですべての設定が完了したので、
__RestartEndpoint
__をサービスにインジェクトできます。
@Service
public class RestartService {
@Autowired
private RestartEndpoint restartEndpoint;
public void restartApp() {
restartEndpoint.restart();
}
}
上記のコードでは、
RestartEndpoint
Beanを使用してアプリケーションを再起動しています。すべての作業を実行するメソッドを1つ呼び出すだけでよいので、これは再起動の良い方法です。
ご覧のとおり、
RestartEndpoint
を使用すると、アプリケーションを簡単に再起動できます。反対に、この方法には、前述のライブラリを追加する必要があるため、欠点があります。まだ使用していない場合は、この機能だけではオーバーヘッドが大きすぎる可能性があります。その場合、前のセクションからの手動のアプローチに固執することができます。
4アプリケーションコンテキストの更新
場合によっては、https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ConfigurableApplicationContext.html#refresh–[refreshを呼び出して、アプリケーションコンテキストをリロードできます。]方法。
この方法は有望に思えるかもしれませんが、すでに初期化されたコンテキストのリフレッシュをサポートするのは一部のアプリケーションコンテキストタイプのみです。たとえば、
FileSystemXmlApplicationContext
、
GroovyWebApplicationContext、
などのいくつかがサポートしています。
残念ながら、Spring Boot Webアプリケーションでこれを試すと、次のエラーが発生します。
java.lang.IllegalStateException: GenericApplicationContext does not support multiple refresh attempts:
just call 'refresh' once
最後に、複数の更新をサポートするコンテキストタイプがいくつかありますが、これを避けるべきです。その理由は、
refresh
メソッドは、アプリケーションコンテキストを初期化するためにフレームワークによって使用される内部メソッドとして設計されているためです。
5結論
この記事では、Spring Bootアプリケーションをプログラムで再起動する方法をいくつか紹介しました。
いつものように、例のソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-boot-ops[GitHub]にあります。