SpringApplication
SpringApplication
(Javadoc) クラスは、main()
メソッドから起動される Spring アプリケーションをブートストラップする便利な方法を提供します。多くの場合、次の例に示すように、静的 SpringApplication.run(Class, String…)
(Javadoc) メソッドに委譲できます。
Java
Kotlin
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class MyApplication
fun main(args: Array<String>) {
runApplication<MyApplication>(*args)
}
アプリケーションが起動すると、次のような出力が表示されるはずです。
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.4.1)
2024-12-19T12:20:12.332Z INFO 126957 --- [ main] o.s.b.d.f.logexample.MyApplication : Starting MyApplication using Java 17.0.13 with PID 126957 (/opt/apps/myapp.jar started by myuser in /opt/apps/)
2024-12-19T12:20:12.338Z INFO 126957 --- [ main] o.s.b.d.f.logexample.MyApplication : No active profile set, falling back to 1 default profile: "default"
2024-12-19T12:20:15.485Z INFO 126957 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
2024-12-19T12:20:15.549Z INFO 126957 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2024-12-19T12:20:15.552Z INFO 126957 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.34]
2024-12-19T12:20:15.725Z INFO 126957 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2024-12-19T12:20:15.734Z INFO 126957 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3258 ms
2024-12-19T12:20:17.301Z INFO 126957 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
2024-12-19T12:20:17.340Z INFO 126957 --- [ main] o.s.b.d.f.logexample.MyApplication : Started MyApplication in 6.042 seconds (process running for 6.85)
2024-12-19T12:20:17.366Z INFO 126957 --- [ionShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown : Commencing graceful shutdown. Waiting for active requests to complete
2024-12-19T12:20:17.387Z INFO 126957 --- [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown : Graceful shutdown complete
デフォルトでは、INFO
ロギングメッセージが表示されます。これには、アプリケーションを起動したユーザーなど、関連するスタートアップの詳細が含まれます。INFO
以外のログレベルが必要な場合は、ログレベルの説明に従って設定できます。アプリケーションバージョンは、メインアプリケーションクラスのパッケージの実装バージョンを使用して決定されます。spring.main.log-startup-info
を false
に設定することにより、始動情報のロギングをオフにできます。これにより、アプリケーションのアクティブなプロファイルのログもオフになります。
起動時に追加のログ記録を追加するには、SpringApplication (Javadoc) のサブクラスで logStartupInfo(boolean) をオーバーライドできます。 |
起動失敗
アプリケーションの起動に失敗した場合、登録された FailureAnalyzer
(Javadoc) Bean は、専用のエラーメッセージと問題を解決するための具体的なアクションを提供する機会を得ます。たとえば、ポート 8080
で Web アプリケーションを起動し、そのポートがすでに使用されている場合は、次のようなメッセージが表示されます。
***************************
APPLICATION FAILED TO START
***************************
Description:
Embedded servlet container failed to start. Port 8080 was already in use.
Action:
Identify and stop the process that is listening on port 8080 or configure this application to listen on another port.
Spring Boot は多数の FailureAnalyzer (Javadoc) 実装を提供しており、独自の実装を追加することもできます。 |
例外を処理できる障害アナライザーがない場合でも、完全な状態レポートを表示して、何が問題だったのかをよりよく理解することができます。そのためには、debug
プロパティを有効にするか、ConditionEvaluationReportLoggingListener
(Javadoc) の DEBUG
ログを有効にする必要があります。
たとえば、java -jar
を使用してアプリケーションを実行している場合、次のように debug
プロパティを有効にできます。
$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug
遅延初期化
SpringApplication
(Javadoc) を使用すると、アプリケーションを遅延初期化できます。遅延初期化を有効にすると、アプリケーションの起動時ではなく、必要に応じて Bean が作成されます。その結果、遅延初期化を有効にすると、アプリケーションの起動にかかる時間が短縮されます。Web アプリケーションでは、遅延初期化を有効にすると、多くの Web 関連 Bean が HTTP リクエストを受信するまで初期化されません。
遅延初期化の欠点は、アプリケーションの問題の発見を遅らせる可能性があることです。誤って構成された Bean が遅延初期化された場合、起動時に障害は発生せず、Bean が初期化されたときにのみ問題が明らかになります。また、JVM に、起動時に初期化される Bean だけでなく、アプリケーションのすべての Bean を収容するのに十分なメモリがあることを確認する必要があります。これらの理由により、遅延初期化はデフォルトでは有効になっていないため、遅延初期化を有効にする前に JVM のヒープサイズの微調整を行うことをお勧めします。
遅延初期化は、SpringApplicationBuilder
(Javadoc) の lazyInitialization
メソッドまたは SpringApplication
(Javadoc) の setLazyInitialization
メソッドを使用してプログラムで有効にできます。または、次の例に示すように、spring.main.lazy-initialization
プロパティを使用して有効にすることもできます。
プロパティ
YAML
spring.main.lazy-initialization=true
spring:
main:
lazy-initialization: true
残りのアプリケーションで遅延初期化を使用しているときに特定の Bean の遅延初期化を無効にする場合は、@Lazy(false) アノテーションを使用して遅延属性を明示的に false に設定できます。 |
バナーのカスタマイズ
起動時に出力されるバナーは、クラスパスに banner.txt
ファイルを追加するか、spring.banner.location
プロパティをそのようなファイルの場所に設定することで変更できます。ファイルに UTF-8 以外のエンコーディングがある場合は、spring.banner.charset
を設定できます。
banner.txt
ファイル内では、Environment
(Javadoc) で使用可能な任意のキーと、次のプレースホルダーのいずれかを使用できます。
変数 | 説明 |
---|---|
|
|
|
|
| 使用している Spring Boot バージョン。たとえば、 |
| 使用する Spring Boot バージョン。表示用にフォーマットされています(括弧で囲まれ、接頭部が |
|
Where |
|
|
プログラムでバナーを生成する場合は、SpringApplication.setBanner(…) メソッドを使用できます。Banner (Javadoc) インターフェースを使用して、独自の printBanner() メソッドを実装します。 |
また、spring.main.banner-mode
プロパティを使用して、バナーを System.out
(標準 Javadoc) に出力するか (console
)、構成されたロガーに送信するか (log
)、まったく生成しないか (off
) を決定することもできます。
出力されたバナーは、springBootBanner
という名前でシングルトン Bean として登録されます。
|
SpringApplication のカスタマイズ
SpringApplication
(Javadoc) のデフォルト設定が気に入らない場合は、代わりにローカルインスタンスを作成してカスタマイズできます。例: バナーをオフにするには、次のように記述します。
Java
Kotlin
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MyApplication.class);
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
}
}
import org.springframework.boot.Banner
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class MyApplication
fun main(args: Array<String>) {
runApplication<MyApplication>(*args) {
setBannerMode(Banner.Mode.OFF)
}
}
SpringApplication (Javadoc) に渡されるコンストラクター引数は、Spring Bean の構成ソースです。ほとんどの場合、これらは @Configuration (Javadoc) クラスへの参照ですが、@Component (Javadoc) クラスへの直接参照である場合もあります。 |
application.properties
ファイルを使用して SpringApplication
(Javadoc) を構成することもできます。詳細については、環境別の設定切り替えを参照してください。
構成オプションの完全なリストについては、SpringApplication
(Javadoc) API ドキュメントを参照してください。
Fluent Builder API
ApplicationContext
(Javadoc) 階層 (親子関連を持つ複数のコンテキスト) を構築する必要がある場合、または Fluent Builder API を使用する場合は、SpringApplicationBuilder
(Javadoc) を使用できます。
SpringApplicationBuilder
(Javadoc) を使用すると、複数のメソッド呼び出しをまとめて チェーンすることができ、次の例に示すように、階層を作成できる parent
メソッドと child
メソッドが含まれています。
Java
Kotlin
new SpringApplicationBuilder().sources(Parent.class)
.child(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);
SpringApplicationBuilder()
.sources(Parent::class.java)
.child(Application::class.java)
.bannerMode(Banner.Mode.OFF)
.run(*args)
ApplicationContext (Javadoc) 階層を作成する際には、いくつかの制限があります。例: Web コンポーネントは子コンテキスト内に含まれている必要があり、親コンテキストと子コンテキストの両方に同じ Environment (Javadoc) が使用されます。詳細については、SpringApplicationBuilder (Javadoc) API ドキュメントを参照してください。 |
アプリケーションの可用性
アプリケーションをプラットフォームにデプロイすると、Kubernetes プローブ (英語) などのインフラストラクチャを使用して、アプリケーションがその可用性に関する情報をプラットフォームに提供できます。Spring Boot には、一般的に使用される「活性」と「準備」の可用性状態のサポートが含まれています。Spring Boot の「アクチュエーター」サポートを使用している場合、これらの状態はヘルスエンドポイントグループとして公開されます。
さらに、ApplicationAvailability
(Javadoc) インターフェースを独自の Bean に挿入することで、可用性の状態を取得することもできます。
活性状態
アプリケーションの「活性」状態は、その内部状態によってアプリケーションが正しく機能するかどうか、現在障害が発生している場合は自動的に回復するかどうかを示します。壊れた「活性」状態は、アプリケーションが回復できない状態にあり、インフラストラクチャがアプリケーションを再起動する必要があることを意味します。
一般に、"Liveness" 状態はヘルスチェックなどの外部チェックに基づいてはなりません。そうした場合、障害が発生した外部システム (データベース、Web API、外部キャッシュ) によって、大規模な再起動がトリガーされ、プラットフォーム全体で障害が連鎖的に発生します。 |
Spring Boot アプリケーションの内部状態は、主に Spring ApplicationContext
(Javadoc) によって表されます。アプリケーションコンテキストが正常に開始された場合、Spring Boot はアプリケーションが有効な状態にあると想定します。コンテキストがリフレッシュされるとすぐに、アプリケーションはライブであるとみなされます。Spring Boot アプリケーションのライフサイクルと関連するアプリケーションイベントを参照してください。
準備状態
アプリケーションの「準備」状態は、アプリケーションがトラフィックを処理する準備ができているかどうかを示します。「準備」状態が失敗している場合、プラットフォームは現時点ではトラフィックをアプリケーションにルーティングすべきではないと認識します。これは通常、起動時、CommandLineRunner
(Javadoc) および ApplicationRunner
(Javadoc) コンポーネントの処理中、またはアプリケーションが追加のトラフィックに対してビジー状態であると判断した場合に発生します。
アプリケーションとコマンドラインランナーが呼び出されるとすぐに、アプリケーションは準備ができていると見なされます。Spring Boot アプリケーションのライフサイクルと関連するアプリケーションイベントを参照してください。
起動時に実行されることが予想されるタスクは、@PostConstruct (英語) などの Spring コンポーネントライフサイクルコールバックを使用するのではなく、CommandLineRunner (Javadoc) および ApplicationRunner (Javadoc) コンポーネントによって実行される必要があります。 |
アプリケーションの可用性状態の管理
アプリケーションコンポーネントは、ApplicationAvailability
(Javadoc) インターフェースを挿入し、そのメソッドを呼び出すことで、いつでも現在の可用性状態を取得できます。多くの場合、アプリケーションは状態の更新をリッスンしたり、アプリケーションの状態を更新したりする必要があります。
例: アプリケーションの「準備」状態をファイルにエクスポートして、Kubernetes の「exec プローブ」がこのファイルを確認できるようにします。
Java
Kotlin
import org.springframework.boot.availability.AvailabilityChangeEvent;
import org.springframework.boot.availability.ReadinessState;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class MyReadinessStateExporter {
@EventListener
public void onStateChange(AvailabilityChangeEvent<ReadinessState> event) {
switch (event.getState()) {
case ACCEPTING_TRAFFIC -> {
// create file /tmp/healthy
}
case REFUSING_TRAFFIC -> {
// remove file /tmp/healthy
}
}
}
}
import org.springframework.boot.availability.AvailabilityChangeEvent
import org.springframework.boot.availability.ReadinessState
import org.springframework.context.event.EventListener
import org.springframework.stereotype.Component
@Component
class MyReadinessStateExporter {
@EventListener
fun onStateChange(event: AvailabilityChangeEvent<ReadinessState?>) {
when (event.state) {
ReadinessState.ACCEPTING_TRAFFIC -> {
// create file /tmp/healthy
}
ReadinessState.REFUSING_TRAFFIC -> {
// remove file /tmp/healthy
}
else -> {
// ...
}
}
}
}
アプリケーションが壊れて回復できない場合は、アプリケーションの状態を更新することもできます。
Java
Kotlin
import org.springframework.boot.availability.AvailabilityChangeEvent;
import org.springframework.boot.availability.LivenessState;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
@Component
public class MyLocalCacheVerifier {
private final ApplicationEventPublisher eventPublisher;
public MyLocalCacheVerifier(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void checkLocalCache() {
try {
// ...
}
catch (CacheCompletelyBrokenException ex) {
AvailabilityChangeEvent.publish(this.eventPublisher, ex, LivenessState.BROKEN);
}
}
}
import org.springframework.boot.availability.AvailabilityChangeEvent
import org.springframework.boot.availability.LivenessState
import org.springframework.context.ApplicationEventPublisher
import org.springframework.stereotype.Component
@Component
class MyLocalCacheVerifier(private val eventPublisher: ApplicationEventPublisher) {
fun checkLocalCache() {
try {
// ...
} catch (ex: CacheCompletelyBrokenException) {
AvailabilityChangeEvent.publish(eventPublisher, ex, LivenessState.BROKEN)
}
}
}
Spring Boot はアクチュエーターヘルスエンドポイントを使用した「活性」と「準備」の Kubernetes HTTP プローブを提供します。Kubernetes での Spring Boot アプリケーションのデプロイに関する詳細なガイダンスについては、専用セクションを参照してください。
アプリケーションイベントとリスナー
ContextRefreshedEvent
(Javadoc) などの通常の Spring Framework イベントに加えて、SpringApplication
(Javadoc) はいくつかの追加のアプリケーションイベントを送信します。
一部のイベントは実際には アプリケーションの作成方法に関係なく、これらのリスナーを自動的に登録したい場合は、次の例に示すように、プロジェクトに
|
アプリケーションが実行されると、アプリケーションイベントは次の順序で送信されます。
ApplicationStartingEvent
(Javadoc) は、リスナーと初期化子の登録を除き、実行の開始時に、あらゆる処理の前に送信されます。コンテキスト内で使用される
Environment
(Javadoc) がわかっているが、コンテキストが作成される前に、ApplicationEnvironmentPreparedEvent
(Javadoc) が送信されます。ApplicationContext
(Javadoc) が準備され、ApplicationContextInitializers が呼び出されましたが、Bean 定義がロードされる前に、ApplicationContextInitializedEvent
(Javadoc) が送信されます。ApplicationPreparedEvent
(Javadoc) は、リフレッシュが開始される直前、ただし Bean 定義がロードされた後に送信されます。ApplicationStartedEvent
(Javadoc) は、コンテキストがリフレッシュされた後、アプリケーションおよびコマンドラインランナーが呼び出される前に送信されます。アプリケーションがライブであるとみなされることを示すために、
AvailabilityChangeEvent
(Javadoc) がLivenessState.CORRECT
(Javadoc) の直後に送信されます。アプリケーションおよびコマンドラインランナーが呼び出された後、
ApplicationReadyEvent
(Javadoc) が送信されます。AvailabilityChangeEvent
(Javadoc) はReadinessState.ACCEPTING_TRAFFIC
(Javadoc) の直後に送信され、アプリケーションがリクエストを処理する準備ができていることを示します。起動時に例外が発生した場合、
ApplicationFailedEvent
(Javadoc) が送信されます。
上記のリストには、SpringApplication
(Javadoc) に関連付けられている SpringApplicationEvent
のみが含まれています。これらに加えて、ApplicationPreparedEvent
(Javadoc) の後、ApplicationStartedEvent
(Javadoc) の前に次のイベントも公開されます。
WebServer
(Javadoc) の準備ができたら、WebServerInitializedEvent
(Javadoc) が送信されます。ServletWebServerInitializedEvent
(Javadoc) とReactiveWebServerInitializedEvent
(Javadoc) は、それぞれサーブレットとリアクティブのバリアントです。ApplicationContext
(Javadoc) がリフレッシュされると、ContextRefreshedEvent
(Javadoc) が送信されます。
多くの場合、アプリケーションイベントを使用する必要はありませんが、それらが存在することを知っておくと便利です。内部的に、Spring Boot はイベントを使用してさまざまなタスクを処理します。 |
イベントリスナーは、デフォルトでは同じスレッドで実行されるため、長時間かかる可能性のあるタスクを実行しないでください。代わりに、アプリケーションランナーとコマンドラインランナーの使用を検討してください。 |
アプリケーションイベントは、Spring Framework のイベント公開メカニズムを使用して送信されます。このメカニズムの一部は、子コンテキストのリスナーに公開されたイベントが、祖先コンテキストのリスナーにも公開されることを保証します。この結果、アプリケーションが SpringApplication
(Javadoc) インスタンスの階層を使用する場合、リスナーは同じタイプのアプリケーションイベントの複数のインスタンスを受信する可能性があります。
リスナーが自身のコンテキストのイベントと子孫コンテキストのイベントを区別できるようにするには、アプリケーションコンテキストの挿入をリクエストし、挿入されたコンテキストをイベントのコンテキストと比較する必要があります。コンテキストは、ApplicationContextAware
(Javadoc) を実装するか、リスナーが Bean の場合は @Autowired
(Javadoc) を使用して挿入できます。
Web 環境
SpringApplication
(Javadoc) は、ユーザーに代わって適切な型の ApplicationContext
(Javadoc) を作成しようとします。WebApplicationType
(Javadoc) を決定するために使用されるアルゴリズムは次のとおりです。
Spring MVC が存在する場合は
AnnotationConfigServletWebServerApplicationContext
(Javadoc) が使用されるSpring MVC が存在せず、Spring WebFlux が存在する場合は、
AnnotationConfigReactiveWebServerApplicationContext
(Javadoc) が使用されます。それ以外の場合は
AnnotationConfigApplicationContext
(Javadoc) が使用される
つまり、同じアプリケーションで Spring MVC と Spring WebFlux の新しい WebClient
(Javadoc) を使用している場合、デフォルトでは Spring MVC が使用されることになります。setWebApplicationType(WebApplicationType)
を呼び出すことで、これを簡単にオーバーライドできます。
setApplicationContextFactory(…)
を呼び出すことによって使用される ApplicationContext
(Javadoc) 型を完全に制御することも可能です。
JUnit テスト内で SpringApplication (Javadoc) を使用する場合は、setWebApplicationType(WebApplicationType.NONE) を呼び出すことが望ましい場合がよくあります。 |
アプリケーション引数へのアクセス
SpringApplication.run(…)
に渡されたアプリケーション引数にアクセスする必要がある場合は、ApplicationArguments
(Javadoc) Bean を挿入できます。次の例に示すように、ApplicationArguments
(Javadoc) インターフェースは、生の String[]
引数と解析された option
および non-option
引数の両方へのアクセスを提供します。
Java
Kotlin
import java.util.List;
import org.springframework.boot.ApplicationArguments;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
if (debug) {
System.out.println(files);
}
// if run with "--debug logfile.txt" prints ["logfile.txt"]
}
}
import org.springframework.boot.ApplicationArguments
import org.springframework.stereotype.Component
@Component
class MyBean(args: ApplicationArguments) {
init {
val debug = args.containsOption("debug")
val files = args.nonOptionArgs
if (debug) {
println(files)
}
// if run with "--debug logfile.txt" prints ["logfile.txt"]
}
}
Spring Boot は、Spring Environment (Javadoc) とともに CommandLinePropertySource (Javadoc) も登録します。これにより、@Value (Javadoc) アノテーションを使用して単一のアプリケーション引数を挿入することもできます。 |
ApplicationRunner または CommandLineRunner の使用
SpringApplication
(Javadoc) が起動した後に特定のコードを実行する必要がある場合は、ApplicationRunner
(Javadoc) または CommandLineRunner
(Javadoc) インターフェースを実装できます。両方のインターフェースは同じように動作し、SpringApplication.run(…)
が完了する直前に呼び出される単一の run
メソッドを提供します。
この契約は、アプリケーションの起動後、トラフィックの受け入れを開始する前に実行する必要があるタスクに適しています。 |
CommandLineRunner
(Javadoc) インターフェースは、文字列配列としてアプリケーション引数へのアクセスを提供しますが、ApplicationRunner
(Javadoc) は前述の ApplicationArguments
(Javadoc) インターフェースを使用します。次の例は、run
メソッドを使用した CommandLineRunner
(Javadoc) を示しています。
Java
Kotlin
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) {
// Do something...
}
}
import org.springframework.boot.CommandLineRunner
import org.springframework.stereotype.Component
@Component
class MyCommandLineRunner : CommandLineRunner {
override fun run(vararg args: String) {
// Do something...
}
}
特定の順序で呼び出す必要がある複数の CommandLineRunner
(Javadoc) または ApplicationRunner
(Javadoc) Bean が定義されている場合は、追加で Ordered
(Javadoc) インターフェースを実装するか、Order
(Javadoc) アノテーションを使用することができます。
アプリケーション終了
各 SpringApplication
(Javadoc) は、終了時に ApplicationContext
(Javadoc) が正常に終了するように、JVM にシャットダウンフックを登録します。すべての標準 Spring ライフサイクルコールバック (DisposableBean
(Javadoc) インターフェースや @PreDestroy
(英語) アノテーションなど) を使用できます。
さらに、SpringApplication.exit()
が呼び出されたときに特定の終了コードを返す必要がある場合、Bean は ExitCodeGenerator
(Javadoc) インターフェースを実装できます。この終了コードは、次の例に示すように、System.exit()
に渡されてステータスコードとして返されます。
Java
Kotlin
import org.springframework.boot.ExitCodeGenerator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class MyApplication {
@Bean
public ExitCodeGenerator exitCodeGenerator() {
return () -> 42;
}
public static void main(String[] args) {
System.exit(SpringApplication.exit(SpringApplication.run(MyApplication.class, args)));
}
}
import org.springframework.boot.ExitCodeGenerator
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Bean
import kotlin.system.exitProcess
@SpringBootApplication
class MyApplication {
@Bean
fun exitCodeGenerator() = ExitCodeGenerator { 42 }
}
fun main(args: Array<String>) {
exitProcess(SpringApplication.exit(
runApplication<MyApplication>(*args)))
}
また、ExitCodeGenerator
(Javadoc) インターフェースは例外によって実装される場合もあります。このような例外が発生すると、Spring Boot は実装された getExitCode()
メソッドによって提供される終了コードを返します。
ExitCodeGenerator
(Javadoc) が複数ある場合は、最初に生成されたゼロ以外の終了コードが使用されます。ジェネレーターが呼び出される順序を制御するには、さらに Ordered
(Javadoc) インターフェースを実装するか、Order
(Javadoc) アノテーションを使用します。
管理機能
spring.application.admin.enabled
プロパティを指定することで、アプリケーションの管理関連機能を有効にすることができます。これにより、プラットフォーム MBeanServer
(標準 Javadoc) 上の SpringApplicationAdminMXBean
(Javadoc) が公開されます。この機能を使用して、Spring Boot アプリケーションをリモートで管理できます。この機能は、サービスラッパーの実装にも役立ちます。
アプリケーションが実行されている HTTP ポートを知りたい場合は、local.server.port のキーを持つプロパティを取得します。 |
アプリケーションのスタートアップの追跡
アプリケーションの起動中、SpringApplication
(Javadoc) と ApplicationContext
(Javadoc) は、アプリケーションのライフサイクル、Bean のライフサイクル、さらにはアプリケーションイベントの処理に関連する多くのタスクを実行します。ApplicationStartup
(Javadoc) 、Spring Framework、StartupStep
を使用してアプリケーションの起動シーケンスを追跡できますオブジェクトを使用します。このデータは、プロファイリングの目的で収集することも、アプリケーションの起動プロセスをより深く理解するために収集することもできます。
SpringApplication
(Javadoc) インスタンスを設定するときに、ApplicationStartup
(Javadoc) 実装を選択できます。例: BufferingApplicationStartup
(Javadoc) を使用するには、次のように記述します。
Java
Kotlin
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MyApplication.class);
application.setApplicationStartup(new BufferingApplicationStartup(2048));
application.run(args);
}
}
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup
import org.springframework.boot.runApplication
@SpringBootApplication
class MyApplication
fun main(args: Array<String>) {
runApplication<MyApplication>(*args) {
applicationStartup = BufferingApplicationStartup(2048)
}
}
最初の利用可能な実装である FlightRecorderApplicationStartup
(Javadoc) は、Spring Framework によって提供されます。これは、Spring 固有の起動イベントを Java Flight Recorder セッションに追加し、アプリケーションのプロファイリングと、Spring コンテキストライフサイクルと JVM イベント (割り当て、GC、クラスの読み込みなど) の相関関係の把握を目的としています。設定が完了したら、Flight Recorder を有効にしてアプリケーションを実行してデータを記録できます。
$ java -XX:StartFlightRecording:filename=recording.jfr,duration=10s -jar demo.jar
Spring Boot には BufferingApplicationStartup
(Javadoc) バリアントが付属しています。この実装は、起動手順をバッファリングし、外部のメトリクスシステムに排出することを目的としています。アプリケーションは、任意のコンポーネントで型 BufferingApplicationStartup
(Javadoc) の Bean を要求できます。
Spring Boot は、この情報を JSON ドキュメントとして提供する startup
エンドポイントを公開するように構成することもできます。
仮想スレッド
Java 21 以降で実行している場合は、プロパティ spring.threads.virtual.enabled
を true
に設定することで仮想スレッドを有効にできます。
アプリケーションでこのオプションをオンにする前に、Java 仮想スレッドの公式ドキュメントを読む [Oracle] ことを検討してください。場合によっては、「固定された仮想スレッド」が原因でアプリケーションのスループットが低下することがあります。このページでは、JDK Flight Recorder または jcmd
CLI を使用してそのようなケースを検出する方法についても説明します。
仮想スレッドが有効になっている場合、スレッドプールを構成するプロパティは効果がありません。これは、仮想スレッドが専用のスレッドプールではなく、JVM 全体のプラットフォームスレッドプールでスケジュールされるためです。 |
仮想スレッドの副作用の 1 つは、それがデーモンスレッドであることです。すべてのスレッドがデーモンスレッドである場合、JVM は終了します。この動作は、たとえば、アプリケーションの稼働を維持するために @Scheduled (Javadoc) Bean に依存している場合に問題となる可能性があります。仮想スレッドを使用する場合、スケジューラスレッドは仮想スレッドであるためデーモンスレッドとなり、JVM を稼働させ続けることはできません。これはスケジューリングに影響するだけでなく、他のテクノロジにも当てはまります。すべての場合に JVM を稼働させ続けるには、プロパティ spring.main.keep-alive を true に設定することをお勧めします。これにより、すべてのスレッドが仮想スレッドであっても、JVM を稼働させ続けることができます。 |