SpringApplication
SpringApplication
クラスは、main()
メソッドから開始される Spring アプリケーションをブートストラップする便利な方法を提供します。多くの場合、次の例に示すように、静的 SpringApplication.run
メソッドに委譲できます。
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.3.1)
2024-06-20T10:08:25.916Z INFO 112065 --- [ main] o.s.b.d.f.logexample.MyApplication : Starting MyApplication using Java 17.0.11 with PID 112065 (/opt/apps/myapp.jar started by myuser in /opt/apps/)
2024-06-20T10:08:25.931Z INFO 112065 --- [ main] o.s.b.d.f.logexample.MyApplication : No active profile set, falling back to 1 default profile: "default"
2024-06-20T10:08:28.799Z INFO 112065 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
2024-06-20T10:08:28.828Z INFO 112065 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2024-06-20T10:08:28.841Z INFO 112065 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.25]
2024-06-20T10:08:29.018Z INFO 112065 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2024-06-20T10:08:29.030Z INFO 112065 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2892 ms
2024-06-20T10:08:30.841Z INFO 112065 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
2024-06-20T10:08:30.878Z INFO 112065 --- [ main] o.s.b.d.f.logexample.MyApplication : Started MyApplication in 6.515 seconds (process running for 8.658)
デフォルトでは、INFO
ロギングメッセージが表示されます。これには、アプリケーションを起動したユーザーなど、関連するスタートアップの詳細が含まれます。INFO
以外のログレベルが必要な場合は、ログレベルの説明に従って設定できます。アプリケーションバージョンは、メインアプリケーションクラスのパッケージの実装バージョンを使用して決定されます。spring.main.log-startup-info
を false
に設定することにより、始動情報のロギングをオフにできます。これにより、アプリケーションのアクティブなプロファイルのログもオフになります。
起動時に追加のログを追加するには、SpringApplication のサブクラスで logStartupInfo(boolean) をオーバーライドできます。 |
起動失敗
アプリケーションの起動に失敗した場合、登録された FailureAnalyzers
は、専用のエラーメッセージと、問題を修正するための具体的なアクションを提供する機会を得ます。たとえば、ポート 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 実装を提供しており、独自の FailureAnalyzer 実装を追加できます。 |
例外を処理できる障害アナライザーがない場合でも、完全な状態レポートを表示して、何が問題になったのかをよりよく理解できます。これを行うには、debug
プロパティを有効にするか、org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
の DEBUG
ロギングを有効にする必要があります。
たとえば、java -jar
を使用してアプリケーションを実行している場合、次のように debug
プロパティを有効にできます。
$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug
遅延初期化
SpringApplication
を使用すると、アプリケーションを遅延的に初期化できます。遅延初期化が有効な場合、Bean はアプリケーションの起動時ではなく、必要に応じて作成されます。その結果、遅延初期化を有効にすると、アプリケーションの起動にかかる時間を短縮できます。Web アプリケーションでは、遅延初期化を有効にすると、HTTP リクエストを受信するまで多くの Web 関連 Bean が初期化されなくなります。
遅延初期化の欠点は、アプリケーションの問題の発見を遅らせる可能性があることです。誤って構成された Bean が遅延初期化された場合、起動時に障害は発生せず、Bean が初期化されたときにのみ問題が明らかになります。また、JVM に、起動時に初期化される Bean だけでなく、アプリケーションのすべての Bean を収容するのに十分なメモリがあることを確認する必要があります。これらの理由により、遅延初期化はデフォルトでは有効になっていないため、遅延初期化を有効にする前に JVM のヒープサイズの微調整を行うことをお勧めします。
遅延初期化は、SpringApplicationBuilder
の lazyInitialization
メソッドまたは SpringApplication
の 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
で使用可能な任意のキーと、次のプレースホルダーのいずれかを使用できます。
変数 | 説明 |
---|---|
|
|
|
|
| 使用している Spring Boot バージョン。たとえば、 |
| 使用する Spring Boot バージョン。表示用にフォーマットされています(括弧で囲まれ、接頭部が |
|
Where |
|
|
SpringApplication.setBanner(…) メソッドは、プログラムでバナーを生成する場合に使用できます。org.springframework.boot.Banner インターフェースを使用して、独自の printBanner() メソッドを実装します。 |
spring.main.banner-mode
プロパティを使用して、バナーを System.out
(console
)に出力するか、構成されたロガーに送信する(log
)か、まったく生成しない(off
)かを決定することもできます。
出力されたバナーは、springBootBanner
という名前でシングルトン Bean として登録されます。
|
SpringApplication のカスタマイズ
SpringApplication
のデフォルトが好みに合わない場合は、代わりにローカルインスタンスを作成してカスタマイズできます。例: バナーをオフにするには、次のように記述できます。
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 に渡されるコンストラクター引数は、Spring Bean の構成ソースです。ほとんどの場合、これらは @Configuration クラスへの参照ですが、@Component クラスへの直接参照である場合もあります。 |
application.properties
ファイルを使用して SpringApplication
を構成することもできます。詳細については、環境別の設定切り替えを参照してください。
構成オプションの完全なリストについては、SpringApplication
Javadoc を参照してください。
Fluent Builder API
ApplicationContext
階層(親 / 子関連を持つ複数のコンテキスト)を構築する必要がある場合、または「流れるような」ビルダー API を使用する場合は、SpringApplicationBuilder
を使用できます。
SpringApplicationBuilder
を使用すると、チェーンで複数のメソッド呼び出しを行うことができ、次の例に示すように、階層を作成できる 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 階層を作成する場合、いくつかの制限があります。例: Web コンポーネントは子コンテキスト内に含まれている必要があり、同じ Environment が親コンテキストと子コンテキストの両方に使用されます。詳細については、SpringApplicationBuilder Javadoc を参照してください。 |
アプリケーションの可用性
アプリケーションをプラットフォームにデプロイすると、Kubernetes プローブ (英語) などのインフラストラクチャを使用して、アプリケーションがその可用性に関する情報をプラットフォームに提供できます。Spring Boot には、一般的に使用される「活性」と「準備」の可用性状態のサポートが含まれています。Spring Boot の「アクチュエーター」サポートを使用している場合、これらの状態はヘルスエンドポイントグループとして公開されます。
さらに、ApplicationAvailability
インターフェースを独自の Bean に挿入することにより、可用性の状態を取得することもできます。
活性状態
アプリケーションの「活性」状態は、その内部状態によってアプリケーションが正しく機能するかどうか、現在障害が発生している場合は自動的に回復するかどうかを示します。壊れた「活性」状態は、アプリケーションが回復できない状態にあり、インフラストラクチャがアプリケーションを再起動する必要があることを意味します。
一般に、「活性」状態はヘルス診断などの外部チェックに基づくべきではありません。その場合、障害のある外部システム(データベース、Web API、外部キャッシュ)により、プラットフォーム全体で大規模な再起動とカスケード障害がトリガーされます。 |
Spring Boot アプリケーションの内部状態は、主に Spring ApplicationContext
で表されます。アプリケーションコンテキストが正常に開始された場合、Spring Boot はアプリケーションが有効な状態にあると想定します。アプリケーションは、コンテキストがリフレッシュされるとすぐにライブと見なされます。Spring Boot アプリケーションのライフサイクルと関連するアプリケーションイベントを参照してください。
準備状態
アプリケーションの「準備完了」状態は、アプリケーションがトラフィックを処理する準備ができているかどうかを示します。失敗した「準備完了」状態は、今のところトラフィックをアプリケーションにルーティングするべきではないことをプラットフォームに通知します。これは通常、起動中、CommandLineRunner
および ApplicationRunner
コンポーネントの処理中、またはアプリケーションが追加のトラフィックに対してビジーすぎると判断した場合に発生します。
アプリケーションとコマンドラインランナーが呼び出されるとすぐに、アプリケーションは準備ができていると見なされます。Spring Boot アプリケーションのライフサイクルと関連するアプリケーションイベントを参照してください。
起動時に実行されることが予想されるタスクは、@PostConstruct などの Spring コンポーネントライフサイクルコールバックを使用する代わりに、CommandLineRunner および ApplicationRunner コンポーネントによって実行される必要があります。 |
アプリケーションの可用性状態の管理
アプリケーションコンポーネントは、ApplicationAvailability
インターフェースを挿入し、その上でメソッドを呼び出すことにより、いつでも現在の可用性の状態を取得できます。多くの場合、アプリケーションは状態の更新をリッスンしたり、アプリケーションの状態を更新したりします。
例: アプリケーションの「準備」状態をファイルにエクスポートして、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
は追加のアプリケーションイベントを送信します。
アプリケーションの作成方法に関係なく、これらのリスナーを自動的に登録する場合は、次の例に示すように、
|
アプリケーションが実行されると、アプリケーションイベントは次の順序で送信されます。
ApplicationStartingEvent
は実行の開始時に送信されますが、リスナーと初期化子の登録を除き、処理の前に送信されます。ApplicationEnvironmentPreparedEvent
は、コンテキストで使用されるEnvironment
がわかっているが、コンテキストが作成される前に送信されます。ApplicationContextInitializedEvent
は、ApplicationContext
が準備され、ApplicationContextInitializers が呼び出されましたが、Bean 定義がロードされる前に送信されます。ApplicationPreparedEvent
は、リフレッシュが開始される直前、ただし Bean 定義がロードされた後に送信されます。ApplicationStartedEvent
は、コンテキストがリフレッシュされた後、アプリケーションとコマンドラインランナーが呼び出される前に送信されます。LivenessState.CORRECT
の直後にAvailabilityChangeEvent
が送信され、アプリケーションがライブと見なされることが示されます。ApplicationReadyEvent
は、アプリケーションとコマンドラインランナーが呼び出された後に送信されます。AvailabilityChangeEvent
はReadinessState.ACCEPTING_TRAFFIC
の直後に送信され、アプリケーションがリクエストを処理する準備ができていることを示します。起動時に例外がある場合、
ApplicationFailedEvent
が送信されます。
上記のリストには、SpringApplication
に関連付けられている SpringApplicationEvent
のみが含まれています。これらに加えて、次のイベントも ApplicationPreparedEvent
の後、ApplicationStartedEvent
の前に公開されます。
WebServer
の準備が整うと、WebServerInitializedEvent
が送信されます。ServletWebServerInitializedEvent
とReactiveWebServerInitializedEvent
は、それぞれサーブレットとリアクティブバリアントです。ApplicationContext
がリフレッシュされると、ContextRefreshedEvent
が送信されます。
多くの場合、アプリケーションイベントを使用する必要はありませんが、それらが存在することを知っておくと便利です。内部的に、Spring Boot はイベントを使用してさまざまなタスクを処理します。 |
イベントリスナーは、デフォルトでは同じスレッドで実行されるため、長時間かかる可能性のあるタスクを実行しないでください。代わりに、アプリケーションランナーとコマンドラインランナーの使用を検討してください。 |
アプリケーションイベントは、Spring Framework のイベント発行メカニズムを使用して送信されます。このメカニズムの一部により、子コンテキストでリスナーに発行されたイベントは、すべての祖先コンテキストでリスナーにも発行されます。この結果、アプリケーションが SpringApplication
インスタンスの階層を使用している場合、リスナーは同じタイプのアプリケーションイベントの複数のインスタンスを受け取る場合があります。
リスナーがそのコンテキストのイベントと子孫コンテキストのイベントを区別できるようにするには、アプリケーションコンテキストの注入をリクエストし、注入されたコンテキストをイベントのコンテキストと比較する必要があります。コンテキストは、ApplicationContextAware
を実装するか、リスナーが Bean の場合は @Autowired
を使用して注入できます。
Web 環境
SpringApplication
が適切な型の ApplicationContext
を作成しようとします。WebApplicationType
を決定するために使用されるアルゴリズムは次のとおりです。
Spring MVC が存在する場合、
AnnotationConfigServletWebServerApplicationContext
が使用されます。Spring MVC がなく、Spring WebFlux が存在する場合は、
AnnotationConfigReactiveWebServerApplicationContext
が使用されます。それ以外の場合、
AnnotationConfigApplicationContext
が使用されます
これは、同じアプリケーションで Spring MVC と Spring WebFlux の新しい WebClient
を使用している場合、デフォルトで Spring MVC が使用されることを意味します。setWebApplicationType(WebApplicationType)
を呼び出すことで簡単にオーバーライドできます。
setApplicationContextFactory(…)
を呼び出すことで使用される ApplicationContext
型を完全に制御することもできます。
JUnit テスト内で SpringApplication を使用する場合、setWebApplicationType(WebApplicationType.NONE) を呼び出すことが望ましい場合がよくあります。 |
アプリケーション引数へのアクセス
SpringApplication.run(…)
に渡されたアプリケーション引数にアクセスする必要がある場合は、org.springframework.boot.ApplicationArguments
Bean を注入できます。ApplicationArguments
インターフェースは、次の例に示すように、未加工の 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 は、CommandLinePropertySource を Spring Environment に登録します。これにより、@Value アノテーションを使用して、単一のアプリケーション引数を注入することもできます。 |
ApplicationRunner または CommandLineRunner の使用
SpringApplication
の起動後に特定のコードを実行する必要がある場合は、ApplicationRunner
または CommandLineRunner
インターフェースを実装できます。両方のインターフェースは同じように機能し、SpringApplication.run(…)
が完了する直前に呼び出される単一の run
メソッドを提供します。
この契約は、アプリケーションの起動後、トラフィックの受け入れを開始する前に実行する必要があるタスクに適しています。 |
CommandLineRunner
インターフェースはアプリケーションの引数へのアクセスを文字列配列として提供しますが、ApplicationRunner
は前述の ApplicationArguments
インターフェースを使用します。次の例は、run
メソッドを使用した CommandLineRunner
を示しています。
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
または ApplicationRunner
Bean が定義されている場合、org.springframework.core.Ordered
インターフェースをさらに実装するか、org.springframework.core.annotation.Order
アノテーションを使用できます。
アプリケーション終了
各 SpringApplication
はシャットダウンフックを JVM に登録して、ApplicationContext
が終了時に正常に閉じるようにします。すべての標準 Spring ライフサイクルコールバック(DisposableBean
インターフェースや @PreDestroy
アノテーションなど)を使用できます。
さらに、Bean は、SpringApplication.exit()
が呼び出されたときに特定の終了コードを返したい場合、org.springframework.boot.ExitCodeGenerator
インターフェースを実装できます。次の例に示すように、この終了コードを 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
インターフェースは例外によって実装される場合があります。このような例外が発生すると、Spring Boot は、実装された getExitCode()
メソッドによって提供される終了コードを返します。
複数の ExitCodeGenerator
がある場合、最初に生成されたゼロ以外の終了コードが使用されます。ジェネレーターが呼び出される順序を制御するには、org.springframework.core.Ordered
インターフェースを追加で実装するか、org.springframework.core.annotation.Order
アノテーションを使用します。
管理機能
spring.application.admin.enabled
プロパティを指定することにより、アプリケーションの管理関連機能を有効にすることができます。これにより、プラットフォーム MBeanServer
で SpringApplicationAdminMXBean
(Javadoc) が公開されます。この機能を使用して、Spring Boot アプリケーションをリモートで管理できます。この機能は、サービスラッパーの実装にも役立ちます。
アプリケーションが実行されている HTTP ポートを知りたい場合は、local.server.port のキーを持つプロパティを取得します。 |
アプリケーションのスタートアップの追跡
アプリケーションの起動時に、SpringApplication
と ApplicationContext
は、アプリケーションのライフサイクル、Bean のライフサイクル、さらにはアプリケーションイベントの処理に関連する多くのタスクを実行します。ApplicationStartup
(Javadoc) を使用すると、Spring Framework を使用すると、StartupStep
オブジェクトを使用してアプリケーションの起動シーケンスを追跡できます。このデータは、プロファイリングの目的で、または単にアプリケーションの起動プロセスをよりよく理解するために収集できます。
SpringApplication
インスタンスをセットアップするときに、ApplicationStartup
実装を選択できます。例: BufferingApplicationStartup
を使用するには、次のように記述できます。
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
は、Spring Framework によって提供されます。これは、Spring 固有の起動イベントを Java Flight Recorder セッションに追加し、アプリケーションのプロファイリングと、それらの Spring コンテキストライフサイクルを JVM イベント(割り当て、GC、クラスの読み込みなど)と相関させることを目的としています。構成が完了すると、フライトレコーダーを有効にしてアプリケーションを実行することでデータを記録できます。
$ java -XX:StartFlightRecording:filename=recording.jfr,duration=10s -jar demo.jar
Spring Boot には BufferingApplicationStartup
バリアントが付属しています。この実装は、起動ステップをバッファリングし、外部メトリクスシステムに排出することを目的としています。アプリケーションは、任意のコンポーネントで型 BufferingApplicationStartup
の Bean を要求できます。
Spring Boot は、この情報を JSON ドキュメントとして提供する startup
エンドポイントを公開するように構成することもできます。
仮想スレッド
Java 21 以降で実行している場合は、プロパティ spring.threads.virtual.enabled
を true
に設定することで仮想スレッドを有効にできます。
アプリケーションでこのオプションをオンにする前に、Java 仮想スレッドの公式ドキュメントを読む [Oracle] ことを検討してください。場合によっては、「固定された仮想スレッド」が原因でアプリケーションのスループットが低下することがあります。このページでは、JDK Flight Recorder または jcmd
CLI を使用してそのようなケースを検出する方法についても説明します。
仮想スレッドの副作用の 1 つは、仮想スレッドがデーモンスレッドであることです。JVM のすべてのスレッドがデーモンスレッドである場合、JVM は終了します。この動作は、たとえばアプリケーションを存続させるために @Scheduled Bean に依存している場合に問題になる可能性があります。仮想スレッドを使用する場合、スケジューラスレッドは仮想スレッドであるため、デーモンスレッドとなり、JVM を存続させ続けることはありません。これはスケジューリングに影響を与えるだけでなく、他のテクノロジーにも当てはまる可能性があります。いかなる場合でも JVM を実行し続けるには、プロパティ spring.main.keep-alive を true に設定することをお勧めします。これにより、すべてのスレッドが仮想スレッドであっても、JVM は確実に存続します。 |