このセクションでは、Spring Boot の詳細について説明します。ここでは、使用およびカスタマイズしたい主な機能について学習できます。まだ読んでいない場合は、「getting-started.html」セクションと「using-spring-boot.html」セクションを読んで、基本を十分に理解しましょう。

1. SpringApplication

SpringApplication クラスは、main() メソッドから開始される Spring アプリケーションをブートストラップする便利な方法を提供します。多くの場合、次の例に示すように、静的 SpringApplication.run メソッドに委譲できます。

public static void main(String[] args) {
    SpringApplication.run(MySpringConfiguration.class, args);
}

アプリケーションが起動すると、次のような出力が表示されるはずです。

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::   v2.3.4.RELEASE

2019-04-31 13:09:54.117  INFO 56603 --- [           main] o.s.b.s.app.SampleApplication            : Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb)
2019-04-31 13:09:54.166  INFO 56603 --- [           main] ationConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.ser[email protected] (英語)  6e5a8246: startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy
2019-04-01 13:09:56.912  INFO 41370 --- [           main] .t.TomcatServletWebServerFactory : Server initialized with port: 8080
2019-04-01 13:09:57.501  INFO 41370 --- [           main] o.s.b.s.app.SampleApplication            : Started SampleApplication in 2.992 seconds (JVM running for 3.658)

デフォルトでは、INFO ロギングメッセージが表示されます。これには、アプリケーションを起動したユーザーなど、関連するスタートアップの詳細が含まれます。INFO 以外のログレベルが必要な場合は、ログレベルの説明に従って設定できます。アプリケーションバージョンは、メインアプリケーションクラスのパッケージの実装バージョンを使用して決定されます。spring.main.log-startup-info を false に設定することにより、始動情報のロギングをオフにできます。これにより、アプリケーションのアクティブなプロファイルのログもオフになります。

起動時に追加のログを追加するには、SpringApplication のサブクラスで logStartupInfo(boolean) をオーバーライドできます。

1.1. 起動失敗

アプリケーションの起動に失敗した場合、登録された 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's listening on port 8080 or configure this application to listen on another port.
Spring Boot は、多数の FailureAnalyzer 実装を提供します。独自の実装を追加できます。

障害アナライザーが例外を処理できない場合でも、完全な状態レポートを表示して、問題の原因をよりよく理解できます。これを行うには、debug プロパティを有効にするか、org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener の DEBUG ロギングを有効にする必要があります。

たとえば、java -jar を使用してアプリケーションを実行している場合、次のように debug プロパティを有効にできます。

$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug

1.2. 遅延初期化

SpringApplication を使用すると、アプリケーションを遅延的に初期化できます。遅延初期化が有効な場合、Bean はアプリケーションの起動時ではなく、必要に応じて作成されます。その結果、遅延初期化を有効にすると、アプリケーションの起動にかかる時間を短縮できます。Web アプリケーションでは、遅延初期化を有効にすると、HTTP リクエストを受信するまで多くの Web 関連 Bean が初期化されなくなります。

遅延初期化の欠点は、アプリケーションの問題の発見を遅らせる可能性があることです。誤って構成された Bean が遅延初期化された場合、起動時に障害は発生せず、Bean が初期化されたときにのみ問題が明らかになります。また、JVM に、起動時に初期化される Bean だけでなく、アプリケーションのすべての Bean を収容するのに十分なメモリがあることを確認する必要があります。これらの理由により、遅延初期化はデフォルトでは有効になっていないため、遅延初期化を有効にする前に JVM のヒープサイズの微調整を行うことをお勧めします。

遅延初期化は、SpringApplicationBuilder の lazyInitialization メソッドまたは SpringApplication の setLazyInitialization メソッドを使用してプログラムで有効にできます。または、次の例に示すように、spring.main.lazy-initialization プロパティを使用して有効にすることもできます。

spring.main.lazy-initialization=true
残りのアプリケーションで遅延初期化を使用しているときに特定の Bean の遅延初期化を無効にする場合は、@Lazy(false) アノテーションを使用して遅延属性を明示的に false に設定できます。

1.3. バナーのカスタマイズ

起動時に出力されるバナーを変更するには、banner.txt ファイルをクラスパスに追加するか、spring.banner.location プロパティをそのようなファイルの場所に設定します。ファイルに UTF-8 以外のエンコードが含まれている場合は、spring.banner.charset を設定できます。テキストファイルに加えて、banner.gifbanner.jpg または banner.png イメージファイルをクラスパスに追加したり、spring.banner.image.location プロパティを設定したりすることもできます。イメージは ASCII アート表現に変換され、テキストバナーの上に出力されます。

banner.txt ファイル内では、次のプレースホルダーのいずれかを使用できます。

表 1: バナー変数
変数 説明

${application.version}

MANIFEST.MF で宣言されているアプリケーションのバージョン番号。例: Implementation-Version: 1.0 は 1.0 として出力されます。

${application.formatted-version}

MANIFEST.MF で宣言され、表示用にフォーマットされたアプリケーションのバージョン番号(括弧で囲まれ、接頭部が v)。たとえば、(v1.0)

${spring-boot.version}

使用している Spring Boot バージョン。たとえば、2.3.4.RELEASE

${spring-boot.formatted-version}

使用する Spring Boot バージョン。表示用にフォーマットされています(括弧で囲まれ、接頭部が v)。たとえば、(v2.3.4.RELEASE)

${Ansi.NAME} (または ${AnsiColor.NAME}${AnsiBackground.NAME}${AnsiStyle.NAME})

ここで、NAME は ANSI エスケープコードの名前です。詳細については、AnsiPropertySource (GitHub) を参照してください。

${application.title}

MANIFEST.MF で宣言されているアプリケーションのタイトル。たとえば、Implementation-Title: MyApp は MyApp として出力されます。

SpringApplication.setBanner(…​) メソッドは、プログラムでバナーを生成する場合に使用できます。org.springframework.boot.Banner インターフェースを使用して、独自の printBanner() メソッドを実装します。

spring.main.banner-mode プロパティを使用して、バナーを System.out (console)に出力するか、構成されたロガーに送信する(log)か、まったく生成しない(off)かを決定することもできます。

出力されたバナーは、springBootBanner という名前でシングルトン Bean として登録されます。

1.4. SpringApplication のカスタマイズ

SpringApplication のデフォルトが好みに合わない場合は、代わりにローカルインスタンスを作成してカスタマイズできます。例:バナーをオフにするには、次のように記述できます。

public static void main(String[] args) {
    SpringApplication app = new SpringApplication(MySpringConfiguration.class);
    app.setBannerMode(Banner.Mode.OFF);
    app.run(args);
}
SpringApplication に渡されるコンストラクター引数は、Spring Bean の構成ソースです。ほとんどの場合、これらは @Configuration クラスへの参照ですが、XML 構成またはスキャンする必要があるパッケージへの参照にすることもできます。

application.properties ファイルを使用して SpringApplication を構成することもできます。詳細については、外部化された構成を参照してください。

構成オプションの完全なリストについては、SpringApplication Javadoc を参照してください。

1.5. Fluent Builder API

ApplicationContext 階層(親 / 子関連を持つ複数のコンテキスト)を構築する必要がある場合、または「流れるような」ビルダー API を使用する場合は、SpringApplicationBuilder を使用できます。

SpringApplicationBuilder を使用すると、チェーンで複数のメソッド呼び出しを行うことができ、次の例に示すように、階層を作成できる parent および child メソッドが含まれます。

new SpringApplicationBuilder()
        .sources(Parent.class)
        .child(Application.class)
        .bannerMode(Banner.Mode.OFF)
        .run(args);
ApplicationContext 階層を作成する場合、いくつかの制限があります。例:Web コンポーネントは子コンテキスト内に含まれている必要があり、同じ Environment が親コンテキストと子コンテキストの両方に使用されます。詳細については、SpringApplicationBuilder Javadoc を参照してください。

1.6. アプリケーションの可用性

アプリケーションをプラットフォームにデプロイすると、Kubernetes プローブ (英語) などのインフラストラクチャを使用して、アプリケーションがその可用性に関する情報をプラットフォームに提供できます。Spring Boot には、一般的に使用される「活性」と「準備」の可用性状態のサポートが含まれています。Spring Boot の「アクチュエーター」サポートを使用している場合、これらの状態はヘルスエンドポイントグループとして公開されます。

さらに、ApplicationAvailability インターフェースを独自の Bean に挿入することにより、可用性の状態を取得することもできます。

1.6.1. 活性状態

アプリケーションの「活性」状態は、アプリケーションの内部状態が正しく動作するかどうか、または現在障害が発生している場合はそれ自体で回復するかどうかを示します。壊れた「活性」状態は、アプリケーションが回復できない状態にあり、インフラストラクチャがアプリケーションを再起動する必要があることを意味します。

一般に、「活性」状態はヘルス診断などの外部チェックに基づくべきではありません。その場合、障害のある外部システム(データベース、Web API、外部キャッシュ)により、プラットフォーム全体で大規模な再起動とカスケード障害がトリガーされます。

Spring Boot アプリケーションの内部状態は、主に Spring ApplicationContext で表されます。アプリケーションコンテキストが正常に開始された場合、Spring Boot はアプリケーションが有効な状態にあると想定します。アプリケーションは、コンテキストがリフレッシュされるとすぐにライブと見なされます。Spring Boot アプリケーションのライフサイクルと関連するアプリケーションイベントを参照してください。

1.6.2. 準備状態

アプリケーションの「準備」状態は、アプリケーションがトラフィックを処理する準備ができているかどうかを示します。「Readiness」状態が失敗すると、プラットフォームに、現時点ではトラフィックをアプリケーションにルーティングしないように指示します。これは通常、起動時に発生します。CommandLineRunner および ApplicationRunner コンポーネントが処理されている間、またはアプリケーションが追加のトラフィックに対してビジー状態であると判断した場合はいつでも発生します。

アプリケーションとコマンドラインランナーが呼び出されるとすぐに、アプリケーションは準備ができていると見なされます。Spring Boot アプリケーションのライフサイクルと関連するアプリケーションイベントを参照してください。

起動時に実行されることが予想されるタスクは、@PostConstruct などの Spring コンポーネントライフサイクルコールバックを使用する代わりに、CommandLineRunner および ApplicationRunner コンポーネントによって実行される必要があります。

1.6.3. アプリケーションの可用性状態の管理

アプリケーションコンポーネントは、ApplicationAvailability インターフェースを挿入し、その上でメソッドを呼び出すことにより、いつでも現在の可用性の状態を取得できます。多くの場合、アプリケーションは状態の更新をリッスンしたり、アプリケーションの状態を更新したりします。

例:アプリケーションの「準備」状態をファイルにエクスポートして、Kubernetes の「exec プローブ」がこのファイルを確認できるようにします。

@Component
public class ReadinessStateExporter {

    @EventListener
    public void onStateChange(AvailabilityChangeEvent<ReadinessState> event) {
        switch (event.getState()) {
        case ACCEPTING_TRAFFIC:
            // create file /tmp/healthy
        break;
        case REFUSING_TRAFFIC:
            // remove file /tmp/healthy
        break;
        }
    }

}

アプリケーションが壊れて回復できない場合は、アプリケーションの状態を更新することもできます。

@Component
public class LocalCacheVerifier {

    private final ApplicationEventPublisher eventPublisher;

    public LocalCacheVerifier(ApplicationEventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }

    public void checkLocalCache() {
        try {
            //...
        }
        catch (CacheCompletelyBrokenException ex) {
            AvailabilityChangeEvent.publish(this.eventPublisher, ex, LivenessState.BROKEN);
        }
    }

}

1.7. アプリケーションイベントとリスナー

ContextRefreshedEvent(Javadoc) などの通常の Spring Framework イベントに加えて、SpringApplication は追加のアプリケーションイベントを送信します。

ApplicationContext が作成される前に実際にトリガーされるイベントもあるため、それらのリスナーを @Bean として登録することはできません。SpringApplication.addListeners(…​) メソッドまたは SpringApplicationBuilder.listeners(…​) メソッドで登録できます。

アプリケーションの作成方法に関係なく、これらのリスナーを自動的に登録する場合は、次の例に示すように、META-INF/spring.factories ファイルをプロジェクトに追加し、org.springframework.context.ApplicationListener キーを使用してリスナーを参照できます。

org.springframework.context.ApplicationListener=com.example.project.MyListener

アプリケーションが実行されると、アプリケーションイベントは次の順序で送信されます。

  1. ApplicationStartingEvent は実行の開始時に送信されますが、リスナーと初期化子の登録を除き、処理の前に送信されます。

  2. ApplicationEnvironmentPreparedEvent は、コンテキストで使用される Environment がわかっているが、コンテキストが作成される前に送信されます。

  3. ApplicationContextInitializedEvent は、ApplicationContext が準備され、ApplicationContextInitializers が呼び出されましたが、Bean 定義がロードされる前に送信されます。

  4. ApplicationPreparedEvent は、リフレッシュが開始される直前、ただし Bean 定義がロードされた後に送信されます。

  5. ApplicationStartedEvent は、コンテキストがリフレッシュされた後、アプリケーションとコマンドラインランナーが呼び出される前に送信されます。

  6. LivenessState.CORRECT の直後に AvailabilityChangeEvent が送信され、アプリケーションがライブと見なされることが示されます。

  7. ApplicationReadyEvent は、アプリケーションとコマンドラインランナーが呼び出された後に送信されます。

  8. AvailabilityChangeEvent は ReadinessState.ACCEPTING_TRAFFIC の直後に送信され、アプリケーションがリクエストを処理する準備ができていることを示します。

  9. 起動時に例外がある場合、ApplicationFailedEvent が送信されます。

上記のリストには、SpringApplication に関連付けられている SpringApplicationEvent のみが含まれています。これらに加えて、次のイベントも ApplicationPreparedEvent の後、ApplicationStartedEvent の前に公開されます。

  • WebServer の準備が整うと、WebServerInitializedEvent が送信されます。ServletWebServerInitializedEvent と ReactiveWebServerInitializedEvent は、それぞれサーブレットとリアクティブバリアントです。

  • ApplicationContext がリフレッシュされると、ContextRefreshedEvent が送信されます。

多くの場合、アプリケーションイベントを使用する必要はありませんが、それらが存在することを知っておくと便利です。内部的に、Spring Boot はイベントを使用してさまざまなタスクを処理します。
イベントリスナーは、デフォルトでは同じスレッドで実行されるため、長時間かかる可能性のあるタスクを実行しないでください。代わりに、アプリケーションランナーとコマンドラインランナーの使用を検討してください。

アプリケーションイベントは、Spring Framework のイベント発行メカニズムを使用して送信されます。このメカニズムの一部により、子コンテキストでリスナーに発行されたイベントは、すべての祖先コンテキストでリスナーにも発行されます。この結果、アプリケーションが SpringApplication インスタンスの階層を使用している場合、リスナーは同じタイプのアプリケーションイベントの複数のインスタンスを受け取る場合があります。

リスナーがそのコンテキストのイベントと子孫コンテキストのイベントを区別できるようにするには、アプリケーションコンテキストの注入をリクエストし、注入されたコンテキストをイベントのコンテキストと比較する必要があります。コンテキストは、ApplicationContextAware を実装するか、リスナーが Bean の場合は @Autowired を使用して注入できます。

1.8. Web 環境

SpringApplication が適切なタイプの ApplicationContext を作成しようとします。WebApplicationType を決定するために使用されるアルゴリズムは次のとおりです。

  • Spring MVC が存在する場合、AnnotationConfigServletWebServerApplicationContext が使用されます

  • Spring MVC が存在せず、Spring WebFlux が存在する場合、AnnotationConfigReactiveWebServerApplicationContext が使用されます

  • それ以外の場合、AnnotationConfigApplicationContext が使用されます

これは、同じアプリケーションで Spring MVC と Spring WebFlux の新しい WebClient を使用している場合、デフォルトで Spring MVC が使用されることを意味します。setWebApplicationType(WebApplicationType) を呼び出すことで簡単にオーバーライドできます。

setApplicationContextClass(…​) を呼び出すことで使用される ApplicationContext タイプを完全に制御することもできます。

JUnit テスト内で SpringApplication を使用する場合、setWebApplicationType(WebApplicationType.NONE) を呼び出すことが望ましい場合がよくあります。

1.9. アプリケーション引数へのアクセス

SpringApplication.run(…​) に渡されたアプリケーション引数にアクセスする必要がある場合は、org.springframework.boot.ApplicationArguments Bean を注入できます。ApplicationArguments インターフェースは、次の例に示すように、未加工の String[] 引数と解析された option および non-option 引数の両方へのアクセスを提供します。

import org.springframework.boot.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.stereotype.*;

@Component
public class MyBean {

    @Autowired
    public MyBean(ApplicationArguments args) {
        boolean debug = args.containsOption("debug");
        List<String> files = args.getNonOptionArgs();
        // if run with "--debug logfile.txt" debug=true, files=["logfile.txt"]
    }

}
Spring Boot は、CommandLinePropertySource を Spring Environment に登録します。これにより、@Value アノテーションを使用して、単一のアプリケーション引数を注入することもできます。

1.10. ApplicationRunner または CommandLineRunner の使用

SpringApplication の起動後に特定のコードを実行する必要がある場合は、ApplicationRunner または CommandLineRunner インターフェースを実装できます。両方のインターフェースは同じように機能し、SpringApplication.run(…​) が完了する直前に呼び出される単一の run メソッドを提供します。

この契約は、アプリケーションの起動後、トラフィックの受け入れを開始する前に実行する必要があるタスクに適しています。

CommandLineRunner インターフェースはアプリケーションの引数へのアクセスを文字列配列として提供しますが、ApplicationRunner は前述の ApplicationArguments インターフェースを使用します。次の例は、run メソッドを使用した CommandLineRunner を示しています。

import org.springframework.boot.*;
import org.springframework.stereotype.*;

@Component
public class MyBean implements CommandLineRunner {

    public void run(String... args) {
        // Do something...
    }

}

特定の順序で呼び出す必要がある複数の CommandLineRunner または ApplicationRunner Bean が定義されている場合、org.springframework.core.Ordered インターフェースをさらに実装するか、org.springframework.core.annotation.Order アノテーションを使用できます。

1.11. アプリケーション終了

各 SpringApplication はシャットダウンフックを JVM に登録して、ApplicationContext が終了時に正常に閉じるようにします。すべての標準 Spring ライフサイクルコールバック(DisposableBean インターフェースや @PreDestroy アノテーションなど)を使用できます。

さらに、Bean は、SpringApplication.exit() が呼び出されたときに特定の終了コードを返したい場合、org.springframework.boot.ExitCodeGenerator インターフェースを実装できます。次の例に示すように、この終了コードを System.exit() に渡して、ステータスコードとして返すことができます。

@SpringBootApplication
public class ExitCodeApplication {

    @Bean
    public ExitCodeGenerator exitCodeGenerator() {
        return () -> 42;
    }

    public static void main(String[] args) {
        System.exit(SpringApplication.exit(SpringApplication.run(ExitCodeApplication.class, args)));
    }

}

また、ExitCodeGenerator インターフェースは例外によって実装される場合があります。このような例外が発生すると、Spring Boot は、実装された getExitCode() メソッドによって提供される終了コードを返します。

1.12. 管理機能

spring.application.admin.enabled プロパティを指定することにより、アプリケーションの管理関連機能を有効にすることができます。これにより、プラットフォーム MBeanServerSpringApplicationAdminMXBean (GitHub) が公開されます。この機能を使用して、Spring Boot アプリケーションをリモートで管理できます。この機能は、サービスラッパーの実装にも役立ちます。

アプリケーションが実行されている HTTP ポートを知りたい場合は、local.server.port のキーを持つプロパティを取得します。

2. 外部化された構成

Spring Boot では、構成を外部化できるため、異なる環境で同じアプリケーションコードを使用できます。プロパティファイル、YAML ファイル、環境変数、およびコマンドライン引数を使用して、構成を外部化できます。プロパティ値は、@Value アノテーションを使用して Bean に直接注入したり、Spring の Environment 抽象化を通じてアクセスしたり、@ConfigurationProperties を通じて構造化オブジェクトにバインドしたりできます

Spring Boot は、値を適切にオーバーライドできるように設計された、非常に特殊な PropertySource 順序を使用します。プロパティは次の順序で考慮されます。

  1. devtools がアクティブな場合、$HOME/.config/spring-boot ディレクトリの Devtools グローバル設定プロパティ

  2. テストに関する @TestPropertySource(Javadoc) アノテーション。

  3. テストの properties 属性。@SpringBootTest(Javadoc) およびアプリケーションの特定のスライスをテストするためのテストアノテーションで利用可能。

  4. コマンドライン引数。

  5. SPRING_APPLICATION_JSON のプロパティ(環境変数またはシステムプロパティに埋め込まれたインライン JSON)。

  6. ServletConfig 初期化パラメーター。

  7. ServletContext 初期化パラメーター。

  8. java:comp/env からの JNDI 属性。

  9. Java システムプロパティ(System.getProperties())。

  10. OS 環境変数。

  11. random.* のみにプロパティを持つ RandomValuePropertySource

  12. パッケージ化された jar 以外のプロファイル固有のアプリケーションプロパティapplication-{profile}.properties および YAML バリアント)。

  13. jar(application-{profile}.properties および YAML バリアント)内にパッケージ化されたプロファイル固有のアプリケーションプロパティ

  14. パッケージ化された jar 以外のアプリケーションプロパティapplication.properties および YAML バリアント)。

  15. jar(application.properties および YAML バリアント)内にパッケージ化されたアプリケーションプロパティ

  16. @Configuration クラスの @PropertySource(Javadoc) アノテーション。このようなプロパティソースは、アプリケーションコンテキストがリフレッシュされるまで Environment に追加されないことに注意してください。これは、リフレッシュが始まる前に読み込まれる logging.* や spring.main.* などの特定のプロパティを設定するには遅すぎます。

  17. デフォルトのプロパティ(SpringApplication.setDefaultProperties の設定により指定されます)。

具体例を提供するために、次の例に示すように、name プロパティを使用する @Component を開発するとします。

import org.springframework.stereotype.*;
import org.springframework.beans.factory.annotation.*;

@Component
public class MyBean {

    @Value("${name}")
    private String name;

    // ...

}

アプリケーションのクラスパス(たとえば、jar 内)に、name の適切なデフォルトのプロパティ値を提供する application.properties ファイルを含めることができます。新しい環境で実行する場合、name をオーバーライドする jar の外部で application.properties ファイルを提供できます。1 回限りのテストでは、特定のコマンドラインスイッチ(たとえば java -jar app.jar --name="Spring")で起動できます。

Spring Boot は、構成ファイルのロード時にワイルドカードの場所もサポートします。デフォルトでは、jar の外側の config/*/ のワイルドカードの場所がサポートされています。spring.config.additional-location および spring.config.location を指定する場合、ワイルドカードの場所もサポートされます。

ワイルドカードの場所は、構成プロパティのソースが複数ある Kubernetes などの環境で特に役立ちます。例:Redis 構成と MySQL 構成がある場合は、これら 2 つの構成を別々に保ちながら、アプリがバインドできる application.properties に両方が存在する必要があります。これにより、/config/redis/application.properties や /config/mysql/application.properties などの異なる場所に 2 つの別個の application.properties ファイルがマウントされる場合があります。そのような場合、ワイルドカードの場所を config/*/ にすると、両方のファイルが処理されます。

ワイルドカードの場所には、 が 1 つだけ含まれ、ディレクトリである検索場所の場合は / で終わり、ファイルである検索場所の場合は */<filename> で終わる必要があります。ワイルドカードを使用した場所は、ファイル名の絶対パスに基づいてアルファベット順にソートされます。

SPRING_APPLICATION_JSON プロパティは、環境変数を使用してコマンドラインで指定できます。例:UN*X シェルで次の行を使用できます。

$ SPRING_APPLICATION_JSON='{"acme":{"name":"test"}}' java -jar myapp.jar

上記の例では、Spring Environment で acme.name=test になります。次の例に示すように、System プロパティで spring.application.json として JSON を提供することもできます。

$ java -Dspring.application.json='{"name":"test"}' -jar myapp.jar

次の例に示すように、コマンドライン引数を使用して JSON を提供することもできます。

$ java -jar myapp.jar --spring.application.json='{"name":"test"}'

次のように、JSON を JNDI 変数として提供することもできます: java:comp/env/spring.application.json

JSON からの null 値が結果のプロパティソースに追加されますが、PropertySourcesPropertyResolver は null プロパティを欠損値として扱います。これは、JSON が null 値を持つ低次のプロパティソースからのプロパティをオーバーライドできないことを意味します。

2.1. ランダム値の構成

RandomValuePropertySource は、ランダムな値を挿入するのに便利です(たとえば、シークレットやテストケースに)。次の例に示すように、整数、long、uuid、または文字列を生成できます。

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

random.int* 構文は OPEN value (,max) CLOSE です。OPEN,CLOSE は任意の文字で、value,max は整数です。max が指定されている場合、value が最小値で、max が最大値(排他的)です。

2.2. コマンドラインプロパティへのアクセス

デフォルトでは、SpringApplication はすべてのコマンドラインオプション引数(つまり、--server.port=9000 などの -- で始まる引数)を property に変換し、Spring Environment に追加します。前述のように、コマンドラインプロパティは常に他のプロパティソースよりも優先されます。

コマンドラインプロパティを Environment に追加したくない場合は、SpringApplication.setAddCommandLineProperties(false) を使用して無効にすることができます。

2.3. アプリケーションプロパティファイル

SpringApplication は、次の場所にある application.properties ファイルからプロパティをロードし、Spring Environment に追加します。

  1. 現在のディレクトリの /config サブディレクトリ

  2. 現在のディレクトリ

  3. クラスパス /config パッケージ

  4. クラスパスのルート

リストは優先順位に従って並べられます(リストの上位の場所で定義されたプロパティは、下位の場所で定義されたプロパティをオーバーライドします)。

「.properties」の代替として YAML('.yml' )ファイルを使用するを使用することもできます。

構成ファイル名として application.properties が気に入らない場合は、spring.config.name 環境プロパティを指定して別のファイル名に切り替えることができます。spring.config.location 環境プロパティ(ディレクトリの場所またはファイルパスのコンマ区切りリスト)を使用して、明示的な場所を参照することもできます。次の例は、異なるファイル名を指定する方法を示しています。

$ java -jar myproject.jar --spring.config.name=myproject

次の例は、2 つの場所を指定する方法を示しています。

$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
spring.config.name および spring.config.location は、どのファイルをロードする必要があるかを判断するために非常に早い段階で使用されます。これらは、環境プロパティ(通常、OS 環境変数、システムプロパティ、またはコマンドライン引数)として定義する必要があります。

spring.config.location に(ファイルではなく)ディレクトリが含まれている場合、それらは / で終わる必要があります(実行時に、プロファイル固有のファイル名を含む、ロード前に spring.config.name から生成された名前が追加されます)。spring.config.location で指定されたファイルはそのまま使用され、プロファイル固有のバリアントはサポートされず、プロファイル固有のプロパティによってオーバーライドされます。直接指定する場合も、ディレクトリに含める場合も、構成ファイルの名前にはファイル拡張子を含める必要があります。標準でサポートされている一般的な拡張機能は、.properties.yaml および .yml です。

構成の場所は逆の順序で検索されます。デフォルトでは、構成された場所は classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/ です。結果の検索順序は次のとおりです。

  1. file:./config/

  2. file:./config/*/

  3. file:./

  4. classpath:/config/

  5. classpath:/

spring.config.location を使用してカスタム構成の場所を構成すると、デフォルトの場所が置き換えられます。例: spring.config.location が値 classpath:/custom-config/,file:./custom-config/ で構成されている場合、検索順序は次のようになります。

  1. file:./custom-config/

  2. classpath:custom-config/

または、spring.config.additional-location を使用してカスタム構成の場所を構成する場合、デフォルトの場所に加えてそれらが使用されます。デフォルトの場所の前に追加の場所が検索されます。例: classpath:/custom-config/,file:./custom-config/ の追加の場所が構成されている場合、検索順序は次のようになります。

  1. file:./custom-config/

  2. classpath:custom-config/

  3. file:./config/

  4. file:./config/*/

  5. file:./

  6. classpath:/config/

  7. classpath:/

この検索順序により、ある構成ファイルでデフォルト値を指定し、別の構成ファイルでそれらの値を選択的にオーバーライドできます。デフォルトの場所の 1 つで、application.properties (または spring.config.name で選択した他のベース名)でアプリケーションのデフォルト値を提供できます。これらのデフォルト値は、カスタムロケーションのいずれかにある別のファイルで実行時にオーバーライドできます。

システムプロパティではなく環境変数を使用する場合、ほとんどのオペレーティングシステムはピリオドで区切られたキー名を許可しませんが、代わりにアンダースコアを使用できます(たとえば、spring.config.name の代わりに SPRING_CONFIG_NAME)。詳細については、環境変数からのバインドを参照してください。
アプリケーションがコンテナーで実行される場合、環境変数またはシステムプロパティの代わりに、またはそれらと同様に、JNDI プロパティ(java:comp/env 内)またはサーブレットコンテキスト初期化パラメーターを使用できます。

2.4. プロファイル固有のプロパティ

application.properties ファイルに加えて、プロファイル固有のプロパティは、命名規則 application-{profile}.properties を使用して定義することもできます。Environment には、アクティブなプロファイルが設定されていない場合に使用される一連のデフォルトプロファイル(デフォルトでは [default])があります。つまり、明示的にアクティブ化されるプロファイルがない場合、application-default.properties のプロパティがロードされます。

プロファイル固有のプロパティは、標準の application.properties と同じ場所からロードされます。プロファイル固有のファイルは、パッケージ固有の jar の内部または外部にあるかどうかにかかわらず、常に非固有のものをオーバーライドします。

複数のプロファイルが指定されている場合、後勝ち戦略が適用されます。例: spring.profiles.active プロパティで指定されたプロファイルは、SpringApplication API で構成されたプロファイルの後に追加されるため、優先されます。

spring.config.location でファイルを指定した場合、それらのファイルのプロファイル固有のバリアントは考慮されません。プロファイル固有のプロパティも使用する場合は、spring.config.location のディレクトリを使用します。

2.5. プロパティのプレースホルダー

application.properties の値は、使用時に既存の Environment でフィルターされるため、以前に定義された値(たとえば、システムプロパティから)を参照できます。

app.name=MyApp
app.description=${app.name} is a Spring Boot application
この手法を使用して、既存の Spring Boot プロパティの「短い」バリアントを作成することもできます。詳細については、howto.html使い方を参照してください。

2.6. 暗号化プロパティ

Spring Boot は、プロパティ値の暗号化の組み込みサポートを提供しませんが、Spring Environment に含まれる値を変更するために必要なフックポイントを提供します。EnvironmentPostProcessor インターフェースを使用すると、アプリケーションを開始する前に Environment を操作できます。詳細については、howto.html を参照してください。

資格情報とパスワードを安全に保存する方法を探している場合、Spring Cloud Vault (英語) プロジェクトは HashiCorp Vault (英語) に外部化された構成を保存するためのサポートを提供します。

2.7. プロパティの代わりに YAML を使用する

YAML (英語) は JSON のスーパーセットであるため、階層構成データを指定するための便利な形式です。SpringApplication クラスは、クラスパスに SnakeYAML (英語) ライブラリがある場合は常に、プロパティの代替として YAML を自動的にサポートします。

「スターター」を使用すると、spring-boot-starter によって SnakeYAML が自動的に提供されます。

2.7.1. YAML の読み込み

Spring Framework は、YAML ドキュメントのロードに使用できる 2 つの便利なクラスを提供します。YamlPropertiesFactoryBean は YAML を Properties としてロードし、YamlMapFactoryBean は YAML を Map としてロードします。

例:次の YAML ドキュメントを検討します。

environments:
    dev:
        url: https://dev.example.com
        name: Developer Setup
    prod:
        url: https://another.example.com
        name: My Cool App

前述の例は、次のプロパティに変換されます。

environments.dev.url=https://dev.example.com
environments.dev.name=Developer Setup
environments.prod.url=https://another.example.com
environments.prod.name=My Cool App

YAML リストは、[index] 間接参照を持つプロパティキーとして表されます。例:次の YAML を検討します。

my:
   servers:
       - dev.example.com
       - another.example.com

前述の例は、次のプロパティに変換されます。

my.servers[0]=dev.example.com
my.servers[1]=another.example.com

Spring Boot の Binder ユーティリティ(@ConfigurationProperties の機能)を使用してそのようなプロパティにバインドするには、タイプ java.util.List (または Set)のターゲット Bean にプロパティが必要であり、setter を提供するか、可変で初期化する必要があります。値。例:次の例は、前に示したプロパティにバインドします。

@ConfigurationProperties(prefix="my")
public class Config {

    private List<String> servers = new ArrayList<String>();

    public List<String> getServers() {
        return this.servers;
    }
}

2.7.2. Spring 環境でプロパティとして YAML を公開する

YamlPropertySourceLoader クラスを使用して、YAML を Spring Environment の PropertySource として公開できます。これにより、@Value アノテーションをプレースホルダー構文とともに使用して、YAML プロパティにアクセスできます。

2.7.3. マルチプロファイル YAML ドキュメント

次の例に示すように、spring.profiles キーを使用してドキュメントが適用されるタイミングを示すことにより、単一のファイルに複数のプロファイル固有の YAML ドキュメントを指定できます。

server:
    address: 192.168.1.100
---
spring:
    profiles: development
server:
    address: 127.0.0.1
---
spring:
    profiles: production & eu-central
server:
    address: 192.168.1.120

上記の例では、development プロファイルがアクティブな場合、server.address プロパティは 127.0.0.1 です。同様に、production および eu-central プロファイルがアクティブな場合、server.address プロパティは 192.168.1.120 です。developmentproduction および eu-central プロファイルが有効になっていない場合、プロパティの値は 192.168.1.100 です。

spring.profiles には、プロファイル名(production など)またはプロファイル式を含めることができます。プロファイル式を使用すると、production & (eu-central | eu-west) などのより複雑なプロファイルロジックを表現できます。詳細については、リファレンスガイドを確認してください。

アプリケーションコンテキストの起動時に明示的にアクティブなものがない場合、デフォルトのプロファイルがアクティブになります。そのため、次の YAML では、"default" プロファイルでのみ使用可能な spring.security.user.password の値を設定します。

server:
  port: 8000
---
spring:
  profiles: default
  security:
    user:
      password: weak

一方、次の例では、パスワードはプロファイルに関連付けられていないため常に設定されており、必要に応じて他のすべてのプロファイルで明示的にリセットする必要があります。

server:
  port: 8000
spring:
  security:
    user:
      password: weak

spring.profiles 要素を使用して指定された Spring プロファイルは、! 文字を使用してオプションで無効にすることができます。単一のドキュメントに対して否定プロファイルと非否定プロファイルの両方が指定されている場合、少なくとも 1 つの非否定プロファイルが一致する必要があり、否定プロファイルは一致しません。

2.7.4. YAML の欠点

YAML ファイルは、@PropertySource アノテーションを使用してロードできません。そのため、そのように値をロードする必要がある場合は、プロパティファイルを使用する必要があります。

プロファイル固有の YAML ファイルでマルチ YAML ドキュメント構文を使用すると、予期しない動作が発生する可能性があります。例:ファイル内の次の構成を検討します。

application-dev.yml
server:
  port: 8000
---
spring:
  profiles: "!test"
  security:
    user:
      password: "secret"

引数 --spring.profiles.active=dev を指定してアプリケーションを実行すると、security.user.password が「secret」に設定されると予想される場合がありますが、そうではありません。

メインファイルの名前は application-dev.yml であるため、ネストされたドキュメントはフィルターされます。すでにプロファイル固有であると見なされており、ネストされたドキュメントは無視されます。

プロファイル固有の YAML ファイルと複数の YAML ドキュメントを混在させないことをお勧めします。それらの 1 つだけを使用することに固執します。

2.8. タイプセーフな構成プロパティ

@Value("${property}") アノテーションを使用して構成プロパティを注入することは、特に複数のプロパティを使用している場合、またはデータが本質的に階層的である場合には、面倒な場合があります。Spring Boot は、強く型付けされた Bean がアプリケーションの構成を管理および検証できるようにするプロパティを操作する代替方法を提供します。

2.8.1. JavaBean プロパティバインディング

次の例に示すように、標準 JavaBean プロパティを宣言する Bean をバインドすることができます。

package com.example;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("acme")
public class AcmeProperties {

    private boolean enabled;

    private InetAddress remoteAddress;

    private final Security security = new Security();

    public boolean isEnabled() { ... }

    public void setEnabled(boolean enabled) { ... }

    public InetAddress getRemoteAddress() { ... }

    public void setRemoteAddress(InetAddress remoteAddress) { ... }

    public Security getSecurity() { ... }

    public static class Security {

        private String username;

        private String password;

        private List<String> roles = new ArrayList<>(Collections.singleton("USER"));

        public String getUsername() { ... }

        public void setUsername(String username) { ... }

        public String getPassword() { ... }

        public void setPassword(String password) { ... }

        public List<String> getRoles() { ... }

        public void setRoles(List<String> roles) { ... }

    }
}

前述の POJO は、次のプロパティを定義します。

  • acme.enabled、デフォルトでは false の値。

  • String から強制変換できるタイプの acme.remote-address

  • acme.security.username、プロパティの名前によって名前が決定されるネストされた「セキュリティ」オブジェクト。特に、戻り値の型はそこではまったく使用されておらず、SecurityProperties である可能性があります。

  • acme.security.password.

  • acme.security.roles。デフォルトは USER である String のコレクションです。

Spring Boot で利用可能な @ConfigurationProperties クラスにマッピングされるプロパティは、プロパティファイル、YAML ファイル、環境変数などを介して設定されますが、パブリック API ですが、クラス自体のアクセサー(getter/setter)は直接使用するためのものではありません。

そのような配置はデフォルトの空のコンストラクターに依存し、getter および setter は、Spring MVC のように標準の Java Bean プロパティ記述子を介して行われるため、通常必須です。setter は、次の場合に省略できます。

  • マップは、初期化されている限り、getter を必要としますが、必ずしも setter を必要とするわけではありません。バインダーによって変更できるためです。

  • コレクションと配列には、インデックス(通常は YAML を使用)または単一のコンマ区切り値(プロパティ)を使用してアクセスできます。後者の場合、setter は必須です。そのようなタイプには、常に setter を追加することをお勧めします。コレクションを初期化する場合は、不変でないことを確認してください(前の例のように)。

  • ネストされた POJO プロパティが初期化される場合(前述の例の Security フィールドのように)、setter は必要ありません。デフォルトのコンストラクターを使用して、バインダーがその場でインスタンスを作成するようにするには、setter が必要です。

プロジェクト Lombok を使用して、getter と setter を自動的に追加する人もいます。Lombok はオブジェクトをインスタンス化するためにコンテナーによって自動的に使用されるため、そのような型の特定のコンストラクターを生成しないように注意してください。

最後に、標準の Java Bean プロパティのみが考慮され、静的プロパティのバインドはサポートされていません。

2.8.2. コンストラクターバインディング

前のセクションの例は、次の例に示すように不変の方法で書き換えることができます。

package com.example;

import java.net.InetAddress;
import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import org.springframework.boot.context.properties.bind.DefaultValue;

@ConstructorBinding
@ConfigurationProperties("acme")
public class AcmeProperties {

    private final boolean enabled;

    private final InetAddress remoteAddress;

    private final Security security;

    public AcmeProperties(boolean enabled, InetAddress remoteAddress, Security security) {
        this.enabled = enabled;
        this.remoteAddress = remoteAddress;
        this.security = security;
    }

    public boolean isEnabled() { ... }

    public InetAddress getRemoteAddress() { ... }

    public Security getSecurity() { ... }

    public static class Security {

        private final String username;

        private final String password;

        private final List<String> roles;

        public Security(String username, String password,
                @DefaultValue("USER") List<String> roles) {
            this.username = username;
            this.password = password;
            this.roles = roles;
        }

        public String getUsername() { ... }

        public String getPassword() { ... }

        public List<String> getRoles() { ... }

    }

}

このセットアップでは、@ConstructorBinding アノテーションを使用して、コンストラクターバインディングを使用する必要があることを示します。これは、バインダーがバインドしたいパラメーターを持つコンストラクターを見つけることを期待することを意味します。

@ConstructorBinding クラスのネストされたメンバー(上記の例の Security など)も、コンストラクターを介してバインドされます。

デフォルト値は @DefaultValue を使用して指定でき、同じ変換サービスが適用されて、String 値を欠落しているプロパティのターゲットタイプに強制変換します。デフォルトでは、Security にバインドされているプロパティがない場合、AcmeProperties インスタンスには security の null 値が含まれます。プロパティがバインドされていない場合でも、Security の null 以外のインスタンスを返す場合は、空の @DefaultValue アノテーションを使用してこれを行うことができます。

package com.example;
import java.net.InetAddress;
import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import org.springframework.boot.context.properties.bind.DefaultValue;

@ConstructorBinding
@ConfigurationProperties("acme")
public class AcmeProperties {

    private final boolean enabled;

    private final InetAddress remoteAddress;

    private final Security security;

    public AcmeProperties(boolean enabled, InetAddress remoteAddress, @DefaultValue Security security) {
        this.enabled = enabled;
        this.remoteAddress = remoteAddress;
        this.security = security;
    }
}
コンストラクターバインディングを使用するには、@EnableConfigurationProperties または構成プロパティスキャンを使用してクラスを有効にする必要があります。通常の Spring メカニズムによって作成された Bean でコンストラクターバインディングを使用することはできません。(たとえば @Component Bean、@Bean メソッドを介して作成された Bean、または @Import を使用してロードされた Bean )
クラスに複数のコンストラクターがある場合は、バインドする必要があるコンストラクターで @ConstructorBinding を直接使用することもできます。
java.util.Optional と @ConfigurationProperties の併用は、主に戻り値の型としての使用を目的としているためお勧めしません。そのため、構成プロパティの注入には適していません。他のタイプのプロパティとの一貫性を保つために、Optional プロパティを宣言し、それに値がない場合、空の Optional ではなく null がバインドされます。

2.8.3. @ConfigurationPropertiesannotated タイプを有効にする

Spring Boot は、@ConfigurationProperties タイプをバインドし、Bean として登録するためのインフラストラクチャを提供します。クラスごとに構成プロパティを有効にするか、コンポーネントスキャンと同様に機能する構成プロパティスキャンを有効にすることができます。

@ConfigurationProperties アノテーションが付けられたクラスは、たとえば、独自の自動構成を開発している場合や、条件付きで有効にしたい場合など、スキャンに適さない場合があります。これらの場合、@EnableConfigurationProperties アノテーションを使用して処理するタイプのリストを指定します。これは、次の例に示すように、@Configuration クラスで実行できます。

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(AcmeProperties.class)
public class MyConfiguration {
}

構成プロパティのスキャンを使用するには、@ConfigurationPropertiesScan アノテーションをアプリケーションに追加します。通常、@SpringBootApplication アノテーションが付けられたメインアプリケーションクラスに追加されますが、任意の @Configuration クラスに追加できます。デフォルトでは、アノテーションを宣言するクラスのパッケージからスキャンが行われます。スキャンする特定のパッケージを定義する場合は、次の例に示すように定義できます。

@SpringBootApplication
@ConfigurationPropertiesScan({ "com.example.app", "org.acme.another" })
public class MyApplication {
}

@ConfigurationProperties Bean が構成プロパティのスキャンまたは @EnableConfigurationProperties を使用して登録されている場合、Bean には従来の名前 <prefix>-<fqn> があります。<prefix> は @ConfigurationProperties アノテーションで指定された環境キーのプレフィックスで、<fqn> は Bean の完全修飾名です。アノテーションが接頭部を提供しない場合、Bean の完全修飾名のみが使用されます。

上記の例の Bean 名は acme-com.example.AcmeProperties です。

@ConfigurationProperties は環境のみを扱い、特にコンテキストから他の Bean を注入しないことをお勧めします。コーナーケースの場合、setter インジェクションを使用するか、フレームワークによって提供される *Aware インターフェースのいずれか(Environment へのアクセスが必要な場合は EnvironmentAware など)を使用できます。それでもコンストラクターを使用して他の Bean を注入する場合は、構成プロパティ Bean に @Component のアノテーションを付け、JavaBean ベースのプロパティバインディングを使用する必要があります。

2.8.4. @ConfigurationPropertiesannotated タイプの使用

このスタイルの構成は、次の例に示すように、SpringApplication 外部 YAML 構成で特にうまく機能します。

# application.yml

acme:
    remote-address: 192.168.1.1
    security:
        username: admin
        roles:
          - USER
          - ADMIN

# additional configuration as required

@ConfigurationProperties Bean を使用するには、次の例に示すように、他の Bean と同じ方法で注入できます。

@Service
public class MyService {

    private final AcmeProperties properties;

    @Autowired
    public MyService(AcmeProperties properties) {
        this.properties = properties;
    }

    //...

    @PostConstruct
    public void openConnection() {
        Server server = new Server(this.properties.getRemoteAddress());
        // ...
    }

}
@ConfigurationProperties を使用すると、IDE で使用できるメタデータファイルを生成して、独自のキーの自動補完を提供することもできます。詳細については、付録を参照してください。

2.8.5. サードパーティの構成

@ConfigurationProperties を使用してクラスにアノテーションを付けるだけでなく、パブリック @Bean メソッドでも使用できます。これは、コントロール外のサードパーティコンポーネントにプロパティをバインドする場合に特に役立ちます。

Environment プロパティから Bean を構成するには、次の例に示すように、@ConfigurationProperties を Bean 登録に追加します。

@ConfigurationProperties(prefix = "another")
@Bean
public AnotherComponent anotherComponent() {
    ...
}

another プレフィックスで定義された JavaBean プロパティは、前述の AcmeProperties の例と同様の方法で、その AnotherComponent Bean にマッピングされます。

2.8.6. 緩いバインディング

Spring Boot は、Environment プロパティを @ConfigurationProperties Bean にバインドするためにいくつかの緩和されたルールを使用しているため、Environment プロパティ名と Bean プロパティ名が完全に一致する必要はありません。これが役立つ一般的な例には、ダッシュで区切られた環境プロパティ(たとえば、context-path が contextPath にバインド)、大文字の環境プロパティ(たとえば、PORT が port にバインド)があります。

例として、次の @ConfigurationProperties クラスを検討してください。

@ConfigurationProperties(prefix="acme.my-project.person")
public class OwnerProperties {

    private String firstName;

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

}

上記のコードでは、次のプロパティ名をすべて使用できます。

テーブル 2: 緩いバインディング
プロパティ メモ

acme.my-project.person.first-name

.properties および .yml ファイルでの使用が推奨されるケバブケース。

acme.myProject.person.firstName

標準のキャメルケースの構文。

acme.my_project.person.first_name

アンダースコア表記。.properties および .yml ファイルで使用するための代替形式です。

ACME_MYPROJECT_PERSON_FIRSTNAME

システム環境変数を使用する場合に推奨される大文字形式。

アノテーションの prefix 値はケバブの場合(小文字で、acme.my-project.person などの - で区切られている)でなければなりません
表 3: プロパティソースごとの緩いバインディングルール
プロパティソース シンプル リスト

プロパティファイル

キャメルケース、ケバブケース、またはアンダースコア表記

[ ] またはコンマ区切り値を使用した標準リスト構文

YAML ファイル

キャメルケース、ケバブケース、またはアンダースコア表記

標準の YAML リスト構文またはコンマ区切り値

環境変数

区切り文字としてアンダースコアを使用した大文字の形式(環境変数からのバインドを参照)。

アンダースコアで囲まれた数値(環境変数からのバインドを参照) `

システムプロパティ

キャメルケース、ケバブケース、またはアンダースコア表記

[ ] またはコンマ区切り値を使用した標準リスト構文

可能な場合、プロパティは my.property-name=acme などの小文字のケバブ形式で保存することをお勧めします。
バインディングマップ

Map プロパティにバインドするときに、key に小文字の英数字または - 以外のものが含まれている場合、元の値が保持されるように括弧表記を使用する必要があります。キーが [] で囲まれていない場合、英数字でも - でもない文字はすべて削除されます。例:次のプロパティを Map にバインドすることを検討してください。

acme:
  map:
    "[/key1]": value1
    "[/key2]": value2
    /key3: value3

上記のプロパティは、/key1/key2 と key3 をマップのキーとして Map にバインドします。

YAML ファイルの場合、キーを適切に解析するには、括弧を引用符で囲む必要があります。
環境変数からのバインド

ほとんどのオペレーティングシステムでは、環境変数に使用できる名前に関する厳格なルールが適用されます。例:Linux シェル変数には、文字(a から z または A から Z)、数字(0 から 9)または下線文字(_)のみを含めることができます。慣例により、Unix シェル変数も大文字で名前が付けられます。

Spring Boot の緩いバインディングルールは、可能な限り、これらの命名制限と互換性を持つように設計されています。

正規形式のプロパティ名を環境変数名に変換するには、次のルールに従います。

  • ドット(.)をアンダースコア(_)に置き換えます。

  • ダッシュ(-)をすべて削除します。

  • 大文字に変換します。

例:構成プロパティ spring.main.log-startup-info は SPRING_MAIN_LOGSTARTUPINFO という名前の環境変数になります。

プロパティ名のダッシュをアンダースコアで置き換えることはできません。上記の例で SPRING_MAIN_LOG_STARTUP_INFO を使用しようとすると、値はバインドされません。

環境変数は、オブジェクトリストにバインドするときにも使用できます。List にバインドするには、要素名を変数名でアンダースコアで囲む必要があります。

例:構成プロパティ my.acme[0].other は、MY_ACME_0_OTHER という名前の環境変数を使用します。

2.8.7. 複合型のマージ

リストが複数の場所で構成されている場合、オーバーライドはリスト全体を置き換えることで機能します。

例: null である name および description 属性を持つ MyPojo オブジェクトをデフォルトと想定します。次の例は、AcmeProperties から MyPojo オブジェクトのリストを公開します。

@ConfigurationProperties("acme")
public class AcmeProperties {

    private final List<MyPojo> list = new ArrayList<>();

    public List<MyPojo> getList() {
        return this.list;
    }

}

次の構成を検討してください。

acme:
  list:
    - name: my name
      description: my description
---
spring:
  profiles: dev
acme:
  list:
    - name: my another name

dev プロファイルがアクティブでない場合、AcmeProperties.list には、前に定義したように 1 つの MyPojo エントリが含まれます。ただし、dev プロファイルが有効になっている場合、list にはまだ 1 つのエントリしか含まれていません(名前が my another name で説明が null)。この構成で、2 番目の MyPojo インスタンスはリストに追加されず、アイテムはマージされません。

List が複数のプロファイルで指定されている場合、最高の優先順位を持つプロファイル(およびそのプロファイルのみ)が使用されます。次の例を考えてみましょう。

acme:
  list:
    - name: my name
      description: my description
    - name: another name
      description: another description
---
spring:
  profiles: dev
acme:
  list:
    - name: my another name

上記の例で、dev プロファイルがアクティブである場合、AcmeProperties.list には 1 つの MyPojo エントリ(名前 my another name および説明 null)が含まれます。YAML の場合、コンマ区切りリストと YAML リストの両方を使用して、リストの内容を完全にオーバーライドできます。

Map プロパティの場合、複数のソースから取得したプロパティ値とバインドできます。ただし、複数のソースの同じプロパティの場合、優先度が最も高いプロパティが使用されます。次の例は、AcmeProperties から Map<String, MyPojo> を公開します。

@ConfigurationProperties("acme")
public class AcmeProperties {

    private final Map<String, MyPojo> map = new HashMap<>();

    public Map<String, MyPojo> getMap() {
        return this.map;
    }

}

次の構成を検討してください。

acme:
  map:
    key1:
      name: my name 1
      description: my description 1
---
spring:
  profiles: dev
acme:
  map:
    key1:
      name: dev name 1
    key2:
      name: dev name 2
      description: dev description 2

dev プロファイルがアクティブでない場合、AcmeProperties.map にはキー key1 (名前 my name 1 および説明 my description 1)を持つ 1 つのエントリが含まれます。ただし、dev プロファイルが有効になっている場合、map には、キー key1 (名前 dev name 1 および説明 my description 1)および key2 (名前 dev name 2 および説明 dev description 2)の 2 つのエントリが含まれます。

前述のマージルールは、YAML ファイルだけでなく、すべてのプロパティソースのプロパティに適用されます。

2.8.8. プロパティの変換

Spring Boot は、@ConfigurationProperties Bean にバインドするときに、外部アプリケーションプロパティを正しいタイプに強制しようとします。カスタムタイプの変換が必要な場合は、ConversionService Bean(conversionService という名前の Bean を使用)またはカスタムプロパティエディター(CustomEditorConfigurer Bean を使用)またはカスタム Converters (@ConfigurationPropertiesBinding としてアノテーション付けされた Bean 定義を使用)を提供できます。

この Bean はアプリケーションライフサイクルの非常に早い段階でリクエストされるため、ConversionService が使用している依存関係を必ず制限してください。通常、必要な依存関係は作成時に完全に初期化されない場合があります。構成キーの強制に不要なカスタム ConversionService の名前を変更し、@ConfigurationPropertiesBinding で修飾されたカスタムコンバーターのみに依存することができます。
期間の変換

Spring Boot は、期間を表現するための専用サポートを備えています。java.time.Duration プロパティを公開する場合、アプリケーションプロパティで次の形式を使用できます。

  • 通常の long 表現 ( @DurationUnit が指定されていない限り、デフォルトの単位としてミリ秒を使用する)

  • java.time.Duration が使用する 標準 ISO-8601 形式

  • 値と単位が結合された、より読みやすい形式 (たとえば 10s は 10 秒を意味する)

次の例を考えてみましょう。

@ConfigurationProperties("app.system")
public class AppSystemProperties {

    @DurationUnit(ChronoUnit.SECONDS)
    private Duration sessionTimeout = Duration.ofSeconds(30);

    private Duration readTimeout = Duration.ofMillis(1000);

    public Duration getSessionTimeout() {
        return this.sessionTimeout;
    }

    public void setSessionTimeout(Duration sessionTimeout) {
        this.sessionTimeout = sessionTimeout;
    }

    public Duration getReadTimeout() {
        return this.readTimeout;
    }

    public void setReadTimeout(Duration readTimeout) {
        this.readTimeout = readTimeout;
    }

}

30 秒のセッションタイムアウトを指定するには、30PT30S と 30s はすべて同等です。500 ミリ秒の読み取りタイムアウトは、500PT0.5S および 500ms のいずれかの形式で指定できます。

サポートされている任意のユニットを使用することもできます。これらは:

  • ns ナノ秒

  • us マイクロ秒

  • ms ミリ秒

  • s 秒

  • m 分

  • h 時間

  • d 日

デフォルトの単位はミリ秒であり、上記のサンプルに示すように、@DurationUnit を使用してオーバーライドできます。@DurationUnit は、getter および setter を使用する JavaBean スタイルのプロパティバインディングでのみサポートされていることに注意してください。コンストラクターバインディングではサポートされていません。

Long プロパティをアップグレードする場合、単位がミリ秒でない場合は、必ず(@DurationUnit を使用して)単位を定義してください。そうすることで、はるかに豊富な形式をサポートしながら、透過的なアップグレードパスが得られます。
期間の変換

期間に加えて、Spring Boot は java.time.Period タイプでも機能します。アプリケーションのプロパティでは、次の形式を使用できます。

  • 通常の int 表現 ( @PeriodUnit が指定されていない限り、デフォルトの単位として日を使用する)

  • java.time.Period が使用する 標準 ISO-8601 形式

  • 値と単位のペアが結合されたより簡単な形式 (たとえば 1y3d は 1 年と 3 日を意味する)

次の単位は、単純な形式でサポートされています。

  • y 年

  • m 月

  • w 週

  • d 日

java.time.Period タイプは実際には週数を格納しません。これは「7 日」を意味するショートカットです。
データサイズの変換

Spring Framework には、サイズをバイト単位で表す DataSize 値タイプがあります。DataSize プロパティを公開する場合、アプリケーションプロパティで次の形式を使用できます。

  • 通常の long 表現 ( @DataSizeUnit が指定されていない限り、デフォルトの単位としてバイトを使用)

  • 値と単位が結合された、より読みやすい形式 (たとえば 10MB は 10 メガバイトを意味する)

次の例を考えてみましょう。

@ConfigurationProperties("app.io")
public class AppIoProperties {

    @DataSizeUnit(DataUnit.MEGABYTES)
    private DataSize bufferSize = DataSize.ofMegabytes(2);

    private DataSize sizeThreshold = DataSize.ofBytes(512);

    public DataSize getBufferSize() {
        return this.bufferSize;
    }

    public void setBufferSize(DataSize bufferSize) {
        this.bufferSize = bufferSize;
    }

    public DataSize getSizeThreshold() {
        return this.sizeThreshold;
    }

    public void setSizeThreshold(DataSize sizeThreshold) {
        this.sizeThreshold = sizeThreshold;
    }

}

10 メガバイトのバッファーサイズを指定するには、10 と 10MB は同等です。256 バイトのサイズしきい値は、256 または 256B として指定できます。

サポートされている任意のユニットを使用することもできます。これらは:

  • B バイト

  • KB キロバイト

  • MB メガバイト

  • GB ギガバイト

  • TB テラバイト

デフォルトの単位はバイトであり、上記のサンプルに示すように @DataSizeUnit を使用してオーバーライドできます。

Long プロパティをアップグレードする場合、単位がバイトでない場合は必ず(@DataSizeUnit を使用して)単位を定義してください。そうすることで、はるかに豊富な形式をサポートしながら、透過的なアップグレードパスが得られます。

2.8.9. @ConfigurationProperties 検証

Spring Boot は、Spring の @Validated アノテーションが付けられている場合、@ConfigurationProperties クラスを検証しようとします。JSR-303 javax.validation 制約アノテーションを構成クラスで直接使用できます。これを行うには、次の例に示すように、準拠する JSR-303 実装がクラスパス上にあることを確認してから、フィールドに制約アノテーションを追加します。

@ConfigurationProperties(prefix="acme")
@Validated
public class AcmeProperties {

    @NotNull
    private InetAddress remoteAddress;

    // ... getters and setters

}
@Validated を使用して構成プロパティを作成する @Bean メソッドにアノテーションを付けることにより、検証をトリガーすることもできます。

ネストされたプロパティに対して検証が常にトリガーされるようにするには、プロパティが見つからない場合でも、関連付けられたフィールドに @Valid のアノテーションを付ける必要があります。次の例は、前述の AcmeProperties の例に基づいています。

@ConfigurationProperties(prefix="acme")
@Validated
public class AcmeProperties {

    @NotNull
    private InetAddress remoteAddress;

    @Valid
    private final Security security = new Security();

    // ... getters and setters

    public static class Security {

        @NotEmpty
        public String username;

        // ... getters and setters

    }

}

configurationPropertiesValidator という Bean 定義を作成して、カスタム Spring Validator を追加することもできます。@Bean メソッドは static として宣言する必要があります。構成プロパティバリデーターは、アプリケーションのライフサイクルの非常に早い段階で作成され、@Bean メソッドを静的として宣言すると、@Configuration クラスをインスタンス化せずに Bean を作成できます。そうすることで、早期のインスタンス化によって引き起こされる可能性のある問題を回避できます。

spring-boot-actuator モジュールには、すべての @ConfigurationProperties Bean を公開するエンドポイントが含まれています。Web ブラウザーで /actuator/configprops を指すか、同等の JMX エンドポイントを使用します。詳細については、「本番対応機能」セクションを参照してください。

2.8.10. @ConfigurationProperties 対 @Value

@Value アノテーションはコアコンテナー機能であり、タイプセーフな構成プロパティと同じ機能を提供しません。次の表は、@ConfigurationProperties および @Value でサポートされている機能をまとめたものです。

フィーチャー @ConfigurationProperties@Value

緩いバインディング

はい

限定的 (以下の注を参照してください)

メタデータのサポート

はい

いいえ

SpEL 評価

いいえ

はい

独自のコンポーネントの構成キーのセットを定義する場合は、@ConfigurationProperties でアノテーションされた POJO にグループ化することをお勧めします。これにより、独自の Bean に注入できる構造化されたタイプセーフなオブジェクトが提供されます。

@Value を使用する場合は、正規名を使用してプロパティ名を参照することをお勧めします(小文字のみを使用したケバブケース)。これにより、Spring Boot は、@ConfigurationProperties をリラックスバインドする場合と同じロジックを使用できます。例: @Value("{demo.item-price}") は、application.properties ファイルから demo.item-price および demo.itemPrice フォームをピックアップし、システム環境から DEMO_ITEMPRICE をピックアップします。代わりに @Value("{demo.itemPrice}") を使用した場合、demo.item-price および DEMO_ITEMPRICE は考慮されません。

最後に、@Value で SpEL 式を記述できますが、そのような式はアプリケーションプロパティファイルから処理されません。

3. プロファイル

Spring プロファイルは、アプリケーション構成の一部を分離し、特定の環境でのみ使用可能にする方法を提供します。次の例に示すように、@Component@Configuration、または @ConfigurationProperties を @Profile でマークして、ロード時を制限できます。

@Configuration(proxyBeanMethods = false)
@Profile("production")
public class ProductionConfiguration {

    // ...

}
@ConfigurationProperties Bean が自動スキャンの代わりに @EnableConfigurationProperties を介して登録されている場合、@EnableConfigurationProperties アノテーションを持つ @Configuration クラスで @Profile アノテーションを指定する必要があります。@ConfigurationProperties がスキャンされる場合、@ConfigurationProperties クラス自体で @Profile を指定できます。

spring.profiles.activeEnvironment プロパティを使用して、アクティブなプロファイルを指定できます。この章で前述した任意の方法でプロパティを指定できます。例:次の例に示すように、application.properties に含めることができます。

spring.profiles.active=dev,hsqldb

次のスイッチ --spring.profiles.active=dev,hsqldb を使用して、コマンドラインで指定することもできます。

3.1. アクティブプロファイルの追加

spring.profiles.active プロパティは、他のプロパティと同じ順序付けルールに従います:最高の PropertySource が勝ちます。つまり、application.properties でアクティブなプロファイルを指定し、コマンドラインスイッチを使用して置き換えることができます。

アクティブなプロファイルを置き換えるのではなく、アクティブなプロファイルに追加するプロファイル固有のプロパティがあると便利な場合があります。spring.profiles.include プロパティを使用して、アクティブなプロファイルを無条件に追加できます。SpringApplication エントリポイントには、追加のプロファイルを設定するための Java API もあります(つまり、spring.profiles.active プロパティによってアクティブ化されたプロファイルの上にあります)。SpringApplication(Javadoc) の setAdditionalProfiles() メソッドを参照してください。

例:スイッチ --spring.profiles.active=prod を使用して次のプロパティを持つアプリケーションを実行すると、proddb および prodmq プロファイルもアクティブになります。

---
my.property: fromyamlfile
---
spring.profiles: prod
spring.profiles.include:
  - proddb
  - prodmq
spring.profiles プロパティを YAML ドキュメントで定義して、この特定のドキュメントがいつ構成に含まれるかを決定できることに注意してください。詳細については、howto.html を参照してください。

3.2. プログラムでプロファイルを設定する

アプリケーションを実行する前に SpringApplication.setAdditionalProfiles(…​) を呼び出すことにより、アクティブなプロファイルをプログラムで設定できます。Spring の ConfigurableEnvironment インターフェースを使用してプロファイルをアクティブにすることもできます。

3.3. プロファイル固有の構成ファイル

application.properties (または application.yml)と @ConfigurationProperties を介して参照されるファイルの両方のプロファイル固有のバリアントは、ファイルと見なされ、ロードされます。詳細については、「プロファイル固有のプロパティ」を参照してください。

4. ロギング

Spring Boot は、すべての内部ロギングに Commons Logging (Apache) を使用しますが、基礎となるログ実装はオープンなままです。Java Util ロギング Log4J2 (Apache) 、および Logback (英語) のデフォルト構成が提供されています。いずれの場合も、ロガーはコンソール出力を使用するように事前設定されており、オプションのファイル出力も利用できます。

デフォルトでは、「スターター」を使用する場合、Logback がロギングに使用されます。Java Util Logging、Commons Logging、Log4J、または SLF4J を使用する依存ライブラリがすべて正常に機能するように、適切な Logback ルーティングも含まれています。

Java には多くのロギングフレームワークがあります。上記のリストがわかりにくい場合でも心配しないでください。通常、ロギングの依存関係を変更する必要はなく、Spring Boot のデフォルトは問題なく機能します。
アプリケーションをサーブレットコンテナーまたはアプリケーションサーバーにデプロイする場合、Java Util Logging API を介して実行されたログは、アプリケーションのログにルーティングされません。これにより、コンテナーまたはコンテナーにデプロイされた他のアプリケーションによって実行されたロギングが、アプリケーションのログに表示されなくなります。

4.1. ログ形式

Spring Boot からのデフォルトのログ出力は、次の例のようになります。

2019-03-05 10:57:51.112  INFO 45469 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.52
2019-03-05 10:57:51.253  INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-03-05 10:57:51.253  INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1358 ms
2019-03-05 10:57:51.698  INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2019-03-05 10:57:51.702  INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]

次の項目が出力されます。

  • 日時 : ミリ秒の精度と簡単にソート可能。

  • ログレベル : ERRORWARNINFODEBUG または TRACE

  • プロセス ID。

  • 実際のログメッセージの開始を区別する --- セパレータ。

  • スレッド名 : 角括弧で囲まれています(コンソール出力では切り捨てられる場合があります)。

  • ロガー名 : これは通常、ソースクラス名です(多くの場合省略されます)。

  • ログメッセージ。

Logback には FATAL レベルはありません。ERROR にマップされます。

4.2. コンソール出力

デフォルトのログ構成では、メッセージが書き込まれるとコンソールにエコーされます。デフォルトでは、ERROR -level、WARN -level、および INFO -level メッセージがログに記録されます。--debug フラグを使用してアプリケーションを起動することにより、「デバッグ」モードを有効にすることもできます。

$ java -jar myapp.jar --debug
application.properties で debug=true を指定することもできます。

デバッグモードを有効にすると、コアロガー(埋め込みコンテナー、Hibernate、および Spring Boot)の選択がより多くの情報を出力するように構成されます。デバッグモードを有効にしても、DEBUG レベルのすべてのメッセージをログに記録するようにアプリケーションが設定されるわけではありませ

または、--trace フラグ(または application.properties の trace=true)を使用してアプリケーションを開始することにより、「トレース」モードを有効にすることができます。これにより、選択されたコアロガー(埋め込みコンテナー、Hibernate スキーマ生成、および Spring ポートフォリオ全体)のトレースログが有効になります。

4.2.1. 色分けされた出力

ターミナルが ANSI をサポートしている場合、読みやすくするためにカラー出力が使用されます。spring.output.ansi.enabled をサポートされている値(Javadoc) に設定して、自動検出をオーバーライドできます。

カラーコーディングは、%clr 変換ワードを使用して構成されます。最も単純な形式では、次の例に示すように、コンバーターはログレベルに従って出力に色を付けます。

%clr(%5p)

次の表に、ログレベルと色のマッピングを示します。

レベル

FATAL

ERROR

WARN

INFO

DEBUG

TRACE

または、変換のオプションとして使用することにより、使用する色またはスタイルを指定できます。例:テキストを黄色にするには、次の設定を使用します。

%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow}

次の色とスタイルがサポートされています。

  • blue

  • cyan

  • faint

  • green

  • magenta

  • red

  • yellow

4.3. ファイル出力

デフォルトでは、Spring Boot はコンソールにのみログを記録し、ログファイルを書き込みません。コンソール出力に加えてログファイルを書き込む場合は、logging.file.name または logging.file.path プロパティを設定する必要があります(たとえば、application.properties で)。

次の表は、logging.* プロパティを一緒に使用する方法を示しています。

表 4: ロギングプロパティ
logging.file.namelogging.file.path サンプル 説明

(なし)

(なし)

コンソールのみのロギング。

特定のファイル

(なし)

my.log

指定されたログファイルに書き込みます。名前は、正確な場所でも、現在のディレクトリからの相対名でもかまいません。

(なし)

特定のディレクトリ

/var/log

指定されたディレクトリに spring.log を書き込みます。名前は、正確な場所でも、現在のディレクトリからの相対名でもかまいません。

ログファイルは 10 MB に達するとローテーションし、コンソール出力と同様に、ERROR -level、WARN -level、および INFO -level メッセージがデフォルトでログに記録されます。サイズの制限は、logging.file.max-size プロパティを使用して変更できます。logging.file.max-history プロパティが設定されていない限り、過去 7 日間のローテーションされたログファイルはデフォルトで保持されます。ログアーカイブの合計サイズは、logging.file.total-size-cap を使用して上限を設定できます。ログアーカイブの合計サイズがそのしきい値を超えると、バックアップが削除されます。アプリケーションの起動時にログアーカイブのクリーンアップを強制するには、logging.file.clean-history-on-start プロパティを使用します。

ロギングプロパティは、実際のロギングインフラストラクチャから独立しています。その結果、特定の構成キー(Logback の logback.configurationFile など)は spring Boot によって管理されません。

4.4. ログレベル

サポートされているすべてのロギングシステムでは、level が TRACE、DEBUG、INFO、WARN、ERROR、FATAL、または OFF のいずれかである logging.level.<logger-name>=<level> を使用して、Spring Environment (たとえば application.properties)にロガーレベルを設定できます。root ロガーは、logging.level.root を使用して構成できます。

次の例は、application.properties の潜在的なロギング設定を示しています。

logging.level.root=warn
logging.level.org.springframework.web=debug
logging.level.org.hibernate=error

環境変数を使用してログレベルを設定することもできます。例: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB=DEBUG は org.springframework.web を DEBUG に設定します。

上記のアプローチは、パッケージレベルのログに対してのみ機能します。緩いバインディングは常に環境変数を小文字に変換するため、この方法で個々のクラスのロギングを構成することはできません。クラスのロギングを構成する必要がある場合は、SPRING_APPLICATION_JSON 変数を使用できます。

4.5. ロググループ

関連するロガーをグループ化して、すべてを同時に構成できると便利な場合がよくあります。例:Tomcat 関連のすべてのロガーのログレベルを一般的に変更することはできますが、トップレベルのパッケージを簡単に思い出すことはできません。

これを支援するために、Spring Boot では、Spring Environment でロギンググループを定義できます。例: application.properties に追加して「tomcat」グループを定義する方法は次のとおりです。

logging.group.tomcat=org.apache.catalina, org.apache.coyote, org.apache.tomcat

定義したら、グループ内のすべてのロガーのレベルを 1 行で変更できます。

logging.level.tomcat=TRACE

Spring Boot には、すぐに使用できる次の事前定義されたロギンググループが含まれています。

名前 ロガー

Web

org.springframework.core.codecorg.springframework.httporg.springframework.weborg.springframework.boot.actuate.endpoint.weborg.springframework.boot.web.servlet.ServletContextInitializerBeans

sql

org.springframework.jdbc.coreorg.hibernate.SQLorg.jooq.tools.LoggerListener

4.6. カスタムログ設定

さまざまなロギングシステムは、クラスパスに適切なライブラリを含めることでアクティブにでき、クラスパスのルートまたは次の Spring Environment プロパティで指定された場所に適切な構成ファイルを提供することでさらにカスタマイズできます: logging.config

org.springframework.boot.logging.LoggingSystem システムプロパティを使用して、Spring Boot に特定のログシステムを強制的に使用させることができます。値は、LoggingSystem 実装の完全修飾クラス名でなければなりません。none の値を使用して、Spring Boot のログ設定を完全に無効にすることもできます。

ApplicationContext が作成される前にロギングが初期化されるため、Spring @Configuration ファイルの @PropertySources からロギングを制御することはできません。ロギングシステムを変更または完全に無効にする唯一の方法は、システムプロパティを使用することです。

ロギングシステムに応じて、次のファイルがロードされます。

ロギングシステム カスタム

Logback

logback-spring.xmllogback-spring.groovylogback.xml または logback.groovy

Log4j2

log4j2-spring.xml または log4j2.xml

JDK (Java Util ロギング)

logging.properties

可能な場合、ロギング構成に -spring バリアントを使用することをお勧めします(たとえば、logback.xml ではなく logback-spring.xml)。標準の構成場所を使用する場合、Spring はログの初期化を完全に制御できません。
Java Util Logging には、「実行可能な jar」から実行するときに課題を引き起こす既知のクラスローディングの課題があります。「実行可能な jar」から実行する場合は、可能な限り回避することをお勧めします。

カスタマイズを支援するために、次の表で説明するように、他のいくつかのプロパティが Spring Environment からシステムプロパティに転送されます。

Spring 環境 システムプロパティ コメント

logging.exception-conversion-word

LOG_EXCEPTION_CONVERSION_WORD

例外を記録するときに使用される変換語。

logging.file.clean-history-on-start

LOG_FILE_CLEAN_HISTORY_ON_START

起動時にアーカイブログファイルを消去するかどうか(LOG_FILE が有効な場合)。(デフォルトの Logback セットアップでのみサポートされます。)

logging.file.name

LOG_FILE

定義されている場合、デフォルトのログ構成で使用されます。

logging.file.max-size

LOG_FILE_MAX_SIZE

ログファイルの最大サイズ(LOG_FILE が有効な場合)。(デフォルトの Logback セットアップでのみサポートされます。)

logging.file.max-history

LOG_FILE_MAX_HISTORY

保持するアーカイブログファイルの最大数(LOG_FILE が有効な場合)。(デフォルトの Logback セットアップでのみサポートされます。)

logging.file.path

LOG_PATH

定義されている場合、デフォルトのログ構成で使用されます。

logging.file.total-size-cap

LOG_FILE_TOTAL_SIZE_CAP

保持するログバックアップの合計サイズ(LOG_FILE が有効な場合)。(デフォルトの Logback セットアップでのみサポートされます。)

logging.pattern.console

CONSOLE_LOG_PATTERN

コンソール(stdout)で使用するログパターン。(デフォルトの Logback セットアップでのみサポートされます。)

logging.pattern.dateformat

LOG_DATEFORMAT_PATTERN

ログ日付形式のアペンダーパターン。(デフォルトの Logback セットアップでのみサポートされます。)

logging.pattern.file

FILE_LOG_PATTERN

ファイルで使用するログパターン(LOG_FILE が有効な場合)。(デフォルトの Logback セットアップでのみサポートされます。)

logging.pattern.level

LOG_LEVEL_PATTERN

ログレベルをレンダリングするときに使用する形式(デフォルト %5p)。(デフォルトの Logback セットアップでのみサポートされます。)

logging.pattern.rolling-file-name

ROLLING_FILE_NAME_PATTERN

ロールオーバーされたログファイル名のパターン(デフォルト ${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz)。(デフォルトの Logback セットアップでのみサポートされます。)

PID

PID

現在のプロセス ID(可能な場合、OS 環境変数としてまだ定義されていない場合に検出されます)。

サポートされているすべてのログシステムは、構成ファイルを解析するときにシステムプロパティを参照できます。例については、spring-boot.jar のデフォルト構成を参照してください。

ロギングプロパティでプレースホルダーを使用する場合は、基になるフレームワークの構文ではなく、Spring Boot の構文を使用する必要があります。特に、Logback を使用する場合は、: をプロパティ名とそのデフォルト値の間の区切り文字として使用し、:- は使用しないでください。

LOG_LEVEL_PATTERN (または Logback で logging.pattern.level)のみをオーバーライドすることにより、MDC およびその他のアドホックコンテンツをログ行に追加できます。例: logging.pattern.level=user:%X{user} %5p を使用する場合、デフォルトのログ形式には、次の例に示すように、「user」の MDC エントリが含まれます(存在する場合)。

2019-08-30 12:30:04.031 user:someone INFO 22174 --- [  nio-8080-exec-0] demo.Controller
Handling authenticated request

4.7. Logback 拡張

Spring Boot には、高度な構成に役立つ Logback の拡張機能が多数含まれています。これらの拡張機能を logback-spring.xml 構成ファイルで使用できます。

標準の logback.xml 構成ファイルのロードが早すぎるため、拡張機能を使用できません。logback-spring.xml を使用するか、logging.config プロパティを定義する必要があります。
拡張は Logback の構成スキャンで (英語) は使用できません。設定しようとすると、構成ファイルに変更を加えると、次のいずれかのエラーがログに記録されます。
ERROR in [email protected] (英語)  :71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]]
ERROR in [email protected] (英語)  :71 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]]

4.7.1. プロファイル固有の構成

<springProfile> タグを使用すると、オプションで、アクティブな Spring プロファイルに基づいて構成のセクションを含めたり除外したりできます。プロファイルセクションは、<configuration> 要素内の任意の場所でサポートされます。name 属性を使用して、構成を受け入れるプロファイルを指定します。<springProfile> タグには、プロファイル名(staging など)またはプロファイル式を含めることができます。プロファイル式を使用すると、production & (eu-central | eu-west) などのより複雑なプロファイルロジックを表現できます。詳細については、リファレンスガイドを確認してください。次のリストは、3 つのサンプルプロファイルを示しています。

<springProfile name="staging">
    <!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>

<springProfile name="dev | staging">
    <!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>

<springProfile name="!production">
    <!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>

4.7.2. 環境プロパティ

<springProperty> タグを使用すると、Spring から Environment のプロパティを公開して、Logback 内で使用できます。これは、Logback 構成の application.properties ファイルの値にアクセスする場合に役立ちます。このタグは、Logback の標準 <property> タグと同様に機能します。ただし、直接 value を指定するのではなく、プロパティの source を(Environment から)指定します。local スコープ以外の場所にプロパティを保存する必要がある場合は、scope 属性を使用できます。フォールバック値が必要な場合(プロパティが Environment に設定されていない場合)、defaultValue 属性を使用できます。次の例は、Logback 内で使用するプロパティを公開する方法を示しています。

<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"
        defaultValue="localhost"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
    <remoteHost>${fluentHost}</remoteHost>
    ...
</appender>
source は、ケバブの場合(my.property-name など)で指定する必要があります。ただし、緩和されたルールを使用して、Environment にプロパティを追加できます。

5. 国際化対応

Spring Boot はローカライズされたメッセージをサポートしているため、アプリケーションは異なる言語設定のユーザーに対応できます。デフォルトでは、Spring Boot は、クラスパスのルートで messages リソースバンドルの存在を探します。

自動構成は、構成されたリソースバンドルのデフォルトプロパティファイルが利用可能な場合に適用されます(つまり、デフォルトで messages.properties)。リソースバンドルに言語固有のプロパティファイルのみが含まれている場合、デフォルトを追加する必要があります。設定されたベース名のいずれかに一致するプロパティファイルが見つからない場合、自動構成された MessageSource はありません。

次の例に示すように、spring.messages 名前空間を使用して、リソースバンドルのベース名と他のいくつかの属性を構成できます。

spring.messages.basename=messages,config.i18n.messages
spring.messages.fallback-to-system-locale=false
spring.messages.basename は、パッケージ修飾子またはクラスパスルートから解決されたリソースのいずれかの場所のコンマ区切りリストをサポートします。

サポートされるオプションの詳細については、MessageSourceProperties (GitHub) を参照してください。

6. JSON

Spring Boot は、3 つの JSON マッピングライブラリとの統合を提供します。

  • Gson

  • Jackson

  • JSON-B

Jackson は、推奨されるデフォルトのライブラリです。

6.1. Jackson

Jackson の自動構成が提供され、Jackson は spring-boot-starter-json の一部です。Jackson がクラスパスにある場合、ObjectMapper Bean が自動的に構成されます。ObjectMapper の構成をカスタマイズするために、いくつかの構成プロパティが提供されています。

6.2. Gson

Gson の自動構成が提供されます。Gson がクラスパスにある場合、Gson Bean が自動的に構成されます。構成をカスタマイズするために、いくつかの spring.gson.* 構成プロパティが提供されています。さらに制御するには、1 つ以上の GsonBuilderCustomizer Bean を使用できます。

6.3. JSON-B

JSON-B の自動構成が提供されます。JSON-B API と実装がクラスパスにある場合、Jsonb Bean が自動的に構成されます。優先される JSON-B 実装は、依存関係管理が提供される Apache Johnzon です。

7. Web アプリケーションの開発

Spring Boot は、Web アプリケーション開発に適しています。組み込み Tomcat、Jetty、Undertow、または Netty を使用して、自己完結型の HTTP サーバーを作成できます。ほとんどの Web アプリケーションは spring-boot-starter-web モジュールを使用して、すぐに起動して実行します。spring-boot-starter-webflux モジュールを使用して、リアクティブ Web アプリケーションを構築することもできます。

Spring Boot Web アプリケーションをまだ開発していない場合は、「Hello World!」に従ってください。入門セクションの例。

7.1. 「Spring Web MVC フレームワーク」

Spring Web MVC フレームワーク(「Spring MVC」とも呼ばれます)は、豊富な「モデルビューコントローラー」Web フレームワークです。Spring MVC では、受信 HTTP リクエストを処理するための特別な @Controller または @RestController Bean を作成できます。コントローラーのメソッドは、@RequestMapping アノテーションを使用して HTTP にマップされます。

次のコードは、JSON データを提供する典型的な @RestController を示しています。

@RestController
@RequestMapping(value="/users")
public class MyRestController {

    @RequestMapping(value="/{user}", method=RequestMethod.GET)
    public User getUser(@PathVariable Long user) {
        // ...
    }

    @RequestMapping(value="/{user}/customers", method=RequestMethod.GET)
    List<Customer> getUserCustomers(@PathVariable Long user) {
        // ...
    }

    @RequestMapping(value="/{user}", method=RequestMethod.DELETE)
    public User deleteUser(@PathVariable Long user) {
        // ...
    }

}

Spring MVC はコア Spring Framework の一部であり、詳細情報はリファレンスドキュメントで入手できますspring.io/guides で利用可能な Spring MVC をカバーするいくつかのガイドもあります。

7.1.1. Spring MVC 自動構成

Spring Boot は、ほとんどのアプリケーションで適切に機能する Spring MVC の自動構成を提供します。

自動構成により、Spring のデフォルトに加えて次の機能が追加されます。

これらの Spring Boot MVC のカスタマイズを保持し、さらに MVC のカスタマイズ(インターセプター、フォーマッター、View Controller、およびその他の機能)を作成する場合は、@EnableWebMvc なしでタイプ WebMvcConfigurer の独自の @Configuration クラスを追加できます。

RequestMappingHandlerMappingRequestMappingHandlerAdapter または ExceptionHandlerExceptionResolver のカスタムインスタンスを提供し、Spring Boot MVC のカスタマイズを維持したい場合は、タイプ WebMvcRegistrations の Bean を宣言し、それを使用してそれらのコンポーネントのカスタムインスタンスを提供できます。

Spring MVC を完全に制御したい場合は、@EnableWebMvc でアノテーション付けされた独自の @Configuration を追加するか、@EnableWebMvc の Javadoc に従って、独自の @Configuration アノテーション付き DelegatingWebMvcConfiguration を追加できます。

7.1.2. HttpMessageConverters

Spring MVC は、HttpMessageConverter インターフェースを使用して HTTP リクエストとレスポンスを変換します。すぐに使用できるデフォルトが含まれています。例:オブジェクトは自動的に JSON(Jackson ライブラリを使用)または XML(Jackson XML 拡張機能(使用可能な場合)を使用、または JAXB を使用して Jackson XML 拡張機能を使用できない場合)に変換できます。デフォルトでは、文字列は UTF-8 でエンコードされます。

コンバーターを追加またはカスタマイズする必要がある場合は、次のリストに示すように、Spring Boot の HttpMessageConverters クラスを使用できます。

import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.*;
import org.springframework.http.converter.*;

@Configuration(proxyBeanMethods = false)
public class MyConfiguration {

    @Bean
    public HttpMessageConverters customConverters() {
        HttpMessageConverter<?> additional = ...
        HttpMessageConverter<?> another = ...
        return new HttpMessageConverters(additional, another);
    }

}

コンテキストに存在する HttpMessageConverter Bean は、コンバーターのリストに追加されます。同じ方法でデフォルトのコンバーターをオーバーライドすることもできます。

7.1.3. カスタム JSON シリアライザーとデシリアライザー

Jackson を使用して JSON データをシリアライズおよびデシリアライズする場合、独自の JsonSerializer および JsonDeserializer クラスを作成することができます。カスタムシリアライザーは通常、モジュールを介して Jackson に登録されます (GitHub) が、Spring Boot は Spring Bean を直接登録しやすくする代替 @JsonComponent アノテーションを提供します。

JsonSerializerJsonDeserializer または KeyDeserializer 実装で @JsonComponent アノテーションを直接使用できます。次の例に示すように、内部クラスとしてシリアライザー / デシリアライザーを含むクラスでも使用できます。

import java.io.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import org.springframework.boot.jackson.*;

@JsonComponent
public class Example {

    public static class Serializer extends JsonSerializer<SomeObject> {
        // ...
    }

    public static class Deserializer extends JsonDeserializer<SomeObject> {
        // ...
    }

}

ApplicationContext 内のすべての @JsonComponent Bean は、Jackson に自動的に登録されます。@JsonComponent は @Component でメタアノテーションが付けられているため、通常のコンポーネントスキャン規則が適用されます。

Spring Boot は、オブジェクトを直列化するときに標準 Jackson バージョンの有用な代替を提供する JsonObjectSerializer (GitHub) および JsonObjectDeserializer (GitHub) 基本クラスも提供します。詳細については、Javadoc の JsonObjectSerializer(Javadoc) および JsonObjectDeserializer(Javadoc) を参照してください。

7.1.4. MessageCodesResolver

Spring MVC には、バインディングエラーからエラーメッセージをレンダリングするためのエラーコードを生成するための戦略 MessageCodesResolver があります。spring.mvc.message-codes-resolver-format プロパティ PREFIX_ERROR_CODE または POSTFIX_ERROR_CODE を設定すると、Spring Boot が自動的に作成します(DefaultMessageCodesResolver.Format(Javadoc) の列挙を参照)。

7.1.5. 静的コンテンツ

デフォルトでは、Spring Boot は、クラスパス内の /static (または /public または /resources または /META-INF/resources)と呼ばれるディレクトリまたは ServletContext のルートから静的コンテンツを提供します。Spring MVC の ResourceHttpRequestHandler を使用するため、独自の WebMvcConfigurer を追加して addResourceHandlers メソッドをオーバーライドすることにより、その動作を変更できます。

スタンドアロン Web アプリケーションでは、コンテナーからのデフォルトサーブレットも有効になり、フォールバックとして機能し、Spring が処理しないことを決定した場合、ServletContext のルートからコンテンツを提供します。Spring は常に DispatcherServlet を介してリクエストを処理できるため、ほとんどの場合、これは起こりません(デフォルトの MVC 構成を変更しない限り)。

デフォルトでは、リソースは /** にマップされますが、spring.mvc.static-path-pattern プロパティでそれを調整できます。たとえば、すべてのリソースを /resources/** に再配置するには、次のようにします。

spring.mvc.static-path-pattern=/resources/**

spring.resources.static-locations プロパティを使用して、静的リソースの場所をカスタマイズすることもできます(デフォルト値をディレクトリの場所のリストに置き換えます)。ルートサーブレットコンテキストパス "/" もロケーションとして自動的に追加されます。

前述の「標準」の静的リソースの場所に加えて、Webjars コンテンツ (英語) には特別なケースが作成されます。WebZZ 形式でパッケージ化されている場合、/webjars/** にパスを持つリソースは jar ファイルから提供されます。

アプリケーションが jar としてパッケージ化されている場合は、src/main/webapp ディレクトリを使用しないでください。このディレクトリは一般的な標準ですが、war パッケージでのみ機能し、jar を生成する場合、ほとんどのビルドツールでは暗黙のうちに無視されます。

Spring Boot は、Spring MVC が提供する高度なリソース処理機能もサポートしているため、静的リソースのキャッシュ無効化や Webjar のバージョンに依存しない URL の使用などのユースケースが可能です。

Webjar にバージョンに依存しない URL を使用するには、webjars-locator-core 依存関係を追加します。次に、Webjar を宣言します。例として jQuery を使用して、"/webjars/jquery/jquery.min.js" を追加すると、"/webjars/jquery/x.y.z/jquery.min.js" が生成されます(x.y.z は Webjar バージョンです)。

JBoss を使用する場合、webjars-locator-core ではなく webjars-locator-jboss-vfs 依存関係を宣言する必要があります。それ以外の場合、すべての Webjar は 404 として解決されます。

キャッシュ無効化を使用するには、次の構成ですべての静的リソースのキャッシュ無効化ソリューションを構成し、URL に <link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/> などのコンテンツハッシュを効果的に追加します。

spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
リソースへのリンクは、Thymeleaf および FreeMarker 用に自動構成された ResourceUrlEncodingFilter のおかげで、実行時にテンプレートで書き換えられます。JSP を使用する場合は、このフィルターを手動で宣言する必要があります。現在、他のテンプレートエンジンは自動的にサポートされていませんが、カスタムテンプレートマクロ / ヘルパーおよび ResourceUrlProvider(Javadoc) を使用することができます。

JavaScript モジュールローダーなどを使用してリソースを動的にロードする場合、ファイルの名前を変更することはできません。そのため、他の戦略もサポートされており、組み合わせることができます。"fixed" 戦略では、次の例に示すように、ファイル名を変更せずに URL に静的バージョン文字列を追加します。

spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
spring.resources.chain.strategy.fixed.enabled=true
spring.resources.chain.strategy.fixed.paths=/js/lib/
spring.resources.chain.strategy.fixed.version=v12

この構成では、"/js/lib/" にある JavaScript モジュールは固定バージョン管理戦略("/v12/js/lib/mymodule.js")を使用しますが、他のリソースはコンテンツコンテンツ(<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>)を引き続き使用します。

サポートされるオプションの詳細については、ResourceProperties (GitHub) を参照してください。

この機能は、専用のブログ投稿 (英語) および Spring Framework のリファレンスドキュメントで詳細に説明されています。

7.1.6. ウェルカムページ

Spring Boot は、静的なウェルカムページとテンプレート化されたウェルカムページの両方をサポートしています。最初に、構成された静的コンテンツの場所で index.html ファイルを探します。見つからない場合は、index テンプレートを探します。どちらかが見つかった場合、アプリケーションのウェルカムページとして自動的に使用されます。

7.1.7. カスタムファビコン

他の静的リソースと同様に、Spring Boot は構成された静的コンテンツの場所で favicon.ico を探します。そのようなファイルが存在する場合、アプリケーションのファビコンとして自動的に使用されます。

7.1.8. パスマッチングとコンテンツネゴシエーション

Spring MVC は、リクエストパスを確認し、それをアプリケーションで定義されたマッピング(たとえば、コントローラーメソッドの @GetMapping アノテーション)と照合することにより、受信 HTTP リクエストをハンドラーにマッピングできます。

Spring Boot は、デフォルトでサフィックスパターンマッチングを無効にすることを選択します。つまり、"GET /projects/spring-boot.json" のようなリクエストは @GetMapping("/projects/spring-boot") マッピングに一致しません。これは、Spring MVC アプリケーションのベストプラクティスと見なされます。この機能は、適切な「Accept」リクエストヘッダーを送信しなかった HTTP クライアントにとって、これまで主に役立ちました。正しいコンテンツタイプをクライアントに送信する必要がありました。最近では、コンテンツネゴシエーションの信頼性がはるかに高くなっています。

常に適切な「Accept」リクエストヘッダーを送信しない HTTP クライアントに対処する他の方法があります。サフィックスマッチングを使用する代わりに、クエリパラメーターを使用して、"GET /projects/spring-boot?format=json" などのリクエストが @GetMapping("/projects/spring-boot") にマッピングされるようにすることができます。

spring.mvc.contentnegotiation.favor-parameter=true

# We can change the parameter name, which is "format" by default:
# spring.mvc.contentnegotiation.parameter-name=myparam

# We can also register additional file extensions/media types with:
spring.mvc.contentnegotiation.media-types.markdown=text/markdown

サフィックスパターンマッチングは非推奨であり、将来のリリースでは削除される予定です。警告を理解していても、アプリケーションでサフィックスパターンマッチングを使用する場合は、次の構成が必要です。

spring.mvc.contentnegotiation.favor-path-extension=true
spring.mvc.pathmatch.use-suffix-pattern=true

または、すべてのサフィックスパターンを開くのではなく、登録済みのサフィックスパターンのみをサポートする方が安全です。

spring.mvc.contentnegotiation.favor-path-extension=true
spring.mvc.pathmatch.use-registered-suffix-pattern=true

# You can also register additional file extensions/media types with:
# spring.mvc.contentnegotiation.media-types.adoc=text/asciidoc

7.1.9. ConfigurableWebBindingInitializer

Spring MVC は WebBindingInitializer を使用して、特定のリクエストに対して WebDataBinder を初期化します。独自の ConfigurableWebBindingInitializer@Bean を作成する場合、Spring Boot はそれを使用するように Spring MVC を自動的に構成します。

7.1.10. テンプレートエンジン

REST Web サービスだけでなく、Spring MVC を使用して動的な HTML コンテンツを提供することもできます。Spring MVC は、Thymeleaf、FreeMarker、JSP など、さまざまなテンプレートテクノロジーをサポートしています。また、他の多くのテンプレートエンジンには、独自の Spring MVC 統合が含まれています。

Spring Boot には、次のテンプレートエンジンの自動構成サポートが含まれています。

可能であれば、JSP を避ける必要があります。組み込みサーブレットコンテナーで使用する場合、いくつかの既知の制限があります。

これらのテンプレートエンジンのいずれかを既定の構成で使用すると、src/main/resources/templates からテンプレートが自動的に選択されます。

アプリケーションの実行メソッドに応じて、IntelliJ IDEA はクラスパスの順序を変えます。IDE でメインメソッドからアプリケーションを実行すると、Maven または Gradle を使用して、またはパッケージ化された jar からアプリケーションを実行する場合とは順序が異なります。これにより、Spring Boot がクラスパスでテンプレートを見つけられない場合があります。この問題がある場合は、IDE でクラスパスを並べ替えて、モジュールのクラスとリソースを最初に配置できます。または、次のように、クラスパス上のすべての templates ディレクトリを検索するようにテンプレートプレフィックスを設定できます: classpath*:/templates/

7.1.11. エラー処理

デフォルトでは、Spring Boot は、すべてのエラーを適切な方法で処理する /error マッピングを提供し、サーブレットコンテナーに「グローバル」エラーページとして登録されます。マシンクライアントの場合、エラー、HTTP ステータス、および例外メッセージの詳細を含む JSON レスポンスを生成します。ブラウザクライアントには、同じデータを HTML 形式でレンダリングする「ホワイトラベル」エラービューがあります(カスタマイズするには、error に解決される View を追加します)。デフォルトの動作を完全に置き換えるには、ErrorController を実装してそのタイプの Bean 定義を登録するか、タイプ ErrorAttributes の Bean を追加して既存のメカニズムを使用し、内容を置き換えます。

BasicErrorController は、カスタム ErrorController の基本クラスとして使用できます。これは、新しいコンテンツタイプのハンドラーを追加する場合に特に便利です(デフォルトでは、text/html を具体的に処理し、他のすべてにフォールバックを提供します)。これを行うには、BasicErrorController を継承し、produces 属性を持つ @RequestMapping を使用して public メソッドを追加し、新しいタイプの Bean を作成します。

次の例に示すように、@ControllerAdvice アノテーションが付けられたクラスを定義して、特定のコントローラーまたは例外タイプ、あるいはその両方を返すように JSON ドキュメントをカスタマイズすることもできます。

@ControllerAdvice(basePackageClasses = AcmeController.class)
public class AcmeControllerAdvice extends ResponseEntityExceptionHandler {

    @ExceptionHandler(YourException.class)
    @ResponseBody
    ResponseEntity<?> handleControllerException(HttpServletRequest request, Throwable ex) {
        HttpStatus status = getStatus(request);
        return new ResponseEntity<>(new CustomErrorType(status.value(), ex.getMessage()), status);
    }

    private HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        if (statusCode == null) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        return HttpStatus.valueOf(statusCode);
    }

}

上記の例では、YourException が AcmeController と同じパッケージで定義されたコントローラーによってスローされた場合、ErrorAttributes 表現の代わりに CustomErrorType POJO の JSON 表現が使用されます。

カスタムエラーページ

特定のステータスコードのカスタム HTML エラーページを表示する場合は、/error ディレクトリにファイルを追加できます。エラーページは、静的 HTML(つまり、任意の静的リソースディレクトリに追加される)にすることも、テンプレートを使用して作成することもできます。ファイルの名前は、正確なステータスコードまたはシリーズマスクである必要があります。

例: 404 を静的 HTML ファイルにマップするには、ディレクトリ構造は次のようになります。

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <other public assets>

FreeMarker テンプレートを使用してすべての 5xx エラーをマップするには、ディレクトリ構造は次のようになります。

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- templates/
             +- error/
             |   +- 5xx.ftlh
             +- <other templates>

より複雑なマッピングの場合、次の例に示すように、ErrorViewResolver インターフェースを実装する Bean を追加することもできます。

public class MyErrorViewResolver implements ErrorViewResolver {

    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request,
            HttpStatus status, Map<String, Object> model) {
        // Use the request or status to optionally return a ModelAndView
        return ...
    }

}

@ExceptionHandler メソッド@ControllerAdvice などの通常の Spring MVC 機能も使用できます。ErrorController は、未処理の例外をピックアップします。

Spring MVC 外のエラーページのマッピング

Spring MVC を使用しないアプリケーションの場合、ErrorPageRegistrar インターフェースを使用して ErrorPages を直接登録できます。この抽象化は、基礎となる埋め込みサーブレットコンテナーと直接機能し、Spring MVC DispatcherServlet がなくても機能します。

@Bean
public ErrorPageRegistrar errorPageRegistrar(){
    return new MyErrorPageRegistrar();
}

// ...

private static class MyErrorPageRegistrar implements ErrorPageRegistrar {

    @Override
    public void registerErrorPages(ErrorPageRegistry registry) {
        registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
    }

}
Filter によって処理されるパスで ErrorPage を登録する場合(Jersey や Wicket などの一部の非 SpringWeb フレームワークで一般的)、次に示すように、Filter を ERROR ディスパッチャーとして明示的に登録する必要があります。次の例:
@Bean
public FilterRegistrationBean myFilter() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(new MyFilter());
    ...
    registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
    return registration;
}

デフォルトの FilterRegistrationBean には ERROR ディスパッチャータイプが含まれていないことに注意してください。

war デプロイでのエラー処理

サーブレットコンテナーにデプロイされると、Spring Boot はそのエラーページフィルターを使用して、エラーステータスのリクエストを適切なエラーページに転送します。これは、サーブレット仕様がエラーページを登録するための API を提供しないために必要です。war ファイルをデプロイするコンテナーと、アプリケーションが使用するテクノロジーによっては、追加の構成が必要になる場合があります。

エラーページフィルターは、レスポンスがまだコミットされていない場合にのみ、リクエストを正しいエラーページに転送できます。デフォルトでは、WebSphere アプリケーションサーバー 8.0 以降は、サーブレットのサービスメソッドが正常に完了すると、レスポンスをコミットします。com.ibm.ws.webcontainer.invokeFlushAfterService を false に設定して、この動作を無効にする必要があります。

Spring Security を使用していて、エラーページのプリンシパルにアクセスする場合は、Spring Security のフィルターがエラーディスパッチで呼び出されるように構成する必要があります。そのためには、spring.security.filter.dispatcher-types プロパティを async, error, forward, request に設定します。

7.1.12. Spring HATEOAS

ハイパーメディアを利用する RESTful API を開発する場合、Spring Boot は、ほとんどのアプリケーションで適切に動作する Spring HATEOAS の自動構成を提供します。自動構成により、@EnableHypermediaSupport を使用する必要がなくなり、多数の Bean が登録されて、ハイパーメディアベースのアプリケーションの構築が容易になります。LinkDiscoverers (クライアント側サポート用)およびレスポンスを目的の表現に正しくマーシャリングするように構成された ObjectMapper が含まれます。ObjectMapper は、さまざまな spring.jackson.* プロパティを設定するか、存在する場合は Jackson2ObjectMapperBuilder Bean によってカスタマイズされます。

@EnableHypermediaSupport を使用して、Spring HATEOAS の構成を制御できます。これを行うと、前述の ObjectMapper カスタマイズが無効になることに注意してください。

7.1.13. CORS サポート

クロスオリジンリソース共有 (英語) (CORS)は、ほとんどのブラウザ (英語) で実装されている W3C 仕様 (英語) であり、IFRAME や JSONP などの安全性が低く強力なアプローチを使用する代わりに、どのようなクロスドメインリクエストを認可するかを柔軟に指定できます。

バージョン 4.2 の時点で、Spring MVC は CORS をサポートしています。Spring Boot アプリケーションで @CrossOrigin(Javadoc) アノテーションを使用したコントローラーメソッド CORS 構成を使用する場合、特定の構成は必要ありません。グローバル CORS 設定は、次の例に示すように、カスタマイズされた addCorsMappings(CorsRegistry) メソッドで WebMvcConfigurer Bean を登録することにより定義できます。

@Configuration(proxyBeanMethods = false)
public class MyConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**");
            }
        };
    }
}

7.2. 「Spring WebFlux フレームワーク」

Spring WebFlux は、Spring Framework 5.0. で導入された新しいリアクティブ Web フレームワークです。SpringMVC とは異なり、サーブレット API を必要とせず、完全に非同期でノンブロッキングであり、Reactor プロジェクト (英語) を通じて Reactive Streams (英語) 仕様を実装します。

Spring WebFlux には、機能ベースとアノテーションベースの 2 つのフレーバーがあります。次の例に示すように、アノテーションベースのモデルは Spring MVC モデルに非常に近いものです。

@RestController
@RequestMapping("/users")
public class MyRestController {

    @GetMapping("/{user}")
    public Mono<User> getUser(@PathVariable Long user) {
        // ...
    }

    @GetMapping("/{user}/customers")
    public Flux<Customer> getUserCustomers(@PathVariable Long user) {
        // ...
    }

    @DeleteMapping("/{user}")
    public Mono<User> deleteUser(@PathVariable Long user) {
        // ...
    }

}

次の例に示すように、機能バリアントである「WebFlux.fn」は、ルーティング構成をリクエストの実際の処理から分離します。

@Configuration(proxyBeanMethods = false)
public class RoutingConfiguration {

    @Bean
    public RouterFunction<ServerResponse> monoRouterFunction(UserHandler userHandler) {
        return route(GET("/{user}").and(accept(APPLICATION_JSON)), userHandler::getUser)
                .andRoute(GET("/{user}/customers").and(accept(APPLICATION_JSON)), userHandler::getUserCustomers)
                .andRoute(DELETE("/{user}").and(accept(APPLICATION_JSON)), userHandler::deleteUser);
    }

}

@Component
public class UserHandler {

    public Mono<ServerResponse> getUser(ServerRequest request) {
        // ...
    }

    public Mono<ServerResponse> getUserCustomers(ServerRequest request) {
        // ...
    }

    public Mono<ServerResponse> deleteUser(ServerRequest request) {
        // ...
    }
}

WebFlux は Spring Framework の一部であり、詳細な情報はリファレンスドキュメントで入手できます

RouterFunction Bean をいくつでも定義して、ルーターの定義をモジュール化できます。優先順位を適用する必要がある場合は、Bean をオーダーできます。

開始するには、spring-boot-starter-webflux モジュールをアプリケーションに追加します。

spring-boot-starter-web モジュールと spring-boot-starter-webflux モジュールの両方をアプリケーションに追加すると、WebFlux ではなく、Spring Boot が Spring MVC を自動構成します。多くの Spring 開発者が spring-boot-starter-webflux を Spring MVC アプリケーションに追加してリアクティブ WebClient を使用するため、この動作が選択されています。選択したアプリケーションタイプを SpringApplication.setWebApplicationType(WebApplicationType.REACTIVE) に設定することにより、引き続き選択を強制できます。

7.2.1. Spring WebFlux 自動構成

Spring Boot は、ほとんどのアプリケーションで適切に機能する Spring WebFlux の自動構成を提供します。

自動構成により、Spring のデフォルトに加えて次の機能が追加されます。

  • HttpMessageReader および HttpMessageWriter インスタンスのコーデックの構成(このドキュメントで後述)。

  • WebJars のサポートを含む、静的リソースの提供のサポート(このドキュメントで後述)。

Spring Boot WebFlux 機能を保持し、さらに WebFlux の構成を追加する場合、@EnableWebFlux なしでタイプ WebFluxConfigurer の独自の @Configuration クラスを追加できます。

Spring WebFlux を完全に制御したい場合は、@EnableWebFlux アノテーションが付けられた独自の @Configuration を追加できます。

7.2.2. HttpMessageReaders および HttpMessageWriters を使用した HTTP コーデック

Spring WebFlux は、HttpMessageReader および HttpMessageWriter インターフェースを使用して、HTTP リクエストおよびレスポンスを変換します。これらは、クラスパスで使用可能なライブラリを調べることにより、実用的なデフォルトを持つように CodecConfigurer で構成されます。

Spring Boot は、コーデックの専用構成プロパティ spring.codec.* を提供します。また、CodecCustomizer インスタンスを使用して、さらにカスタマイズを適用します。例: spring.jackson.* 設定キーは Jackson コーデックに適用されます。

コーデックを追加またはカスタマイズする必要がある場合は、次の例に示すように、カスタム CodecCustomizer コンポーネントを作成できます。

import org.springframework.boot.web.codec.CodecCustomizer;

@Configuration(proxyBeanMethods = false)
public class MyConfiguration {

    @Bean
    public CodecCustomizer myCodecCustomizer() {
        return codecConfigurer -> {
            // ...
        };
    }

}

7.2.3. 静的コンテンツ

デフォルトでは、Spring Boot は、クラスパス内の /static (または /public または /resources または /META-INF/resources)と呼ばれるディレクトリから静的コンテンツを提供します。Spring WebFlux の ResourceWebHandler を使用するため、独自の WebFluxConfigurer を追加して addResourceHandlers メソッドをオーバーライドすることにより、その動作を変更できます。

デフォルトでは、リソースは /** にマップされますが、spring.webflux.static-path-pattern プロパティを設定することでそれを調整できます。たとえば、すべてのリソースを /resources/** に再配置するには、次のようにします。

spring.webflux.static-path-pattern=/resources/**

spring.resources.static-locations を使用して、静的リソースの場所をカスタマイズすることもできます。これにより、デフォルト値がディレクトリの場所のリストに置き換えられます。そうすると、デフォルトのウェルカムページ検出がカスタムの場所に切り替わります。起動時にいずれかの場所に index.html がある場合、アプリケーションのホームページです。

前述の「標準」の静的リソースの場所に加えて、Webjars コンテンツ (英語) には特別なケースが作成されます。WebZZ 形式でパッケージ化されている場合、/webjars/** にパスを持つリソースは jar ファイルから提供されます。

Spring WebFlux アプリケーションは厳密にはサーブレット API に依存しないため、war ファイルとしてデプロイすることはできず、src/main/webapp ディレクトリを使用しません。

7.2.4. ウェルカムページ

Spring Boot は、静的なウェルカムページとテンプレート化されたウェルカムページの両方をサポートしています。最初に、構成された静的コンテンツの場所で index.html ファイルを探します。見つからない場合は、index テンプレートを探します。どちらかが見つかった場合、アプリケーションのウェルカムページとして自動的に使用されます。

7.2.5. テンプレートエンジン

REST Web サービスだけでなく、Spring WebFlux を使用して動的 HTML コンテンツを提供することもできます。Spring WebFlux は、Thymeleaf、FreeMarker、Mustache など、さまざまなテンプレートテクノロジーをサポートしています。

Spring Boot には、次のテンプレートエンジンの自動構成サポートが含まれています。

これらのテンプレートエンジンのいずれかを既定の構成で使用すると、src/main/resources/templates からテンプレートが自動的に選択されます。

7.2.6. エラー処理

Spring Boot は、すべてのエラーを適切な方法で処理する WebExceptionHandler を提供します。処理順序でのその位置は、WebFlux によって提供されるハンドラーの直前であり、最後に考慮されます。マシンクライアントの場合、エラー、HTTP ステータス、および例外メッセージの詳細を含む JSON レスポンスを生成します。ブラウザクライアントには、同じデータを HTML 形式でレンダリングする「ホワイトラベル」エラーハンドラーがあります。また、独自の HTML テンプレートを提供してエラーを表示することもできます(次のセクションを参照)。

この機能をカスタマイズするための最初のステップは、多くの場合、既存のメカニズムを使用しますが、エラーの内容を置換または拡張することを伴います。そのために、タイプ ErrorAttributes の Bean を追加できます。

エラー処理の動作を変更するには、ErrorWebExceptionHandler を実装し、そのタイプの Bean 定義を登録できます。WebExceptionHandler は非常に低レベルであるため、Spring Boot は次の例に示すように、WebFlux の関数方法でエラーを処理できる便利な AbstractErrorWebExceptionHandler も提供します。

public class CustomErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {

    // Define constructor here

    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {

        return RouterFunctions
                .route(aPredicate, aHandler)
                .andRoute(anotherPredicate, anotherHandler);
    }

}

より完全な図を得るには、DefaultErrorWebExceptionHandler を直接サブクラス化し、特定のメソッドをオーバーライドすることもできます。

カスタムエラーページ

特定のステータスコードのカスタム HTML エラーページを表示する場合は、/error ディレクトリにファイルを追加できます。エラーページは、静的 HTML(つまり、任意の静的リソースディレクトリに追加される)にすることも、テンプレートで作成することもできます。ファイルの名前は、正確なステータスコードまたはシリーズマスクである必要があります。

例: 404 を静的 HTML ファイルにマップするには、ディレクトリ構造は次のようになります。

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <other public assets>

Mustache テンプレートを使用してすべての 5xx エラーをマップするには、ディレクトリ構造は次のようになります。

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- templates/
             +- error/
             |   +- 5xx.mustache
             +- <other templates>

7.2.7. Web フィルター

Spring WebFlux は、HTTP リクエスト / レスポンス交換をフィルタリングするために実装できる WebFilter インターフェースを提供します。アプリケーションコンテキストで見つかった WebFilter Bean は、各交換のフィルタリングに自動的に使用されます。

フィルターの順序が重要な場合、Ordered を実装するか、@Order でアノテーションを付けることができます。Spring Boot の自動構成により、Web フィルターが構成される場合があります。その場合、次の表に示す順序が使用されます。

Web フィルター 順序

MetricsWebFilter

Ordered.HIGHEST_PRECEDENCE + 1

WebFilterChainProxy (Spring Security)

-100

HttpTraceWebFilter

Ordered.LOWEST_PRECEDENCE - 10

7.3. JAX-RS および Jersey

REST エンドポイントに JAX-RS プログラミングモデルを使用する場合は、Spring MVC の代わりに利用可能な実装のいずれかを使用できます。Jersey (英語) Apache CXF (英語) はすぐに使用できます。CXF では、Servlet または Filter をアプリケーションコンテキストで @Bean として登録する必要があります。Jersey はネイティブ Spring をサポートしているため、Spring Boot での自動構成サポートとスターターも提供しています。

Jersey を開始するには、spring-boot-starter-jersey を依存関係として含めてから、次の例に示すように、すべてのエンドポイントを登録するタイプ ResourceConfig の @Bean が 1 つ必要です。

@Component
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        register(Endpoint.class);
    }

}
Jersey の実行可能アーカイブのスキャンのサポートはかなり制限されています。例:実行可能な war ファイルを実行している場合、完全に実行可能な jar ファイルまたは WEB-INF/classes  で見つかったパッケージ内のエンドポイントをスキャンできません。この制限を回避するには、packages メソッドを使用せず、前の例に示すように、register メソッドを使用してエンドポイントを個別に登録する必要があります。

より高度なカスタマイズのために、ResourceConfigCustomizer を実装する Bean を任意の数だけ登録することもできます。

登録されたすべてのエンドポイントは、次の例に示すように、HTTP リソースアノテーション(@GET など)を含む @Components である必要があります。

@Component
@Path("/hello")
public class Endpoint {

    @GET
    public String message() {
        return "Hello";
    }

}

Endpoint は Spring @Component であるため、そのライフサイクルは Spring によって管理され、@Autowired アノテーションを使用して依存関係を注入し、@Value アノテーションを使用して外部構成を注入できます。デフォルトでは、Jersey サーブレットが登録され、/* にマップされます。@ApplicationPath を ResourceConfig に追加することにより、マッピングを変更できます。

デフォルトでは、Jersey は、jerseyServletRegistration という名前のタイプ ServletRegistrationBean の @Bean のサーブレットとしてセットアップされます。デフォルトでは、サーブレットは遅延的に初期化されますが、spring.jersey.servlet.load-on-startup を設定することでその動作をカスタマイズできます。同じ名前の独自のものを作成することにより、その Bean を無効化またはオーバーライドできます。spring.jersey.type=filter を設定することにより、サーブレットの代わりにフィルターを使用することもできます(この場合、置換またはオーバーライドする @Bean は jerseyFilterRegistration です)。フィルターには @Order があり、spring.jersey.filter.order で設定できます。spring.jersey.init.* を使用してプロパティのマップを指定することにより、サーブレットとフィルターの両方の登録に初期化パラメーターを指定できます。

7.4. 組み込みサーブレットコンテナーのサポート

Spring Boot には、組み込み Tomcat (Apache) Jetty (英語) 、および Undertow (GitHub) サーバーのサポートが含まれています。ほとんどの開発者は、適切な「スターター」を使用して、完全に構成されたインスタンスを取得します。デフォルトでは、組み込みサーバーはポート 8080 で HTTP リクエストをリッスンします。

7.4.1. サーブレット、フィルター、およびリスナー

組み込みサーブレットコンテナーを使用する場合、Spring Bean を使用するか、サーブレットコンポーネントをスキャンすることにより、サーブレット仕様からサーブレット、フィルター、およびすべてのリスナー(HttpSessionListener など)を登録できます。

サーブレット、フィルター、およびリスナーを Spring Bean として登録する

Spring Bean である ServletFilter またはサーブレット *Listener インスタンスは、組み込みコンテナーに登録されます。これは、構成中に application.properties の値を参照する場合に特に便利です。

デフォルトでは、コンテキストに含まれるサーブレットが 1 つのみの場合、/ にマッピングされます。複数のサーブレット Bean の場合、Bean 名がパスプレフィックスとして使用されます。フィルターは /* にマップします。

規則ベースのマッピングの柔軟性が不十分な場合は、ServletRegistrationBeanFilterRegistrationBean および ServletListenerRegistrationBean クラスを使用して完全に制御できます。

通常、フィルター Bean を順序付けしないでおくと安全です。特定の順序が必要な場合は、Filter に @Order でアノテーションを付けるか、Ordered を実装する必要があります。@Order で Bean メソッドにアノテーションを付けることにより、Filter の順序を構成することはできません。Filter クラスを変更して @Order を追加したり、Ordered を実装したりできない場合は、Filter に FilterRegistrationBean を定義し、setOrder(int) メソッドを使用して登録 Bean の順序を設定する必要があります。Ordered.HIGHEST_PRECEDENCE でリクエスト本文を読み取るフィルターの構成は避けてください。アプリケーションの文字エンコード構成に反する可能性があるためです。サーブレットフィルターがリクエストをラップする場合、OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER 以下の順序で構成する必要があります。

アプリケーション内のすべての Filter の順序を確認するには、web  ロギンググループlogging.level.web=debug)のデバッグレベルロギングを有効にします。登録されたフィルターの詳細(順序や URL パターンなど)は、起動時にログに記録されます。
Filter Bean はアプリケーションライフスタイルの非常に早い段階で初期化されるため、登録する際には注意してください。他の Bean と対話する Filter を登録する必要がある場合は、代わりに DelegatingFilterProxyRegistrationBean(Javadoc) の使用を検討してください。

7.4.2. サーブレットコンテキストの初期化

埋め込みサーブレットコンテナーは、Servlet 3.0+ javax.servlet.ServletContainerInitializer インターフェースまたは Spring の org.springframework.web.WebApplicationInitializer インターフェースを直接実行しません。これは、war 内で実行するように設計されたサードパーティライブラリが Spring Boot アプリケーションを破損するリスクを減らすことを目的とした意図的な設計上の決定です。

Spring Boot アプリケーションでサーブレットコンテキストの初期化を実行する必要がある場合は、org.springframework.boot.web.servlet.ServletContextInitializer インターフェースを実装する Bean を登録する必要があります。単一の onStartup メソッドは ServletContext へのアクセスを提供し、必要に応じて、既存の WebApplicationInitializer へのアダプターとして簡単に使用できます。

サーブレット、フィルター、およびリスナーのスキャン

埋め込みコンテナーを使用する場合、@ServletComponentScan を使用して、@WebServlet@WebFilter および @WebListener アノテーションが付けられたクラスの自動登録を有効にできます。

@ServletComponentScan は、コンテナーの組み込み検出メカニズムが代わりに使用されるスタンドアロンコンテナーでは効果がありません。

7.4.3. ServletWebServerApplicationContext

内部では、Spring Boot は、組み込みサーブレットコンテナーのサポートに異なるタイプの ApplicationContext を使用します。ServletWebServerApplicationContext は、単一の ServletWebServerFactory Bean を検索することによって自身をブートストラップする特別なタイプの WebApplicationContext です。通常、TomcatServletWebServerFactoryJettyServletWebServerFactory または UndertowServletWebServerFactory は自動構成されています。

通常、これらの実装クラスを意識する必要はありません。ほとんどのアプリケーションは自動構成され、適切な ApplicationContext および ServletWebServerFactory がユーザーに代わって作成されます。

7.4.4. 埋め込みサーブレットコンテナーのカスタマイズ

Spring Environment プロパティを使用して、一般的なサーブレットコンテナー設定を構成できます。通常、application.properties ファイルでプロパティを定義します。

一般的なサーバー設定は次のとおりです。

  • ネットワーク設定 : 受信 HTTP リクエストのリスンポート(server.port)、server.address にバインドするインターフェースアドレスなど。

  • セッション設定 : セッションが永続的か(server.servlet.session.persistent)、セッションタイムアウト(server.servlet.session.timeout)、セッションデータの場所(server.servlet.session.store-dir)、およびセッション Cookie 構成(server.servlet.session.cookie.*)。

  • エラー管理 : エラーページ(server.error.path)などの場所。

  • SSL

  • HTTP 圧縮

Spring Boot は、可能な限り共通の設定を公開しようとしますが、常に可能とは限りません。これらの場合、専用の名前空間はサーバー固有のカスタマイズを提供します(server.tomcat および server.undertow を参照)。たとえば、アクセスログは、組み込みサーブレットコンテナーの特定の機能を使用して設定できます。

完全なリストについては、ServerProperties (GitHub) クラスを参照してください。
プログラムによるカスタマイズ

組み込みサーブレットコンテナーをプログラムで設定する必要がある場合は、WebServerFactoryCustomizer インターフェースを実装する Spring Bean を登録できます。WebServerFactoryCustomizer は、多数のカスタマイズ setter メソッドを含む ConfigurableServletWebServerFactory へのアクセスを提供します。次の例は、プログラムでポートを設定する方法を示しています。

import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.stereotype.Component;

@Component
public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {

    @Override
    public void customize(ConfigurableServletWebServerFactory server) {
        server.setPort(9000);
    }

}
TomcatServletWebServerFactoryJettyServletWebServerFactory と UndertowServletWebServerFactory は、それぞれ Tomcat、Jetty、Undertow 用の追加のカスタマイズ setter メソッドを持つ ConfigurableServletWebServerFactory の専用バリアントです。
ConfigurableServletWebServerFactory を直接カスタマイズする

前述のカスタマイズ手法があまりにも制限されている場合は、TomcatServletWebServerFactoryJettyServletWebServerFactory または UndertowServletWebServerFactory Bean を自分で登録できます。

@Bean
public ConfigurableServletWebServerFactory webServerFactory() {
    TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
    factory.setPort(9000);
    factory.setSessionTimeout(10, TimeUnit.MINUTES);
    factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notfound.html"));
    return factory;
}

Setter は、多くの構成オプション用に提供されています。よりエキゾチックな何かをする必要がある場合、いくつかの protected メソッド「フック」も提供されます。詳細については、ソースコードのドキュメント(Javadoc) を参照してください。

7.4.5. JSP の制限

組み込みサーブレットコンテナーを使用する(実行可能アーカイブとしてパッケージ化されている)Spring Boot アプリケーションを実行する場合、JSP サポートにはいくつかの制限があります。

  • Jetty と Tomcat では、war パッケージを使用すれば動作するはずです。実行可能な war は、java -jar で起動すると動作し、任意の標準コンテナーに配備することもできます。実行可能 jar を使用する場合、JSP はサポートされません。

  • Undertow は JSP をサポートしていません。

  • カスタム error.jsp ページを作成しても、エラー処理のデフォルトビューは上書きされません。代わりにカスタムエラーページを使用する必要があります。

7.5. 埋め込み型リアクティブサーバーのサポート

Spring Boot には、Reactor、Netty、Tomcat、Jetty、および Undertow の埋め込み型リアクティブ Web サーバーのサポートが含まれています。ほとんどの開発者は適切な「スターター」を使用して、完全に構成されたインスタンスを取得します。デフォルトでは、組み込みサーバーはポート 8080 で HTTP リクエストをリッスンします。

7.6. リアクティブサーバーリソースの構成

Reactor Netty または Jetty サーバーを自動構成する場合、Spring Boot は、サーバーインスタンスに HTTP リソースを提供する特定の Bean ReactorResourceFactory または JettyResourceFactory を作成します。

デフォルトでは、これらのリソースは、最適なパフォーマンスのために、Reactor Netty および Jetty クライアントとも共有されます。

  • 同じテクノロジーがサーバーとクライアントに使用されます

  • クライアントインスタンスは、Spring Boot によって自動構成された WebClient.Builder Bean を使用して構築されます

開発者は、カスタム ReactorResourceFactory または JettyResourceFactory Bean を提供することにより、Jetty および Reactor Netty のリソース構成をオーバーライドできます。これは、クライアントとサーバーの両方に適用されます。

WebClient ランタイムセクションでクライアント側のリソース構成について詳しく知ることができます。

8. 正常なシャットダウン

グレースフルシャットダウンは、4 つすべての組み込み Web サーバー(Jetty、Reactor Netty、Tomcat、および Undertow)と、リアクティブおよびサーブレットベースの両方の Web アプリケーションでサポートされています。これは、アプリケーションコンテキストを閉じるときに発生し、SmartLifecycle Bean を停止する最も早い段階で実行されます。この停止処理では、既存のリクエストは完了できるが新しいリクエストは許可されない猶予期間を提供するタイムアウトが使用されます。新しいリクエストが許可されない正確な方法は、使用されている Web サーバーによって異なります。Jetty、Reactor、Netty、および Tomcat は、ネットワーク層でのリクエストの受け入れを停止します。Undertow はリクエストを受け入れますが、サービスが利用できない (503) レスポンスですぐにレスポンスします。

Tomcat による正常なシャットダウンには、Tomcat 9.0.33 以降が必要です。

グレースフルシャットダウンを有効にするには、次の例に示すように、server.shutdown プロパティを構成します。

server.shutdown=graceful

タイムアウト期間を構成するには、次の例に示すように、spring.lifecycle.timeout-per-shutdown-phase プロパティを構成します。

spring.lifecycle.timeout-per-shutdown-phase=20s
IDE で正常なシャットダウンを使用すると、適切な SIGTERM 信号が送信されない場合、正常に動作しない可能性があります。詳細については、IDE のドキュメントを参照してください。

9. RSocket

RSocket (英語) は、バイトストリームトランスポートで使用するバイナリプロトコルです。単一の接続を介して渡す非同期メッセージを介して対称相互作用モデルを有効にします。

Spring Framework の spring-messaging モジュールは、クライアント側とサーバー側の両方で RSocket リクエスターとレスポンダーのサポートを提供します。RSocket プロトコルの概要など、詳細については、Spring Framework リファレンスの RSocket セクションを参照してください。

9.1. RSocket 戦略の自動構成

Spring Boot は、RSocket ペイロードのエンコードおよびデコードに必要なすべてのインフラストラクチャを提供する RSocketStrategies Bean を自動構成します。デフォルトでは、自動構成は以下を順番に構成しようとします。

  1. Jackson を使用した CBOR (英語) コーデック

  2. Jackson を使用した JSON コーデック

spring-boot-starter-rsocket スターターは両方の依存関係を提供します。Jackson サポートセクションをチェックして、カスタマイズの可能性について詳しく調べましょう。

開発者は、RSocketStrategiesCustomizer インターフェースを実装する Bean を作成することにより、RSocketStrategies コンポーネントをカスタマイズできます。コーデックの順序を決定するため、@Order は重要であることに注意してください。

9.2. RSocket サーバーの自動構成

Spring Boot は、RSocket サーバーの自動構成を提供します。必要な依存関係は spring-boot-starter-rsocket によって提供されます。

Spring Boot を使用すると、WebFlux サーバーから WebSocket を介して RSocket を公開したり、独立した RSocket サーバーを立ち上げることができます。これは、アプリケーションのタイプとその構成によって異なります。

WebFlux アプリケーション(つまり、タイプ WebApplicationType.REACTIVE)の場合、RSocket サーバーは、次のプロパティが一致する場合にのみ Web サーバーにプラグインされます。

spring.rsocket.server.mapping-path=/rsocket # a mapping path is defined
spring.rsocket.server.transport=websocket # websocket is chosen as a transport
#spring.rsocket.server.port= # no port is defined
RSocket を Web サーバーに接続することは、Reactor Netty でのみサポートされています。RSocket 自体はそのライブラリで構築されています。

または、RSocket TCP または websocket サーバーは、独立した組み込みサーバーとして起動されます。依存関係の要件に加えて、唯一の必要な構成は、そのサーバーのポートを定義することです。

spring.rsocket.server.port=9898 # the only required configuration
spring.rsocket.server.transport=tcp # you're free to configure other properties

9.3. Spring メッセージング RSocket サポート

Spring Boot は、RSocket の Spring メッセージングインフラストラクチャを自動構成します。

これは、Spring Boot が、アプリケーションへの RSocket リクエストを処理する RSocketMessageHandler Bean を作成することを意味します。

9.4. RSocketRequester で RSocket サービスを呼び出す

サーバーとクライアントの間に RSocket チャネルが確立されると、どのパーティも相手とリクエストを送受信できます。

サーバーとして、RSocket @Controller の任意のハンドラーメソッドで RSocketRequester インスタンスをインジェクトできます。クライアントとして、最初に RSocket 接続を設定および確立する必要があります。Spring Boot は、予想されるコーデックでこのような場合に RSocketRequester.Builder を自動構成します。

RSocketRequester.Builder インスタンスはプロトタイプ Bean です。つまり、各注入ポイントは新しいインスタンスを提供します。このビルダーはステートフルであり、同じインスタンスを使用して異なる設定でリクエスターを作成しないでくださいため、これは意図的に行われます。

次のコードは典型的な例を示しています。

@Service
public class MyService {

    private final Mono<RSocketRequester> rsocketRequester;

    public MyService(RSocketRequester.Builder rsocketRequesterBuilder) {
        this.rsocketRequester = rsocketRequesterBuilder
                .connectTcp("example.org", 9898).cache();
    }

    public Mono<User> someRSocketCall(String name) {
        return this.rsocketRequester.flatMap(req ->
                    req.route("user").data(name).retrieveMono(User.class));
    }

}

10. セキュリティ

Spring Security がクラスパスにある場合、Web アプリケーションはデフォルトで保護されます。Spring Boot は、Spring Security のコンテンツネゴシエーション戦略に基づいて、httpBasic と formLogin のどちらを使用するかを決定します。メソッドレベルのセキュリティを Web アプリケーションに追加するために、必要な設定で @EnableGlobalMethodSecurity を追加することもできます。追加情報は Spring Security リファレンスガイドにあります。

デフォルトの UserDetailsService には単一のユーザーがいます。ユーザー名は user であり、パスワードはランダムであり、次の例に示すように、アプリケーションの起動時に INFO レベルで出力されます。

Using generated security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35
ロギング構成を微調整する場合は、org.springframework.boot.autoconfigure.security カテゴリが INFO -level メッセージを記録するように設定されていることを確認してください。それ以外の場合、デフォルトのパスワードは出力されません。

spring.security.user.name および spring.security.user.password を提供することにより、ユーザー名とパスワードを変更できます。

Web アプリケーションでデフォルトで取得する基本機能は次のとおりです。

  • UserDetailsService (または WebFlux アプリケーションの場合は ReactiveUserDetailsService)メモリ内ストアを持つ Bean と、生成されたパスワードを持つ単一のユーザー(ユーザーのプロパティについては SecurityProperties.User(Javadoc) を参照)。

  • アプリケーション全体(アクチュエーターがクラスパス上にある場合はアクチュエーターエンドポイントを含む)に対するフォームベースのログインまたは HTTP Basic セキュリティ(リクエストの Accept ヘッダーに依存)。

  • 認証イベントを公開するための DefaultAuthenticationEventPublisher

Bean を追加することにより、異なる AuthenticationEventPublisher を提供できます。

10.1. MVC セキュリティ

デフォルトのセキュリティ構成は、SecurityAutoConfiguration および UserDetailsServiceAutoConfiguration に実装されています。SecurityAutoConfiguration は Web セキュリティ用に SpringBootWebSecurityConfiguration をインポートし、UserDetailsServiceAutoConfiguration は認証を構成します。これは非 Web アプリケーションにも関連します。デフォルトの Web アプリケーションセキュリティ設定を完全にオフにするには、または OAuth 2 クライアントやリソースサーバーなどの複数の Spring Security コンポーネントを組み合わせるには、タイプ WebSecurityConfigurerAdapter の Bean を追加します(これにより、UserDetailsService 構成またはアクチュエーターのセキュリティが無効になりません)。

UserDetailsService 構成もオフにするには、タイプ UserDetailsServiceAuthenticationProvider または AuthenticationManager の Bean を追加できます。

カスタム WebSecurityConfigurerAdapter を追加することにより、アクセスルールをオーバーライドできます。Spring Boot は、アクチュエーターエンドポイントおよび静的リソースのアクセスルールをオーバーライドするために使用できる便利なメソッドを提供します。EndpointRequest を使用して、management.endpoints.web.base-path プロパティに基づく RequestMatcher を作成できます。PathRequest を使用して、一般的に使用される場所のリソース用の RequestMatcher を作成できます。

10.2. WebFlux セキュリティ

Spring MVC アプリケーションと同様に、spring-boot-starter-security 依存関係を追加することにより、WebFlux アプリケーションを保護できます。デフォルトのセキュリティ構成は、ReactiveSecurityAutoConfiguration および UserDetailsServiceAutoConfiguration に実装されています。ReactiveSecurityAutoConfiguration は Web セキュリティのために WebFluxSecurityConfiguration をインポートし、UserDetailsServiceAutoConfiguration は認証を構成します。これは非 Web アプリケーションにも関連します。デフォルトの Web アプリケーションセキュリティ設定を完全にオフにするには、タイプ WebFilterChainProxy の Bean を追加できます(これにより、UserDetailsService 設定またはアクチュエーターのセキュリティが無効になりません)。

UserDetailsService 構成もオフにするには、タイプ ReactiveUserDetailsService または ReactiveAuthenticationManager の Bean を追加できます。

カスタム SecurityWebFilterChain Bean を追加することにより、アクセスルールと、OAuth 2 クライアントやリソースサーバーなどの複数の Spring Security コンポーネントの使用を構成できます。Spring Boot は、アクチュエーターエンドポイントおよび静的リソースのアクセスルールをオーバーライドするために使用できる便利なメソッドを提供します。EndpointRequest を使用して、management.endpoints.web.base-path プロパティに基づく ServerWebExchangeMatcher を作成できます。

PathRequest を使用して、一般的に使用される場所のリソース用の ServerWebExchangeMatcher を作成できます。

例:次のようなものを追加して、セキュリティ構成をカスタマイズできます。

@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    return http
        .authorizeExchange()
            .matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
            .pathMatchers("/foo", "/bar")
                .authenticated().and()
            .formLogin().and()
        .build();
}

10.3. OAuth2

OAuth2 (英語) は、Spring でサポートされている広く使用されている認可フレームワークです。

10.3.1. クライアント

クラスパスに spring-security-oauth2-client がある場合、いくつかの自動構成を利用して OAuth2/Open ID Connect クライアントを設定できます。この構成では、OAuth2ClientProperties のプロパティを使用します。同じプロパティが、サーブレットアプリケーションとリアクティブアプリケーションの両方に適用されます。

次の例に示すように、spring.security.oauth2.client プレフィックスに複数の OAuth2 クライアントとプロバイダーを登録できます。

spring.security.oauth2.client.registration.my-client-1.client-id=abcd
spring.security.oauth2.client.registration.my-client-1.client-secret=password
spring.security.oauth2.client.registration.my-client-1.client-name=Client for user scope
spring.security.oauth2.client.registration.my-client-1.provider=my-oauth-provider
spring.security.oauth2.client.registration.my-client-1.scope=user
spring.security.oauth2.client.registration.my-client-1.redirect-uri=https://my-redirect-uri.com
spring.security.oauth2.client.registration.my-client-1.client-authentication-method=basic
spring.security.oauth2.client.registration.my-client-1.authorization-grant-type=authorization_code

spring.security.oauth2.client.registration.my-client-2.client-id=abcd
spring.security.oauth2.client.registration.my-client-2.client-secret=password
spring.security.oauth2.client.registration.my-client-2.client-name=Client for email scope
spring.security.oauth2.client.registration.my-client-2.provider=my-oauth-provider
spring.security.oauth2.client.registration.my-client-2.scope=email
spring.security.oauth2.client.registration.my-client-2.redirect-uri=https://my-redirect-uri.com
spring.security.oauth2.client.registration.my-client-2.client-authentication-method=basic
spring.security.oauth2.client.registration.my-client-2.authorization-grant-type=authorization_code

spring.security.oauth2.client.provider.my-oauth-provider.authorization-uri=https://my-auth-server/oauth/authorize
spring.security.oauth2.client.provider.my-oauth-provider.token-uri=https://my-auth-server/oauth/token
spring.security.oauth2.client.provider.my-oauth-provider.user-info-uri=https://my-auth-server/userinfo
spring.security.oauth2.client.provider.my-oauth-provider.user-info-authentication-method=header
spring.security.oauth2.client.provider.my-oauth-provider.jwk-set-uri=https://my-auth-server/token_keys
spring.security.oauth2.client.provider.my-oauth-provider.user-name-attribute=name

OpenID Connect ディスカバリ (英語) をサポートする OpenID Connect プロバイダーの場合、構成をさらに簡素化できます。プロバイダーは、発行者 ID としてアサートする URI である issuer-uri で構成する必要があります。例:提供された issuer-uri が「https://example.com」の場合、OpenID Provider Configuration Request は「https://example.com/.well-known/openid-configuration」になります。結果は OpenID Provider Configuration Response になると予想されます。次の例は、issuer-uri を使用して OpenID Connect プロバイダーを構成する方法を示しています。

spring.security.oauth2.client.provider.oidc-provider.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/

デフォルトでは、Spring Security の OAuth2LoginAuthenticationFilter は /login/oauth2/code/* に一致する URL のみを処理します。redirect-uri をカスタマイズして別のパターンを使用する場合は、そのカスタムパターンを処理するための構成を提供する必要があります。例:サーブレットアプリケーションの場合、次のような独自の WebSecurityConfigurerAdapter を追加できます。

public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .oauth2Login()
                .redirectionEndpoint()
                    .baseUri("/custom-callback");
    }
}
一般的なプロバイダーの OAuth2 クライアント登録

Google、Github、Facebook、および Okta を含む一般的な OAuth2 および OpenID プロバイダーには、一連のプロバイダーのデフォルト(それぞれ googlegithubfacebook および okta)を提供します。

これらのプロバイダーをカスタマイズする必要がない場合は、provider 属性をデフォルトを推測する必要がある属性に設定できます。また、クライアント登録のキーがデフォルトでサポートされているプロバイダーと一致する場合、Spring Boot も同様に推測します。

つまり、次の例の 2 つの構成では、Google プロバイダーを使用しています。

spring.security.oauth2.client.registration.my-client.client-id=abcd
spring.security.oauth2.client.registration.my-client.client-secret=password
spring.security.oauth2.client.registration.my-client.provider=google

spring.security.oauth2.client.registration.google.client-id=abcd
spring.security.oauth2.client.registration.google.client-secret=password

10.3.2. リソースサーバー

クラスパスに spring-security-oauth2-resource-server がある場合、Spring Boot は OAuth2 リソースサーバーをセットアップできます。JWT 構成の場合、次の例に示すように、JWK セット URI または OIDC 発行者 URI を指定する必要があります。

spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://example.com/oauth2/default/v1/keys
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/
認可サーバーが JWK Set URI をサポートしていない場合、JWT の署名の検証に使用される公開鍵でリソースサーバーを構成できます。これは、spring.security.oauth2.resourceserver.jwt.public-key-location プロパティを使用して実行できます。値は、PEM エンコードされた x509 形式の公開キーを含むファイルを指す必要があります。

同じプロパティは、サーブレットアプリケーションとリアクティブアプリケーションの両方に適用できます。

または、サーブレットアプリケーション用に独自の JwtDecoder Bean を定義するか、リアクティブアプリケーション用に ReactiveJwtDecoder を定義できます。

JWT の代わりに Opaque トークンが使用される場合、次のプロパティを設定して、イントロスペクションを介してトークンを検証できます。

spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://example.com/check-token
spring.security.oauth2.resourceserver.opaquetoken.client-id=my-client-id
spring.security.oauth2.resourceserver.opaquetoken.client-secret=my-client-secret

繰り返しますが、同じプロパティがサーブレットとリアクティブの両方のアプリケーションに適用可能です。

または、サーブレットアプリケーション用に独自の OpaqueTokenIntrospector Bean を定義するか、リアクティブアプリケーション用に ReactiveOpaqueTokenIntrospector を定義できます。

10.3.3. 認可サーバー

現在、Spring Security は OAuth 2.0 認可サーバーの実装をサポートしていません。ただし、この機能は Spring Security OAuth プロジェクトから利用でき、最終的には Spring Security に完全に置き換えられます。それまでは、spring-security-oauth2-autoconfigure モジュールを使用して、OAuth 2.0 認可サーバーを簡単にセットアップできます。手順については、ドキュメント (英語) を参照してください。

10.4. SAML 2.0

10.4.1. 証明書利用者

クラスパスに spring-security-saml2-service-provider がある場合は、自動構成を利用して SAML 2.0 依存パーティをセットアップできます。この構成では、Saml2RelyingPartyProperties のプロパティを使用します。

証明書利用者登録は、ID プロバイダー IDP とサービスプロバイダー SP の間のペア構成を表します。次の例に示すように、spring.security.saml2.relyingparty プレフィックスに複数の証明書利用者を登録できます。

spring.security.saml2.relyingparty.registration.my-relying-party1.signing.credentials[0].private-key-location=path-to-private-key
spring.security.saml2.relyingparty.registration.my-relying-party1.signing.credentials[0].certificate-location=path-to-certificate
spring.security.saml2.relyingparty.registration.my-relying-party1.identityprovider.verification.credentials[0].certificate-location=path-to-verification-cert
spring.security.saml2.relyingparty.registration.my-relying-party1.identityprovider.entity-id=remote-idp-entity-id1
spring.security.saml2.relyingparty.registration.my-relying-party1.identityprovider.sso-url=https://remoteidp1.sso.url

spring.security.saml2.relyingparty.registration.my-relying-party2.signing.credentials[0].private-key-location=path-to-private-key
spring.security.saml2.relyingparty.registration.my-relying-party2.signing.credentials[0].certificate-location=path-to-certificate
spring.security.saml2.relyingparty.registration.my-relying-party2.identityprovider.verification.credentials[0].certificate-location=path-to-other-verification-cert
spring.security.saml2.relyingparty.registration.my-relying-party2.identityprovider.entity-id=remote-idp-entity-id2
spring.security.saml2.relyingparty.registration.my-relying-party2.identityprovider.sso-url=https://remoteidp2.sso.url

10.5. アクチュエーターのセキュリティ

セキュリティのために、/health および /info 以外のすべてのアクチュエーターはデフォルトで無効になっています。management.endpoints.web.exposure.include プロパティを使用して、アクチュエーターを有効にすることができます。

Spring Security がクラスパス上にあり、他の WebSecurityConfigurerAdapter が存在しない場合、/health および /info 以外のすべてのアクチュエーターは、Spring Boot 自動構成によって保護されます。カスタム WebSecurityConfigurerAdapter を定義すると、Spring Boot の自動構成がバックオフし、アクチュエーターアクセスルールを完全に制御できるようになります。

management.endpoints.web.exposure.include を設定する前に、露出したアクチュエーターに機密情報が含まれていないこと、および / またはファイアウォールの背後に配置したり、Spring Security のようなもので保護することを確認してください。

10.5.1. クロスサイトリクエストフォージェリ保護

Spring Boot は Spring Security のデフォルトに依存しているため、CSRF 保護はデフォルトでオンになっています。つまり、POST (シャットダウンおよびロガーのエンドポイント)、PUT、または DELETE を必要とするアクチュエーターエンドポイントは、デフォルトのセキュリティ構成が使用されている場合、403 禁止エラーを受け取ります。

非ブラウザクライアントによって使用されるサービスを作成している場合にのみ、CSRF 保護を完全に無効にすることをお勧めします。

CSRF 保護に関する追加情報は、Spring Security リファレンスガイドにあります。

11. SQL データベースでの作業

Spring Framework は、JdbcTemplate を使用した JDBC への直接アクセスから、Hibernate などの「オブジェクトリレーショナルマッピング」テクノロジーの完成まで、SQL データベースの操作に対する広範なサポートを提供します。Spring Data は追加レベルの機能を提供します。Repository 実装をインターフェースから直接作成し、規約を使用してメソッド名からクエリを生成します。

11.1. DataSource を構成する

Java の javax.sql.DataSource インターフェースは、データベース接続を操作する標準的な方法を提供します。伝統的に、「DataSource」は、URL といくつかの資格情報を使用してデータベース接続を確立します。

通常、DataSource の構成を完全に制御するためのより高度な例については、「方法」セクションを参照してください。

11.1.1. 組み込みデータベースのサポート

インメモリ埋め込みデータベースを使用してアプリケーションを開発すると便利な場合がよくあります。明らかに、インメモリデータベースは永続的なストレージを提供しません。アプリケーションの起動時にデータベースにデータを入力し、アプリケーションの終了時にデータを破棄する準備をする必要があります。

「使い方」セクションには、データベースの初期化方法に関するセクションが含まれています。

Spring Boot は、組み込み H2 (英語) HSQL (英語) 、および Derby (Apache) データベースを自動構成できます。接続 URL を提供する必要はありません。使用する組み込みデータベースへのビルド依存関係のみを含める必要があります。

テストでこの機能を使用している場合、使用するアプリケーションコンテキストの数に関係なく、テストスイート全体で同じデータベースが再利用されることに気付く場合があります。各コンテキストに個別の組み込みデータベースがあることを確認する場合は、spring.datasource.generate-unique-name を true に設定する必要があります。

例:典型的な POM 依存関係は次のとおりです。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <scope>runtime</scope>
</dependency>
組み込みデータベースを自動構成するには、spring-jdbc に依存する必要があります。この例では、spring-boot-starter-data-jpa を介して推移的にプルされます。
何らかの理由で埋め込みデータベースの接続 URL を構成する場合は、データベースの自動シャットダウンが無効になっていることを確認してください。H2 を使用する場合は、DB_CLOSE_ON_EXIT=FALSE を使用する必要があります。HSQLDB を使用する場合は、shutdown=true が使用されていないことを確認する必要があります。データベースの自動シャットダウンを無効にすると、Spring Boot がデータベースを閉じるタイミングを制御できるため、データベースへのアクセスが不要になったときに確実に実行されます。

11.1.2. 本番データベースへの接続

本番データベース接続は、プーリング DataSource を使用して自動構成することもできます。Spring Boot は、特定の実装を選択するために次のアルゴリズムを使用します。

  1. パフォーマンスと同時実行性の点から、HikariCP (GitHub) をお勧めします。HikariCP が使用可能な場合、常に選択します。

  2. それ以外の場合、Tomcat プーリング DataSource が利用可能であれば、それを使用します。

  3. HikariCP も Tomcat プーリングデータソースも使用できず、Commons DBCP2 (Apache) が使用可能な場合は、それを使用します。

spring-boot-starter-jdbc または spring-boot-starter-data-jpa の「スターター」を使用する場合、HikariCP への依存関係が自動的に取得されます。

spring.datasource.type プロパティを設定することにより、そのアルゴリズムを完全にバイパスし、使用する接続プールを指定できます。tomcat-jdbc はデフォルトで提供されているため、これは Tomcat コンテナーでアプリケーションを実行する場合に特に重要です。
追加の接続プールは、常に手動で構成できます。独自の DataSource Bean を定義すると、自動構成は行われません。

DataSource 構成は、spring.datasource.* の外部構成プロパティによって制御されます。例: application.properties で次のセクションを宣言できます。

spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url プロパティを設定して、少なくとも URL を指定する必要があります。そうでない場合、Spring Boot は組み込みデータベースの自動構成を試みます。
Spring Boot は url からほとんどのデータベースについて推測できるため、多くの場合、driver-class-name を指定する必要はありません。
プーリング DataSource を作成するには、有効な Driver クラスが利用可能であることを確認できる必要があるため、何かを行う前にそれを確認します。つまり、spring.datasource.driver-class-name=com.mysql.jdbc.Driver を設定する場合、そのクラスはロード可能でなければなりません。

サポートされるオプションの詳細については、DataSourceProperties (GitHub) を参照してください。これらは、実際の実装に関係なく機能する標準オプションです。それぞれの接頭辞(spring.datasource.hikari.*spring.datasource.tomcat.*、および spring.datasource.dbcp2.*)を使用して、実装固有の設定を微調整することもできます。詳細については、使用している接続プール実装のドキュメントを参照してください。

たとえば、Tomcat 接続プール (Apache) を使用する場合、次の例に示すように、多くの追加設定をカスタマイズできます。

# Number of ms to wait before throwing an exception if no connection is available.
spring.datasource.tomcat.max-wait=10000

# Maximum number of active connections that can be allocated from this pool at the same time.
spring.datasource.tomcat.max-active=50

# Validate the connection before borrowing it from the pool.
spring.datasource.tomcat.test-on-borrow=true

11.1.3. JNDI DataSource への接続

Spring Boot アプリケーションをアプリケーションサーバーにデプロイする場合、アプリケーションサーバーの組み込み機能を使用して DataSource を構成および管理し、JNDI を使用してそれにアクセスすることができます。

spring.datasource.jndi-name プロパティは、特定の JNDI ロケーションから DataSource にアクセスするための spring.datasource.urlspring.datasource.username および spring.datasource.password プロパティの代替として使用できます。例: application.properties の次のセクションは、JBoss AS で定義された DataSource にアクセスする方法を示しています。

spring.datasource.jndi-name=java:jboss/datasources/customers

11.2. JdbcTemplate を使用する

Spring の JdbcTemplate および NamedParameterJdbcTemplate クラスは自動構成されており、次の例に示すように、独自の Bean に直接 @Autowire できます。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public MyBean(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    // ...

}

次の例に示すように、spring.jdbc.template.* プロパティを使用して、テンプレートの一部のプロパティをカスタマイズできます。

spring.jdbc.template.max-rows=500
NamedParameterJdbcTemplate は、バックグラウンドで同じ JdbcTemplate インスタンスを再利用します。複数の JdbcTemplate が定義されていて、1 次候補が存在しない場合、NamedParameterJdbcTemplate は自動構成されません。

11.3. JPA および Spring Data JPA

Java Persistence API は、オブジェクトをリレーショナルデータベースに「マップ」できる標準テクノロジーです。spring-boot-starter-data-jpa POM を使用すると、簡単に開始できます。以下の重要な依存関係を提供します。

  • Hibernate: 最も一般的な JPA 実装の 1 つ。

  • Spring Data JPA: JPA ベースのリポジトリの実装に役立ちます。

  • Spring ORM: Spring Framework からのコア ORM サポート。

ここでは、JPA または Spring Data の詳細については詳しく説明しません。spring.io“JPA でデータアクセス ” ガイドに従い、Spring Data JPA および Hibernate (英語) のリファレンスドキュメントを読むことができます。

11.3.1. エンティティクラス

従来、JPA「エンティティ」クラスは persistence.xml ファイルで指定されていました。Spring Boot では、このファイルは不要であり、代わりに「エンティティスキャン」が使用されます。デフォルトでは、メイン構成クラス(@EnableAutoConfiguration または @SpringBootApplication でアノテーションが付けられたもの)のすべてのパッケージが検索されます。

@Entity@Embeddable または @MappedSuperclass のアノテーションが付けられたクラスが考慮されます。典型的なエンティティクラスは、次の例のようになります。

package com.example.myapp.domain;

import java.io.Serializable;
import javax.persistence.*;

@Entity
public class City implements Serializable {

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String state;

    // ... additional members, often include @OneToMany mappings

    protected City() {
        // no-args constructor required by JPA spec
        // this one is protected since it shouldn't be used directly
    }

    public City(String name, String state) {
        this.name = name;
        this.state = state;
    }

    public String getName() {
        return this.name;
    }

    public String getState() {
        return this.state;
    }

    // ... etc

}
@EntityScan アノテーションを使用して、エンティティスキャンの場所をカスタマイズできます。「howto.html」使い方を参照してください。

11.3.2. Spring Data JPA リポジトリ

Spring Data JPA リポジトリは、データにアクセスするために定義できるインターフェースです。JPA クエリは、メソッド名から自動的に作成されます。例: CityRepository インターフェースは、特定の状態のすべての都市を見つけるために findAllByState(String state) メソッドを宣言する場合があります。

より複雑なクエリの場合、Spring Data の Query(Javadoc) アノテーションでメソッドにアノテーションを付けることができます。

Spring Data リポジトリは通常、Repository(Javadoc) または CrudRepository(Javadoc) インターフェースから拡張されます。自動構成を使用する場合、リポジトリはメイン構成クラス(@EnableAutoConfiguration または @SpringBootApplication でアノテーションが付けられたもの)を含むパッケージから検索されます。

次の例は、典型的な Spring Data リポジトリインターフェース定義を示しています。

package com.example.myapp.domain;

import org.springframework.data.domain.*;
import org.springframework.data.repository.*;

public interface CityRepository extends Repository<City, Long> {

    Page<City> findAll(Pageable pageable);

    City findByNameAndStateAllIgnoringCase(String name, String state);

}

Spring Data JPA リポジトリは、3 つの異なるブートストラップモードをサポートしています:デフォルト、遅延、およびレイジー。遅延または遅延ブートストラップを有効にするには、spring.data.jpa.repositories.bootstrap-mode プロパティをそれぞれ deferred または lazy に設定します。遅延または遅延ブートストラップを使用する場合、自動構成された EntityManagerFactoryBuilder は、コンテキストの AsyncTaskExecutor をブートストラップエグゼキューターとして使用します(存在する場合)。複数存在する場合は、applicationTaskExecutor という名前が使用されます。

Spring Data JPA に関して、ほんの少し触れただけです。詳細については、Spring Data JPA リファレンスドキュメントを参照してください。

11.3.3. JPA データベースの作成と削除

デフォルトでは、組み込みデータベース(H2、HSQL、または Derby)を使用する場合にのみ、JPA データベースが自動的に作成されます。spring.jpa.* プロパティを使用して、JPA 設定を明示的に構成できます。例:テーブルを作成および削除するには、次の行を application.properties に追加します。

spring.jpa.hibernate.ddl-auto=create-drop
Hibernate の独自の内部プロパティ名(覚えている場合)は hibernate.hbm2ddl.auto です。spring.jpa.properties.* を使用して、他の Hibernate ネイティブプロパティとともに設定できます(プレフィックスは、エンティティマネージャーに追加する前に削除されます)。次の行は、Hibernate の JPA プロパティの設定例を示しています。
spring.jpa.properties.hibernate.globally_quoted_identifiers=true

上記の例の行は、hibernate.globally_quoted_identifiers プロパティの true の値を Hibernate エンティティマネージャーに渡します。

デフォルトでは、ApplicationContext が開始されるまで、DDL の実行(または検証)は延期されます。spring.jpa.generate-ddl フラグもありますが、ddl-auto 設定がよりきめ細かいため、Hibernate 自動構成がアクティブな場合は使用されません。

11.3.4. Open EntityManager in View

Web アプリケーションを実行している場合、Spring Boot はデフォルトで OpenEntityManagerInViewInterceptor(Javadoc) を登録して「Open EntityManager in View」パターンを適用し、Web ビューでの遅延読み込みを可能にします。この動作が望ましくない場合は、application.properties で spring.jpa.open-in-view を false に設定する必要があります。

11.4. Spring Data JDBC

Spring Data には JDBC のリポジトリサポートが含まれており、CrudRepository のメソッドの SQL を自動的に生成します。より高度なクエリのために、@Query アノテーションが提供されています。

Spring Boot は、必要な依存関係がクラスパスにある場合、Spring Data の JDBC リポジトリを自動構成します。spring-boot-starter-data-jdbc への単一の依存関係でプロジェクトに追加できます。必要に応じて、@EnableJdbcRepositories アノテーションまたは JdbcConfiguration サブクラスをアプリケーションに追加して、Spring Data JDBC の構成を制御できます。

Spring Data JDBC の詳細については、リファレンスドキュメントを参照してください。

11.5. H2 の Web コンソールを使用する

H2 データベース (英語) は、Spring Boot が自動構成できるブラウザーベースのコンソール (英語) を提供します。コンソールは、次の条件が満たされると自動構成されます。

  • サーブレットベースの Web アプリケーションを開発しています。

  • com.h2database:h2 はクラスパス上にあります。

  • Spring Boot の開発者ツールを使用しています。

Spring Boot の開発者ツールを使用していないが、H2 のコンソールを引き続き使用したい場合は、spring.h2.console.enabled プロパティを true の値で構成できます。
H2 コンソールは開発中の使用のみを目的としているため、spring.h2.console.enabled が本番環境で true に設定されないように注意する必要があります。

11.5.1. H2 コンソールのパスを変更する

デフォルトでは、コンソールは /h2-console で使用可能です。spring.h2.console.path プロパティを使用して、コンソールのパスをカスタマイズできます。

11.6. jOOQ を使用する

jOOQ オブジェクト指向クエリ(jOOQ (英語) )は、データベースから Java コードを生成し、その流れるような API を介してタイプセーフな SQL クエリを作成できる Data Geekery (英語) の人気製品です。Spring Boot では、有償版とオープンソース版の両方を使用できます。

11.6.1. コード生成

jOOQ タイプセーフクエリを使用するには、データベーススキーマから Java クラスを生成する必要があります。jOOQ ユーザーマニュアル (英語) の指示に従うことができます。jooq-codegen-maven プラグインを使用し、spring-boot-starter-parent 「親 POM」も使用する場合、プラグインの <version> タグを安全に省略できます。Spring ブート定義バージョン変数(h2.version など)を使用して、プラグインのデータベース依存関係を宣言することもできます。次のリストに例を示します。

<plugin>
    <groupId>org.jooq</groupId>
    <artifactId>jooq-codegen-maven</artifactId>
    <executions>
        ...
    </executions>
    <dependencies>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>${h2.version}</version>
        </dependency>
    </dependencies>
    <configuration>
        <jdbc>
            <driver>org.h2.Driver</driver>
            <url>jdbc:h2:~/yourdatabase</url>
        </jdbc>
        <generator>
            ...
        </generator>
    </configuration>
</plugin>

11.6.2. DSLContext を使用する

jOOQ が提供する流れるような API は、org.jooq.DSLContext インターフェースを介して開始されます。Spring Boot は、DSLContext を Spring Bean として自動構成し、それをアプリケーション DataSource に接続します。DSLContext を使用するには、次の例に示すように、@Autowire を使用できます。

@Component
public class JooqExample implements CommandLineRunner {

    private final DSLContext create;

    @Autowired
    public JooqExample(DSLContext dslContext) {
        this.create = dslContext;
    }

}
jOOQ マニュアルでは、create という名前の変数を使用して DSLContext を保持する傾向があります。

その後、次の例に示すように、DSLContext を使用してクエリを作成できます。

public List<GregorianCalendar> authorsBornAfter1980() {
    return this.create.selectFrom(AUTHOR)
        .where(AUTHOR.DATE_OF_BIRTH.greaterThan(new GregorianCalendar(1980, 0, 1)))
        .fetch(AUTHOR.DATE_OF_BIRTH);
}

11.6.3. jOOQ SQL ダイアレクト

spring.jooq.sql-dialect プロパティが設定されていない限り、Spring Boot はデータソースに使用する SQL ダイアレクトを決定します。Spring Boot がダイアレクトを検出できなかった場合、DEFAULT を使用します。

Spring Boot は、jOOQ のオープンソースバージョンでサポートされているダイアレクトのみを自動構成できます。

11.6.4. jOOQ のカスタマイズ

jOOQ Configuration の作成時に使用される独自の @Bean 定義を定義することにより、より高度なカスタマイズを実現できます。次の jOOQ タイプの Bean を定義できます。

  • ConnectionProvider

  • ExecutorProvider

  • TransactionProvider

  • RecordMapperProvider

  • RecordUnmapperProvider

  • Settings

  • RecordListenerProvider

  • ExecuteListenerProvider

  • VisitListenerProvider

  • TransactionListenerProvider

jOOQ 構成を完全に制御したい場合は、独自の org.jooq.Configuration@Bean を作成することもできます。

11.7. R2DBC を使用する

リアクティブリレーショナルデータベースコネクティビティ(R2DBC (英語) )プロジェクトは、リアクティブプログラミング API をリレーショナルデータベースにもたらします。R2DBC の io.r2dbc.spi.Connection は、ノンブロッキングデータベース接続を操作する標準的な方法を提供します。接続は、jdbc を使用した DataSource と同様に、ConnectionFactory を介して提供されます。

ConnectionFactory 構成は、spring.r2dbc.* の外部構成プロパティによって制御されます。例: application.properties で次のセクションを宣言できます。

spring.r2dbc.url=r2dbc:postgresql://localhost/test
spring.r2dbc.username=dbuser
spring.r2dbc.password=dbpass
Spring Boot は R2DBC の接続ファクトリディスカバリからドライバーを取得するため、ドライバークラス名を指定する必要はありません。
少なくとも URL を指定する必要があります。URL で指定された情報は、個々のプロパティ、つまり nameusernamepassword およびプーリングオプションよりも優先されます。
「使い方」セクションには、データベースの初期化方法に関するセクションが含まれています。

ConnectionFactory によって作成された接続をカスタマイズするには、つまり、中央データベース構成で構成しない(または構成できない)特定のパラメーターを設定するには、ConnectionFactoryOptionsBuilderCustomizer@Bean を使用できます。次の例は、データベースポートを手動でオーバーライドし、残りのオプションをアプリケーション構成から取得する方法を示しています。

@Bean
public ConnectionFactoryOptionsBuilderCustomizer connectionFactoryPortCustomizer() {
    return (builder) -> builder.option(PORT, 5432);
}

次の例は、いくつかの PostgreSQL 接続オプションを設定する方法を示しています。

@Bean
public ConnectionFactoryOptionsBuilderCustomizer postgresCustomizer() {
    Map<String, String> options = new HashMap<>();
    options.put("lock_timeout", "30s");
    options.put("statement_timeout", "60s");
    return (builder) -> builder.option(OPTIONS, options);
}

ConnectionFactory Bean が使用可能な場合、通常の JDBC DataSource 自動構成がバックオフします。JDBC DataSource 自動構成を保持する必要があり、リアクティブアプリケーションでブロッキング JDBC API を使用するリスクに満足している場合は、アプリケーションの @Configuration クラスに @Import(DataSourceAutoConfiguration.class) を追加して再度有効にします。

11.7.1. 組み込みデータベースのサポート

JDBC サポートと同様に、Spring Boot はリアクティブ使用のために組み込みデータベースを自動的に構成できます。接続 URL を提供する必要はありません。次の例に示すように、使用する組み込みデータベースへのビルド依存関係のみを含める必要があります。

<dependency>
    <groupId>io.r2dbc</groupId>
    <artifactId>r2dbc-h2</artifactId>
    <scope>runtime</scope>
</dependency>

テストでこの機能を使用している場合、使用するアプリケーションコンテキストの数に関係なく、テストスイート全体で同じデータベースが再利用されることに気付く場合があります。各コンテキストに個別の組み込みデータベースがあることを確認する場合は、spring.r2dbc.generate-unique-name を true に設定する必要があります。

11.7.2. DatabaseClient を使用する

Spring Data の DatabaseClient クラスは自動構成されており、次の例に示すように、独自の Bean に直接 @Autowire できます。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.r2dbc.function.DatabaseClient;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final DatabaseClient databaseClient;

    @Autowired
    public MyBean(DatabaseClient databaseClient) {
        this.databaseClient = databaseClient;
    }

    // ...

}

11.7.3. Spring Data R2DBC リポジトリ

Spring Data R2DBC リポジトリは、データにアクセスするために定義できるインターフェースです。クエリはメソッド名から自動的に作成されます。例: CityRepository インターフェースは、特定の状態のすべての都市を見つけるために findAllByState(String state) メソッドを宣言できます。

より複雑なクエリの場合、Spring Data の Query(Javadoc) アノテーションでメソッドにアノテーションを付けることができます。

Spring Data リポジトリは通常、Repository(Javadoc) または CrudRepository(Javadoc) インターフェースから拡張されます。自動構成を使用する場合、リポジトリはメイン構成クラス(@EnableAutoConfiguration または @SpringBootApplication でアノテーションが付けられたもの)を含むパッケージから検索されます。

次の例は、典型的な Spring Data リポジトリインターフェース定義を示しています。

package com.example.myapp.domain;

import org.springframework.data.domain.*;
import org.springframework.data.repository.*;
import reactor.core.publisher.Mono;

public interface CityRepository extends Repository<City, Long> {

    Mono<City> findByNameAndStateAllIgnoringCase(String name, String state);

}
Spring Data R2DBC の表面にはほとんど傷がありません。詳細については、Spring Data R2DBC リファレンスドキュメントを参照してください。

12. NoSQL テクノロジーの使用

Spring Data は、次のようなさまざまな NoSQL テクノロジーへのアクセスに役立つ追加プロジェクトを提供します。

Spring Boot は、Redis、MongoDB、Neo4j、Elasticsearch、Solr Cassandra、Couchbase、および LDAP の自動構成を提供します。他のプロジェクトを利用することもできますが、自分で構成する必要があります。spring.io/projects/spring-data の適切なリファレンスドキュメントを参照してください。

12.1. Redis

Redis (英語) は、キャッシュ、メッセージブローカー、および豊富な機能を備えたキーと値のストアです。Spring Boot は、Lettuce (GitHub) および Jedis (GitHub) クライアントライブラリの基本的な自動構成と、Spring Data Redis (GitHub) が提供する抽象化を提供します。

依存関係を便利な方法で収集するための spring-boot-starter-data-redis 「スターター」があります。デフォルトでは、Lettuce (GitHub) を使用します。そのスターターは、従来のアプリケーションとリアクティブアプリケーションの両方を処理します。

また、リアクティブをサポートする他のストアとの一貫性を保つために、spring-boot-starter-data-redis-reactive 「スターター」も提供しています。

12.1.1. Redis への接続

他の Spring Bean と同様に、自動構成された RedisConnectionFactoryStringRedisTemplate またはバニラ RedisTemplate インスタンスを注入できます。デフォルトでは、インスタンスは localhost:6379 で Redis サーバーへの接続を試みます。次のリストは、そのような Bean の例を示しています。

@Component
public class MyBean {

    private StringRedisTemplate template;

    @Autowired
    public MyBean(StringRedisTemplate template) {
        this.template = template;
    }

    // ...

}
より高度なカスタマイズのために、LettuceClientConfigurationBuilderCustomizer を実装する任意の数の Bean を登録することもできます。Jedis を使用する場合は、JedisClientConfigurationBuilderCustomizer も利用できます。

自動構成タイプのいずれかの独自の @Bean を追加すると、デフォルトが置き換えられます(RedisTemplate の場合を除き、除外がそのタイプではなく Bean 名 redisTemplate に基づいている場合)。デフォルトでは、commons-pool2 がクラスパス上にある場合、プールされた接続ファクトリを取得します。

12.2. MongoDB

MongoDB (英語) は、従来のテーブルベースのリレーショナルデータの代わりに JSON のようなスキーマを使用するオープンソースの NoSQL ドキュメントデータベースです。Spring Boot は、spring-boot-starter-data-mongodb および spring-boot-starter-data-mongodb-reactive 「スターター」など、MongoDB を操作するためのいくつかの便利な機能を提供します。

12.2.1. MongoDB データベースへの接続

MongoDB データベースにアクセスするために、自動構成された org.springframework.data.mongodb.MongoDatabaseFactory を注入できます。デフォルトでは、インスタンスは mongodb://localhost/test で MongoDB サーバーへの接続を試みます。次の例は、MongoDB データベースに接続する方法を示しています。

import org.springframework.data.mongodb.MongoDatabaseFactory;
import com.mongodb.client.MongoDatabase;

@Component
public class MyBean {

    private final MongoDatabaseFactory mongo;

    @Autowired
    public MyBean(MongoDatabaseFactory mongo) {
        this.mongo = mongo;
    }

    // ...

    public void example() {
        MongoDatabase db = mongo.getMongoDatabase();
        // ...
    }

}

次の例に示すように、spring.data.mongodb.uri プロパティを設定して URL を変更し、レプリカセットなどの追加設定を構成できます。

spring.data.mongodb.uri=mongodb://user:[email protected] (英語)  :12345,mongo2.example.com:23456/test

または、個別のプロパティを使用して接続の詳細を指定できます。例: application.properties で次の設定を宣言できます。

spring.data.mongodb.host=mongoserver.example.com
spring.data.mongodb.port=27017
spring.data.mongodb.database=test
spring.data.mongodb.username=user
spring.data.mongodb.password=secret

独自の MongoClient を定義している場合、それを使用して適切な MongoDatabaseFactory を自動構成します。

自動構成された MongoClient は、MongoClientSettings を使用して作成されます。構成を微調整するには、1 つ以上の MongoClientSettingsBuilderCustomizer Bean を宣言します。MongoClientSettings をビルドするために使用される MongoClientSettings.Builder で順番に呼び出されます。

spring.data.mongodb.port が指定されていない場合、デフォルトの 27017 が使用されます。前に示した例からこの行を削除できます。
Spring Data MongoDB を使用しない場合は、MongoDatabaseFactory を使用する代わりに MongoClient Bean を注入できます。MongoDB 接続の確立を完全に制御したい場合は、独自の MongoDatabaseFactory または MongoClient Bean を宣言することもできます。
リアクティブドライバーを使用している場合、SSL には Netty が必要です。Netty が使用可能で、使用するファクトリがまだカスタマイズされていない場合、自動構成によりこのファクトリが自動的に構成されます。

12.2.2. MongoTemplate

Spring Data MongoDB は、その設計が Spring の JdbcTemplate に非常に似ている MongoTemplate (英語) クラスを提供します。JdbcTemplate と同様に、Spring Boot は、次のように、テンプレートをインジェクトするために Bean を自動構成します。

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final MongoTemplate mongoTemplate;

    public MyBean(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    // ...

}

詳細については、MongoOperations Javadoc (英語) を参照してください。

12.2.3. Spring Data MongoDB リポジトリ

Spring Data には、MongoDB のリポジトリサポートが含まれています。前述の JPA リポジトリと同様に、基本的な原則は、クエリがメソッド名に基づいて自動的に構築されることです。

実際、Spring Data JPA と Spring Data MongoDB の両方が同じ共通インフラストラクチャを共有しています。以前の JPA の例を使用できます。City が JPA @Entity ではなく MongoDB データクラスであると仮定すると、次の例に示すように同じように機能します。

package com.example.myapp.domain;

import org.springframework.data.domain.*;
import org.springframework.data.repository.*;

public interface CityRepository extends Repository<City, Long> {

    Page<City> findAll(Pageable pageable);

    City findByNameAndStateAllIgnoringCase(String name, String state);

}
@EntityScan アノテーションを使用して、ドキュメントのスキャン場所をカスタマイズできます。
リッチオブジェクトマッピングテクノロジを含む Spring Data MongoDB の詳細については、リファレンスドキュメントを参照してください

12.2.4. 埋め込み Mongo

Spring Boot は、埋め込み Mongo (GitHub) の自動構成を提供します。Spring Boot アプリケーションで使用するには、de.flapdoodle.embed:de.flapdoodle.embed.mongo に依存関係を追加します。

Mongo が listen するポートは、spring.data.mongodb.port プロパティを設定することにより構成できます。ランダムに割り当てられた空きポートを使用するには、値 0 を使用します。MongoAutoConfiguration によって作成された MongoClient は、ランダムに割り当てられたポートを使用するように自動的に構成されます。

カスタムポートを構成しない場合、組み込みサポートはデフォルトで(27017 ではなく)ランダムポートを使用します。

クラスパスに SLF4J がある場合、Mongo によって生成された出力は、org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongo という名前のロガーに自動的にルーティングされます。

Mongo インスタンスの構成とロギングルーティングを制御するために、独自の IMongodConfig および IRuntimeConfig Bean を宣言できます。ダウンロード構成は、DownloadConfigBuilderCustomizer Bean を宣言することによりカスタマイズできます。

12.3. Neo4j

Neo4j (英語) は、ファーストクラスの関連で接続されたノードのリッチデータモデルを使用するオープンソースの NoSQL グラフデータベースであり、従来の RDBMS アプローチよりも接続されたビッグデータに適しています。Spring Boot は、spring-boot-starter-data-neo4j 「スターター」など、Neo4j での作業にいくつかの便利な機能を提供します。

12.3.1. Neo4j データベースへの接続

Neo4j サーバーにアクセスするために、自動構成された org.neo4j.ogm.session.Session を挿入できます。デフォルトでは、インスタンスは Bolt プロトコルを使用して localhost:7687 で Neo4j サーバーに接続しようとします。次の例は、Neo4j Session を注入する方法を示しています。

@Component
public class MyBean {

    private final Session session;

    @Autowired
    public MyBean(Session session) {
        this.session = session;
    }

    // ...

}

次の例に示すように、spring.data.neo4j.* プロパティを設定することにより、使用する URI および資格情報を構成できます。

spring.data.neo4j.uri=bolt://my-server:7687
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=secret

org.neo4j.ogm.config.Configuration Bean または org.neo4j.ogm.session.SessionFactory Bean を追加することにより、セッションの作成を完全に制御できます。

12.3.2. 埋め込みモードを使用する

org.neo4j:neo4j-ogm-embedded-driver をアプリケーションの依存関係に追加すると、Spring Boot は、アプリケーションのシャットダウン時にデータを保持しない Neo4j のインプロセス埋め込みインスタンスを自動的に構成します。

組み込み Neo4j OGM ドライバーは Neo4j カーネル自体を提供しないため、org.neo4j:neo4j を依存関係として自分で宣言する必要があります。互換性のあるバージョンのリストについては、Neo4j OGM のドキュメントを参照して (英語) ください。

クラスパスに複数のドライバーがある場合、組み込みドライバーは他のドライバーよりも優先されます。spring.data.neo4j.embedded.enabled=false を設定することにより、埋め込みモードを明示的に無効にできます。

データ Neo4j テストは、上記のように組み込みドライバーと Neo4j カーネルがクラスパス上にある場合、組み込み Neo4j インスタンスを自動的に使用します。

構成内のデータベースファイルへのパスを指定することにより、埋め込みモードの永続性を有効にできます。spring.data.neo4j.uri=file://var/tmp/graph.db

12.3.3. ネイティブ型の使用

Neo4j-OGM は、java.time.* のようないくつかのタイプを、String ベースのプロパティまたは Neo4j が提供するネイティブタイプのいずれかにマッピングできます。後方互換性の理由から、Neo4j-OGM のデフォルトは String ベースの表現を使用することです。ネイティブ型を使用するには、org.neo4j:neo4j-ogm-bolt-native-types または org.neo4j:neo4j-ogm-embedded-native-types のいずれかに依存関係を追加し、次の例に示すように spring.data.neo4j.use-native-types プロパティを構成します。

spring.data.neo4j.use-native-types=true

12.3.4. Neo4jSession

デフォルトでは、Web アプリケーションを実行している場合、セッションはリクエストの処理全体のスレッドにバインドされます(つまり、「セッションを表示中に開く」パターンを使用します)。この動作が望ましくない場合は、application.properties ファイルに次の行を追加します。

spring.data.neo4j.open-in-view=false

12.3.5. Spring Data Neo4j リポジトリ

Spring Data には、Neo4j のリポジトリサポートが含まれています。

Spring Data Neo4j は、他の多くの Spring Data モジュールと同様に、Spring Data JPA と共通のインフラストラクチャを共有しています。以前の JPA の例を使用して、City を JPA @Entity ではなく Neo4j OGM @NodeEntity として定義すると、リポジトリの抽象化は次の例に示すように同じように機能します。

package com.example.myapp.domain;

import java.util.Optional;

import org.springframework.data.neo4j.repository.*;

public interface CityRepository extends Neo4jRepository<City, Long> {

    Optional<City> findOneByNameAndState(String name, String state);

}

spring-boot-starter-data-neo4j 「スターター」により、リポジトリのサポートとトランザクション管理が可能になります。@Configuration -bean でそれぞれ @EnableNeo4jRepositories と @EntityScan を使用して、リポジトリとエンティティを探すように場所をカスタマイズできます。

オブジェクトマッピングテクノロジーを含む Spring Data Neo4j の詳細については、リファレンスドキュメントを参照してください (英語)

12.4. Solr

Apache Solr (英語) は検索エンジンです。Spring Boot は、Solr 5 クライアントライブラリの基本的な自動構成と、Spring Data Solr (GitHub) が提供する抽象化を提供します。依存関係を便利な方法で収集するための spring-boot-starter-data-solr 「スターター」があります。

12.4.1. Solr への接続

他の Spring Bean と同様に、自動構成された SolrClient インスタンスを注入できます。デフォルトでは、インスタンスは localhost:8983/solr のサーバーへの接続を試みます。次の例は、Solr Bean を注入する方法を示しています。

@Component
public class MyBean {

    private SolrClient solr;

    @Autowired
    public MyBean(SolrClient solr) {
        this.solr = solr;
    }

    // ...

}

タイプ SolrClient の独自の @Bean を追加すると、デフォルトが置き換えられます。

12.4.2. Spring Data Solr リポジトリ

Spring Data には、Apache Solr のリポジトリサポートが含まれています。前述の JPA リポジトリと同様に、基本的な原則は、クエリがメソッド名に基づいて自動的に構築されることです。

実際、Spring Data JPA Solr と Spring Data Solr は、同じ共通インフラストラクチャを共有しています。以前の JPA の例を使用すると、City が JPA @Entity ではなく @SolrDocument クラスになったと仮定すると、同じように機能します。

IP: Spring Data Solr の詳細については、リファレンスドキュメントを参照してください (英語)

12.5. Elasticsearch

Elasticsearch (英語) は、オープンソースの分散型 RESTREST 検索および分析エンジンです。Spring Boot は、Elasticsearch の基本的な自動構成を提供します。

Spring Boot はいくつかのクライアントをサポートしています:

  • 公式の Java「低レベル」および「高レベル」REST クライアント

  • Spring Data Elasticsearch が提供する ReactiveElasticsearchClient 

Spring Boot は、専用の「スターター」 spring-boot-starter-data-elasticsearch を提供します。

12.5.1. REST クライアントを使用して Elasticsearch に接続する

Elasticsearch には、クラスターのクエリに使用できる「低レベル」クライアントと「高レベル」クライアントの 2 つの異なる REST クライアント (英語) が付属しています。

クラスパスに org.elasticsearch.client:elasticsearch-rest-client 依存関係がある場合、Spring Boot は、デフォルトで localhost:9200 をターゲットとする RestClient Bean を自動構成および登録します。次の例に示すように、RestClient の構成方法をさらに調整できます。

spring.elasticsearch.rest.uris=https://search.example.com:9200
spring.elasticsearch.rest.read-timeout=10s
spring.elasticsearch.rest.username=user
spring.elasticsearch.rest.password=secret

より高度なカスタマイズのために、RestClientBuilderCustomizer を実装する任意の数の Bean を登録することもできます。登録を完全に制御するには、RestClientBuilder Bean を定義します。

クラスパスに org.elasticsearch.client:elasticsearch-rest-high-level-client の依存関係がある場合、Spring Boot は RestHighLevelClient を自動構成します。これにより、既存の RestClientBuilder Bean を利用して、HTTP 構成が再利用されます。

12.5.2. Reactive REST クライアントを使用して Elasticsearch に接続する

Spring Data Elasticsearch は、Elasticsearch インスタンスをリアクティブ方式で照会するために ReactiveElasticsearchClient を提供しています。WebFlux の WebClient の上に構築されているため、spring-boot-starter-elasticsearch と spring-boot-starter-webflux の両方の依存関係がこのサポートを有効にできます。

デフォルトでは、Spring Boot は localhost:9200 をターゲットとする ReactiveElasticsearchClient Bean を自動構成および登録します。次の例に示すように、構成方法をさらに調整できます。

spring.data.elasticsearch.client.reactive.endpoints=search.example.com:9200
spring.data.elasticsearch.client.reactive.use-ssl=true
spring.data.elasticsearch.client.reactive.socket-timeout=10s
spring.data.elasticsearch.client.reactive.username=user
spring.data.elasticsearch.client.reactive.password=secret

構成プロパティが十分ではなく、クライアント構成を完全に制御したい場合は、カスタム ClientConfiguration Bean を登録できます。

12.5.3. Spring Data を使用して Elasticsearch に接続する

Elasticsearch に接続するには、RestHighLevelClient Bean を定義するか、Spring Boot によって自動構成するか、アプリケーションによって手動で提供する必要があります(前のセクションを参照)。この構成を配置すると、次の例に示すように、他の Spring Bean と同様に ElasticsearchRestTemplate を注入できます。

@Component
public class MyBean {

    private final ElasticsearchRestTemplate template;

    public MyBean(ElasticsearchRestTemplate template) {
        this.template = template;
    }

    // ...

}

spring-data-elasticsearch および WebClient (通常 spring-boot-starter-webflux)を使用するために必要な依存関係がある場合、Spring Boot は ReactiveElasticsearchClient および ReactiveElasticsearchTemplate を Bean として自動構成することもできます。これらは、他の REST クライアントに対応するリアクティブ型です。

12.5.4. Spring Data Elasticsearch リポジトリ

Spring Data には、Elasticsearch のリポジトリサポートが含まれています。前述の JPA リポジトリと同様に、基本的な原則は、クエリがメソッド名に基づいて自動的に構築されることです。

実際、Spring Data JPA と Spring Data Elasticsearch の両方が同じ共通インフラストラクチャを共有しています。以前の JPA の例を使用すると、City が JPA @Entity ではなく Elasticsearch @Document クラスであると仮定すると、同じように機能します。

Spring Data Elasticsearch の詳細については、リファレンスドキュメントを参照してください (英語)

Spring Boot は、ElasticsearchRestTemplate または ReactiveElasticsearchTemplate Bean を使用して、クラシックおよびリアクティブの両方の Elasticsearch リポジトリをサポートします。おそらく、これらの Bean は、必要な依存関係が存在する場合、Spring Boot によって自動構成されます。

Elasticsearch リポジトリのバッキングに独自のテンプレートを使用する場合は、"elasticsearchTemplate" という名前である限り、独自の ElasticsearchRestTemplate または ElasticsearchOperations@Bean を追加できます。Bean 名が "reactiveElasticsearchTemplate" の ReactiveElasticsearchTemplate および ReactiveElasticsearchOperations にも同じことが当てはまります。

次のプロパティを使用して、リポジトリのサポートを無効にすることができます。

spring.data.elasticsearch.repositories.enabled=false

12.6. Cassandra

Cassandra (Apache) は、多くのコモディティサーバーで大量のデータを処理するために設計されたオープンソースの分散データベース管理システムです。Spring Boot は、Cassandra の自動構成と、Spring Data Cassandra (GitHub) が提供する抽象化を提供します。依存関係を便利な方法で収集するための spring-boot-starter-data-cassandra 「スターター」があります。

12.6.1. Cassandra への接続

他の Spring Bean と同様に、自動構成された CassandraTemplate または Cassandra CqlSession インスタンスを注入できます。spring.data.cassandra.* プロパティを使用して、接続をカスタマイズできます。通常、次の例に示すように、keyspace-name および contact-points に加えてローカルデータセンター名を指定します。

spring.data.cassandra.keyspace-name=mykeyspace
spring.data.cassandra.contact-points=cassandrahost1:9042,cassandrahost2:9042
spring.data.cassandra.local-datacenter=datacenter1

次の例に示すように、すべての連絡先でポートが同じ場合は、ショートカットを使用してホスト名のみを指定できます。

spring.data.cassandra.keyspace-name=mykeyspace
spring.data.cassandra.contact-points=cassandrahost1,cassandrahost2
spring.data.cassandra.local-datacenter=datacenter1
これら 2 つの例は、デフォルトのポート 9042 と同じです。ポートを構成する必要がある場合は、spring.data.cassandra.port を使用してください。

Cassandra ドライバーには、クラスパスのルートに application.conf をロードする独自の構成インフラストラクチャがあります。

Spring Boot はこのようなファイルを検索せず、spring.data.cassandra.* 名前空間を介して多くの構成プロパティを提供します。より高度なドライバーのカスタマイズについては、DriverConfigLoaderBuilderCustomizer を実装する任意の数の Bean を登録できます。CqlSession は、タイプ CqlSessionBuilderCustomizer の Bean でカスタマイズできます。

CqlSessionBuilder を使用して複数の CqlSession Bean を作成している場合、ビルダーは可変であるため、各セッションに新しいコピーを必ず挿入してください。

次のコードリストは、Cassandra Bean を挿入する方法を示しています。

@Component
public class MyBean {

    private final CassandraTemplate template;

    public MyBean(CassandraTemplate template) {
        this.template = template;
    }

    // ...

}

タイプ CassandraTemplate の独自の @Bean を追加すると、デフォルトが置き換えられます。

12.6.2. Spring Data Cassandra リポジトリ

Spring Data には、Cassandra の基本的なリポジトリサポートが含まれています。現在、これは前述の JPA リポジトリよりも制限されており、ファインダメソッドに @Query でアノテーションを付ける必要があります。

Spring Data Cassandra の詳細については、リファレンスドキュメントを参照してください

12.7. Couchbase

Couchbase (英語) は、対話型アプリケーション向けに最適化された、オープンソースの分散型マルチモデル NoSQL ドキュメント指向データベースです。Spring Boot は、Couchbase の自動構成と、Spring Data Couchbase (GitHub) が提供する抽象化を提供します。依存関係を便利な方法で収集するための spring-boot-starter-data-couchbase および spring-boot-starter-data-couchbase-reactive 「スターター」があります。

12.7.1. Couchbase への接続

Couchbase SDK といくつかの構成を追加することにより、Cluster を取得できます。spring.couchbase.* プロパティを使用して、接続をカスタマイズできます。通常、次の例に示すように、接続文字列 (GitHub) 、ユーザー名、パスワードを指定します。

spring.couchbase.connection-string=couchbase://192.168.1.123
spring.couchbase.username=user
spring.couchbase.password=secret

ClusterEnvironment 設定の一部をカスタマイズすることもできます。たとえば、次の構成は、新しい Bucket を開くために使用するタイムアウトを変更し、SSL サポートを有効にします。

spring.couchbase.env.timeouts.connect=3000
spring.couchbase.env.ssl.key-store=/location/of/keystore.jks
spring.couchbase.env.ssl.key-store-password=secret
詳細については、spring.couchbase.env.* プロパティを確認してください。より細かく制御するには、1 つ以上の ClusterEnvironmentBuilderCustomizer Bean を使用できます。

12.7.2. Spring Data Couchbase リポジトリ

Spring Data には、Couchbase のリポジトリサポートが含まれています。Spring Data Couchbase の詳細については、リファレンスドキュメントを参照してください (英語)

CouchbaseClientFactory Bean が利用可能であれば、他の Spring Bean と同じように自動構成された CouchbaseTemplate インスタンスを注入できます。これは、上記のように Cluster が使用可能で、バケット名が指定されている場合に発生します。

spring.data.couchbase.bucket-name=my-bucket

次の例は、CouchbaseTemplate Bean を挿入する方法を示しています。

@Component
public class MyBean {

    private final CouchbaseTemplate template;

    @Autowired
    public MyBean(CouchbaseTemplate template) {
        this.template = template;
    }

    // ...

}

自動構成によって提供される Bean をオーバーライドするために、独自の構成で定義できる Bean がいくつかあります。

  • couchbaseMappingContext という名前の CouchbaseMappingContext@Bean

  • couchbaseCustomConversions という名前の CustomConversions@Bean

  • couchbaseTemplate という名前の CouchbaseTemplate@Bean

独自の構成でこれらの名前をハードコードしないようにするには、Spring Data Couchbase が提供する BeanNames を再利用できます。たとえば、次のように、使用するコンバーターをカスタマイズできます。

@Configuration(proxyBeanMethods = false)
public class SomeConfiguration {

    @Bean(BeanNames.COUCHBASE_CUSTOM_CONVERSIONS)
    public CustomConversions myCustomConversions() {
        return new CustomConversions(...);
    }

    // ...

}

12.8. LDAP

LDAP (英語) (ライトウェイトディレクトリアクセスプロトコル)は、IP ネットワークを介して分散ディレクトリ情報サービスにアクセスして維持するための、ベンダーに依存しないオープンな業界標準のアプリケーションプロトコルです。Spring Boot は、準拠する LDAP サーバーの自動構成と、UnboundID (英語) の組み込みインメモリ LDAP サーバーのサポートを提供します。

LDAP 抽象化は Spring Data LDAP (GitHub) によって提供されます。依存関係を便利な方法で収集するための spring-boot-starter-data-ldap 「スターター」があります。

12.8.1. LDAP サーバーへの接続

LDAP サーバーに接続するには、次の例に示すように、spring-boot-starter-data-ldap 「Starter」または spring-ldap-core への依存関係を宣言してから、application.properties でサーバーの URL を宣言してください。

spring.ldap.urls=ldap://myserver:1235
spring.ldap.username=admin
spring.ldap.password=secret

接続設定をカスタマイズする必要がある場合は、spring.ldap.base および spring.ldap.base-environment プロパティを使用できます。

LdapContextSource は、これらの設定に基づいて自動構成されます。DirContextAuthenticationStrategy Bean が使用可能な場合、自動構成された LdapContextSource に関連付けられます。たとえば PooledContextSource を使用するなど、カスタマイズする必要がある場合は、自動構成された LdapContextSource を注入できます。カスタマイズされた ContextSource に @Primary のフラグを立てて、自動構成された LdapTemplate がそれを使用するようにしてください。

12.8.2. Spring Data LDAP リポジトリ

Spring Data には、LDAP のリポジトリサポートが含まれています。Spring Data LDAP の詳細については、リファレンスドキュメントを参照してください (英語)

次の例に示すように、他の Spring Bean と同様に、自動構成された LdapTemplate インスタンスを注入することもできます。

@Component
public class MyBean {

    private final LdapTemplate template;

    @Autowired
    public MyBean(LdapTemplate template) {
        this.template = template;
    }

    // ...

}

12.8.3. 組み込みインメモリ LDAP サーバー

テスト目的で、Spring Boot は UnboundID (英語) からのインメモリ LDAP サーバーの自動構成をサポートしています。サーバーを構成するには、次のように、com.unboundid:unboundid-ldapsdk に依存関係を追加し、spring.ldap.embedded.base-dn プロパティを宣言します。

spring.ldap.embedded.base-dn=dc=spring,dc=io

複数の base-dn 値を定義することは可能ですが、識別名には通常コンマが含まれるため、正しい表記を使用して定義する必要があります。

yaml ファイルでは、yaml リスト表記を使用できます。

spring.ldap.embedded.base-dn:
  - dc=spring,dc=io
  - dc=pivotal,dc=io

プロパティファイルでは、プロパティ名の一部としてインデックスを含める必要があります。

spring.ldap.embedded.base-dn[0]=dc=spring,dc=io
spring.ldap.embedded.base-dn[1]=dc=pivotal,dc=io

デフォルトでは、サーバーはランダムなポートで起動し、通常の LDAP サポートをトリガーします。spring.ldap.urls プロパティを指定する必要はありません。

クラスパスに schema.ldif ファイルがある場合、サーバーの初期化に使用されます。別のリソースから初期化スクリプトをロードする場合は、spring.ldap.embedded.ldif プロパティも使用できます。

デフォルトでは、LDIF ファイルを検証するために標準スキーマが使用されます。spring.ldap.embedded.validation.enabled プロパティを設定することにより、検証を完全にオフにできます。カスタム属性がある場合は、spring.ldap.embedded.validation.schema を使用してカスタム属性タイプまたはオブジェクトクラスを定義できます。

12.9. InfluxDB

InfluxDB (英語) は、運用監視、アプリケーションメトリック、モノのインターネットセンサーデータ、リアルタイム分析などのフィールドにおける時系列データの高速で高可用性の保存と取得に最適化されたオープンソースの時系列データベースです。

12.9.1. InfluxDB への接続

次の例に示すように、influxdb-java クライアントがクラスパス上にあり、データベースの URL が設定されている場合、Spring Boot は InfluxDB インスタンスを自動構成します。

spring.influx.url=https://172.0.0.1:8086

InfluxDB への接続にユーザーとパスワードが必要な場合、それに応じて spring.influx.user および spring.influx.password プロパティを設定できます。

InfluxDB は OkHttp に依存しています。InfluxDB がバックグラウンドで使用する HTTP クライアントを調整する必要がある場合は、InfluxDbOkHttpClientBuilderProvider Bean を登録できます。

13. キャッシング

Spring Framework は、アプリケーションに透過的にキャッシュを追加するためのサポートを提供します。コアでは、抽象化によりメソッドにキャッシュが適用されるため、キャッシュで利用可能な情報に基づいて実行回数が削減されます。キャッシングロジックは、呼び出し側に干渉することなく透過的に適用されます。Spring Boot は、@EnableCaching アノテーションを介してキャッシュサポートが有効になっている限り、キャッシュインフラストラクチャを自動構成します。

詳細については、Spring Framework リファレンスの関連セクションを確認してください。

簡単に言うと、サービスのオペレーションにキャッシングを追加するには、次の例に示すように、メソッドに関連するアノテーションを追加します。

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

@Component
public class MathService {

    @Cacheable("piDecimals")
    public int computePiDecimal(int i) {
        // ...
    }

}

この例は、潜在的にコストのかかる操作でのキャッシュの使用を示しています。computePiDecimal を呼び出す前に、抽象化は i 引数に一致する piDecimals キャッシュ内のエントリを探します。エントリが見つかった場合、キャッシュ内のコンテンツはすぐに呼び出し元に返され、メソッドは呼び出されません。それ以外の場合、メソッドが呼び出され、値を返す前にキャッシュが更新されます。

標準の JSR-107(JCache)アノテーション(@CacheResult など)を透過的に使用することもできます。ただし、Spring Cache アノテーションと JCache アノテーションを混在させないでください。

特定のキャッシュライブラリを追加しない場合、Spring Boot はメモリ内の同時マップを使用する単純なプロバイダーを自動構成します。キャッシュが必要な場合(前の例の piDecimals など)、このプロバイダーがキャッシュを作成します。単純なプロバイダーは、本番環境での使用にはあまりお勧めしませんが、使い始めて、機能を理解していることを確認するには最適です。使用するキャッシュプロバイダーについて決めたら、必ずそのドキュメントを読んで、アプリケーションが使用するキャッシュを構成する方法を理解しましょう。ほぼすべてのプロバイダーでは、アプリケーションで使用するすべてのキャッシュを明示的に構成する必要があります。spring.cache.cache-names プロパティで定義されたデフォルトのキャッシュをカスタマイズする方法を提供するものもあります。

キャッシュからデータを透過的に更新または削除することもできます。

13.1. サポートされているキャッシュプロバイダー

キャッシュ抽象化は実際のストアを提供せず、org.springframework.cache.Cache および org.springframework.cache.CacheManager インターフェースによって具体化される抽象化に依存します。

タイプ CacheManager の Bean または cacheResolver という名前の CacheResolver を定義していない場合(CachingConfigurer(Javadoc) を参照)、Spring Boot は以下のプロバイダーを(示された順序で)検出しようとします。

  1. 汎用

  2. JCache (JSR-107) (EhCache 3, ヘーゼルキャスト、インフィニスパンなど)

  3. EhCache 2.x

  4. Hazelcast

  5. Infinispan

  6. Couchbase

  7. Redis

  8. Caffeine

  9. シンプル

spring.cache.type プロパティを設定することにより、特定のキャッシュプロバイダーを強制することもできます。特定の環境(テストなど)でキャッシュを完全に無効にする必要がある場合は、このプロパティを使用します。
spring-boot-starter-cache 「スターター」を使用して、基本的なキャッシュの依存関係をすばやく追加します。スターターは spring-context-support を持ち込みます。依存関係を手動で追加する場合、JCache、EhCache 2.x,、または Caffeine サポートを使用するには、spring-context-support を含める必要があります。

CacheManager が Spring Boot によって自動構成されている場合、CacheManagerCustomizer インターフェースを実装する Bean を公開することにより、完全に初期化される前に構成をさらに調整できます。次の例では、null 値を基になるマップに渡す必要があることを示すフラグを設定します。

@Bean
public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() {
    return new CacheManagerCustomizer<ConcurrentMapCacheManager>() {
        @Override
        public void customize(ConcurrentMapCacheManager cacheManager) {
            cacheManager.setAllowNullValues(false);
        }
    };
}
上記の例では、自動構成された ConcurrentMapCacheManager が予期されています。そうでない場合(独自の構成を提供したか、別のキャッシュプロバイダーが自動構成された場合)、カスタマイザーはまったく呼び出されません。カスタマイザーは必要な数だけ持つことができ、@Order または Ordered を使用してオーダーすることもできます。

13.1.1. 汎用

コンテキストが少なくとも 1 つの org.springframework.cache.Cache Bean を定義している場合、汎用キャッシングが使用されます。そのタイプのすべての Bean をラップする CacheManager が作成されます。

13.1.2. JCache (JSR-107)

JCache (英語) は、クラスパスに javax.cache.spi.CachingProvider が存在することでブートストラップされ(つまり、JSR-107 準拠のキャッシングライブラリがクラスパスに存在します)、JCacheCacheManager は spring-boot-starter-cache 「スターター」によって提供されます。さまざまな準拠ライブラリが利用可能であり、Spring Boot は Ehcache 3、Hazelcast、および Infinispan の依存関係管理を提供します。他の準拠ライブラリも追加できます。

複数のプロバイダーが存在する場合がありますが、その場合はプロバイダーを明示的に指定する必要があります。JSR-107 標準が構成ファイルの場所を定義する標準化された方法を強制しない場合でも、Spring Boot は、次の例に示すように、実装の詳細でキャッシュを設定するために最善を尽くします。

# Only necessary if more than one provider is present
spring.cache.jcache.provider=com.acme.MyCachingProvider
spring.cache.jcache.config=classpath:acme.xml
キャッシュライブラリがネイティブ実装と JSR-107 サポートの両方を提供する場合、Spring Boot は JSR-107 サポートを優先するため、別の JSR-107 実装に切り替えると同じ機能を使用できます。
Spring Boot は Hazelcast を一般的にサポートしています。単一の HazelcastInstance が使用可能な場合、spring.cache.jcache.config プロパティが指定されていない限り、CacheManager にも自動的に再利用されます。

基になる javax.cache.cacheManager をカスタマイズするには、2 つの方法があります。

  • spring.cache.cache-names プロパティを設定することにより、起動時にキャッシュを作成できます。カスタム javax.cache.configuration.Configuration Bean が定義されている場合、それを使用してカスタマイズします。

  • org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer Bean は、完全なカスタマイズのために CacheManager を参照して呼び出されます。

標準 javax.cache.CacheManager Bean が定義されている場合、抽象化が期待する org.springframework.cache.CacheManager 実装で自動的にラップされます。それ以上のカスタマイズは適用されません。

13.1.3. EhCache 2.x

EhCache (英語) 2.x は、ehcache.xml という名前のファイルがクラスパスのルートにある場合に使用されます。EhCache 2.x が見つかった場合、spring-boot-starter-cache の「スターター」によって提供された EhCacheCacheManager がキャッシュマネージャーのブートストラップに使用されます。次の例に示すように、代替構成ファイルも提供できます。

spring.cache.ehcache.config=classpath:config/another-config.xml

13.1.4. Hazelcast

Spring Boot は Hazelcast を一般的にサポートしています。HazelcastInstance が自動構成されている場合、CacheManager に自動的にラップされます。

13.1.5. Infinispan

Infinispan (英語) にはデフォルトの構成ファイルの場所がないため、明示的に指定する必要があります。それ以外の場合、デフォルトのブートストラップが使用されます。

spring.cache.infinispan.config=infinispan.xml

spring.cache.cache-names プロパティを設定することにより、起動時にキャッシュを作成できます。カスタム ConfigurationBuilder Bean が定義されている場合、それを使用してキャッシュをカスタマイズします。

Spring Boot での Infinispan のサポートは組み込みモードに制限されており、非常に基本的なものです。さらにオプションが必要な場合は、代わりに公式の Infinispan Spring Boot スターターを使用する必要があります。詳細については、Infinispan のドキュメント (GitHub) を参照してください。

13.1.6. Couchbase

Spring Data Couchbase が使用可能で、Couchbase が構成されている場合、CouchbaseCacheManager が自動構成されます。spring.cache.cache-names プロパティを設定することにより、起動時に追加のキャッシュを作成することが可能で、spring.cache.couchbase.* プロパティを使用してキャッシュのデフォルトを構成できます。たとえば、次の構成では、エントリの有効期限が 10 分の cache1 および cache2 キャッシュが作成されます。

spring.cache.cache-names=cache1,cache2
spring.cache.couchbase.expiration=10m

構成をさらに制御する必要がある場合は、CouchbaseCacheManagerBuilderCustomizer Bean の登録を検討してください。次の例は、cache1 および cache2 の特定のエントリの有効期限を設定するカスタマイザを示しています。

@Bean
public CouchbaseCacheManagerBuilderCustomizer myCouchbaseCacheManagerBuilderCustomizer() {
    return (builder) -> builder
            .withCacheConfiguration("cache1",
                    CouchbaseCacheConfiguration.defaultCacheConfig().entryExpiry(Duration.ofSeconds(10)))
            .withCacheConfiguration("cache2",
                    CouchbaseCacheConfiguration.defaultCacheConfig().entryExpiry(Duration.ofMinutes(1)));

}

13.1.7. Redis

Redis (英語) が使用可能で構成されている場合、RedisCacheManager は自動構成されます。spring.cache.cache-names プロパティを設定することにより、起動時に追加のキャッシュを作成でき、spring.cache.redis.* プロパティを使用してキャッシュのデフォルトを設定できます。たとえば、次の構成では、存続時間 10 分で cache1 および cache2 キャッシュを作成します。

spring.cache.cache-names=cache1,cache2
spring.cache.redis.time-to-live=600000
デフォルトでは、2 つの個別のキャッシュが同じキーを使用する場合、Redis に重複するキーがなく、無効な値を返すことができないように、キープレフィックスが追加されます。独自の RedisCacheManager を作成する場合は、この設定を有効にしておくことを強くお勧めします。
独自の RedisCacheConfiguration@Bean を追加することにより、デフォルト構成を完全に制御できます。これは、デフォルトの直列化戦略をカスタマイズする場合に便利です。

構成をさらに制御する必要がある場合は、RedisCacheManagerBuilderCustomizer Bean の登録を検討してください。次の例は、cache1 および cache2 の特定の存続時間を構成するカスタマイザーを示しています。

@Bean
public RedisCacheManagerBuilderCustomizer myRedisCacheManagerBuilderCustomizer() {
    return (builder) -> builder
            .withCacheConfiguration("cache1",
                    RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(10)))
            .withCacheConfiguration("cache2",
                    RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(1)));

}

13.1.8. Caffeine

Caffeine (GitHub) は、Guava のサポートに代わる Guava のキャッシュの Java 8 の書き換えです。Caffeine が存在する場合、CaffeineCacheManager (spring-boot-starter-cache 「スターター」によって提供される)が自動構成されます。キャッシュは、起動時に spring.cache.cache-names プロパティを設定することで作成でき、次のいずれか(示された順序)でカスタマイズできます。

  1. spring.cache.caffeine.spec によって定義されたキャッシュ仕様

  2. com.github.benmanes.caffeine.cache.CaffeineSpec Bean が定義されています

  3. com.github.benmanes.caffeine.cache.Caffeine Bean が定義されています

たとえば、次の構成では、最大サイズが 500 で存続時間が 10 分の cache1 および cache2 キャッシュが作成されます。

spring.cache.cache-names=cache1,cache2
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s

com.github.benmanes.caffeine.cache.CacheLoader Bean が定義されている場合、CaffeineCacheManager に自動的に関連付けられます。CacheLoader はキャッシュマネージャーによって管理されるすべてのキャッシュに関連付けられるため、CacheLoader<Object, Object> として定義する必要があります。自動構成では、他の一般的なタイプは無視されます。

13.1.9. シンプル

他のプロバイダーが見つからない場合は、ConcurrentHashMap をキャッシュストアとして使用する単純な実装が構成されます。アプリケーションにキャッシングライブラリが存在しない場合、これがデフォルトです。デフォルトでは、キャッシュは必要に応じて作成されますが、cache-names プロパティを設定することにより、使用可能なキャッシュのリストを制限できます。たとえば、cache1 および cache2 キャッシュのみが必要な場合は、cache-names プロパティを次のように設定します。

spring.cache.cache-names=cache1,cache2

そうすると、アプリケーションがリストにないキャッシュを使用する場合、実行時にキャッシュが必要になりますが、起動時は失敗します。これは、宣言されていないキャッシュを使用する場合の「実際の」キャッシュプロバイダーの動作に似ています。

13.1.10. なし

@EnableCaching が構成に存在する場合、適切なキャッシュ構成も期待されます。特定の環境でキャッシュを完全に無効にする必要がある場合は、次の例に示すように、キャッシュタイプを強制的に none に設定して、no-op 実装を使用します。

spring.cache.type=none

14. メッセージング

Spring Framework は、JmsTemplate を使用した JMS API の単純化された使用から、メッセージを非同期で受信するための完全なインフラストラクチャまで、メッセージングシステムとの統合に対する広範なサポートを提供します。Spring AMQP は、Advanced Message Queuing Protocol に同様の機能セットを提供します。Spring Boot は、RabbitTemplate および RabbitMQ の自動構成オプションも提供します。Spring WebSocket は STOMP メッセージングのサポートをネイティブに含み、Spring Boot はスターターおよび少量の自動構成を介してそれをサポートします。Spring Boot は、Apache Kafka もサポートしています。

14.1. JMS

javax.jms.ConnectionFactory インターフェースは、JMS ブローカーと対話するための javax.jms.Connection を作成する標準的な方法を提供します。Spring は JMS を使用するために ConnectionFactory を必要としますが、通常は直接使用する必要はなく、代わりに高レベルのメッセージング抽象化に依存できます。(詳細については、Spring Framework リファレンスドキュメントの関連セクションを参照してください)Spring Boot は、メッセージを送受信するために必要なインフラストラクチャーを自動構成します。

14.1.1. ActiveMQ サポート

ActiveMQ (Apache) がクラスパスで使用可能な場合、Spring Boot は ConnectionFactory も構成できます。ブローカーが存在する場合、組み込みブローカーが自動的に開始および構成されます(構成によってブローカー URL が指定されていない場合)。

spring-boot-starter-activemq を使用する場合、JMS と統合する Spring インフラストラクチャと同様に、ActiveMQ インスタンスの接続または埋め込みに必要な依存関係が提供されます。

ActiveMQ 構成は、spring.activemq.* の外部構成プロパティによって制御されます。例: application.properties で次のセクションを宣言できます。

spring.activemq.broker-url=tcp://192.168.1.210:9876
spring.activemq.user=admin
spring.activemq.password=secret

デフォルトでは、CachingConnectionFactory は、spring.jms.* の外部構成プロパティによって制御できる適切な設定でネイティブ ConnectionFactory をラップします。

spring.jms.cache.session-cache-size=5

ネイティブプーリングを使用する場合は、次の例に示すように、org.messaginghub:pooled-jms に依存関係を追加し、それに応じて JmsPoolConnectionFactory を構成することにより、使用できます。

spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=50
サポートされるオプションの詳細については、ActiveMQProperties (GitHub) を参照してください。より高度なカスタマイズのために、ActiveMQConnectionFactoryCustomizer を実装する任意の数の Bean を登録することもできます。

デフォルトでは、ActiveMQ は宛先がまだ存在しない場合に宛先を作成し、指定された名前に対して宛先が解決されるようにします。

14.1.2. Artemis サポート

Spring Boot は、クラスパスで Artemis (Apache) が使用可能であることを検出すると、ConnectionFactory を自動構成できます。ブローカーが存在する場合、埋め込みモードのブローカーは自動的に起動および構成されます(モードプロパティが明示的に設定されていない場合)。サポートされるモードは、embedded (組み込みブローカーが必要であり、ブローカーがクラスパスで使用できない場合にエラーが発生することを明示するため)および native (netty トランスポートプロトコルを使用してブローカーに接続するため)です。後者が構成されている場合、Spring Boot は、デフォルト設定でローカルマシンで実行されているブローカーに接続する ConnectionFactory を構成します。

spring-boot-starter-artemis を使用する場合、既存の Artemis インスタンスに接続するために必要な依存関係と、JMS と統合する Spring インフラストラクチャが提供されます。org.apache.activemq:artemis-jms-server をアプリケーションに追加すると、埋め込みモードを使用できます。

Artemis の構成は、spring.artemis.* の外部構成プロパティによって制御されます。例: application.properties で次のセクションを宣言できます。

spring.artemis.mode=native
spring.artemis.host=192.168.1.210
spring.artemis.port=9876
spring.artemis.user=admin
spring.artemis.password=secret

ブローカーを埋め込むときに、永続性を有効にし、使用可能にする必要がある宛先をリストするかどうかを選択できます。これらをコンマ区切りリストとして指定して、デフォルトのオプションで作成するか、タイプ org.apache.activemq.artemis.jms.server.config.JMSQueueConfiguration または org.apache.activemq.artemis.jms.server.config.TopicConfiguration の Bean をそれぞれ高度なキューおよびトピック構成に定義できます。

デフォルトでは、CachingConnectionFactory は、spring.jms.* の外部構成プロパティによって制御できる適切な設定でネイティブ ConnectionFactory をラップします。

spring.jms.cache.session-cache-size=5

ネイティブプーリングを使用する場合は、次の例に示すように、org.messaginghub:pooled-jms に依存関係を追加し、それに応じて JmsPoolConnectionFactory を構成することにより、使用できます。

spring.artemis.pool.enabled=true
spring.artemis.pool.max-connections=50

サポートされるオプションの詳細については、ArtemisProperties (GitHub) を参照してください。

JNDI ルックアップは含まれず、宛先は Artemis 構成の name 属性または構成を通じて提供された名前を使用して、名前に対して解決されます。

14.1.3. JNDI ConnectionFactory を使用する

アプリケーションサーバーでアプリケーションを実行している場合、Spring Boot は JNDI を使用して JMS ConnectionFactory を見つけようとします。デフォルトでは、java:/JmsXA と java:/XAConnectionFactory の場所がチェックされます。次の例に示すように、別の場所を指定する必要がある場合は、spring.jms.jndi-name プロパティを使用できます。

spring.jms.jndi-name=java:/MyConnectionFactory

14.1.4. メッセージを送る

Spring の JmsTemplate は自動構成されており、次の例に示すように、独自の Bean に直接オートワイヤーできます。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final JmsTemplate jmsTemplate;

    @Autowired
    public MyBean(JmsTemplate jmsTemplate) {
        this.jmsTemplate = jmsTemplate;
    }

    // ...

}
JmsMessagingTemplate(Javadoc) は、同様の方法で注入できます。DestinationResolver または MessageConverter Bean が定義されている場合、自動構成された JmsTemplate に自動的に関連付けられます。

14.1.5. メッセージを受信する

JMS インフラストラクチャが存在する場合、Bean に @JmsListener のアノテーションを付けてリスナーエンドポイントを作成できます。JmsListenerContainerFactory が定義されていない場合、デフォルトのものが自動的に構成されます。DestinationResolver または MessageConverter Bean が定義されている場合、それらは自動的にデフォルトファクトリに関連付けられます。

デフォルトでは、デフォルトのファクトリはトランザクションです。JtaTransactionManager が存在するインフラストラクチャで実行すると、デフォルトでリスナーコンテナーに関連付けられます。そうでない場合、sessionTransacted フラグが有効になります。後者のシナリオでは、リスナーメソッド(またはそのデリゲート)に @Transactional を追加することにより、ローカルデータストアトランザクションを受信メッセージの処理に関連付けることができます。これにより、ローカルトランザクションが完了すると、受信メッセージが確認されます。これには、同じ JMS セッションで実行されたレスポンスメッセージの送信も含まれます。

次のコンポーネントは、someQueue 宛先にリスナーエンドポイントを作成します。

@Component
public class MyBean {

    @JmsListener(destination = "someQueue")
    public void processMessage(String content) {
        // ...
    }

}
詳細については、@EnableJms の Javadoc を参照してください。

さらに JmsListenerContainerFactory インスタンスを作成する必要がある場合、またはデフォルトをオーバーライドする場合は、Spring Boot が提供する DefaultJmsListenerContainerFactoryConfigurer を使用して、自動構成されたものと同じ設定で DefaultJmsListenerContainerFactory を初期化できます。

たとえば、次の例では、特定の MessageConverter を使用する別のファクトリを公開しています。

@Configuration(proxyBeanMethods = false)
static class JmsConfiguration {

    @Bean
    public DefaultJmsListenerContainerFactory myFactory(
            DefaultJmsListenerContainerFactoryConfigurer configurer) {
        DefaultJmsListenerContainerFactory factory =
                new DefaultJmsListenerContainerFactory();
        configurer.configure(factory, connectionFactory());
        factory.setMessageConverter(myMessageConverter());
        return factory;
    }

}

その後、次のように @JmsListener アノテーション付きメソッドでファクトリを使用できます。

@Component
public class MyBean {

    @JmsListener(destination = "someQueue", containerFactory="myFactory")
    public void processMessage(String content) {
        // ...
    }

}

14.2. AMQP

Advanced Message Queuing Protocol(AMQP)は、メッセージ指向ミドルウェア向けのプラットフォームに依存しないワイヤーレベルのプロトコルです。Spring AMQP プロジェクトは、コア Spring コンセプトを AMQP ベースのメッセージングソリューションの開発に適用します。Spring Boot は、spring-boot-starter-amqp 「スターター」など、RabbitMQ を介して AMQP を操作するためのいくつかの便利な機能を提供します。

14.2.1. RabbitMQ サポート

RabbitMQ (英語) は、AMQP プロトコルに基づいた、軽量で信頼性が高く、スケーラブルでポータブルなメッセージブローカーです。Spring は、RabbitMQ を使用して AMQP プロトコルを介して通信します。

RabbitMQ 構成は、spring.rabbitmq.* の外部構成プロパティによって制御されます。例: application.properties で次のセクションを宣言できます。

spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=secret

または、addresses 属性を使用して同じ接続を構成できます。

spring.rabbitmq.addresses=amqp://admin:[email protected] (英語)  
その方法でアドレスを指定する場合、host および port プロパティは無視されます。アドレスが amqps プロトコルを使用している場合、SSL サポートは自動的に有効になります。

ConnectionNameStrategy Bean がコンテキストに存在する場合、自動構成された ConnectionFactory によって作成された接続に名前を付けるために自動的に使用されます。サポートされるオプションの詳細については、RabbitProperties (GitHub) を参照してください。

詳細については、RabbitMQ で使用されるプロトコルである AMQP を理解する (英語) を参照してください。

14.2.2. メッセージを送る

Spring の AmqpTemplate および AmqpAdmin は自動構成され、次の例に示すように、独自の Bean に直接オートワイヤーできます。

import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final AmqpAdmin amqpAdmin;
    private final AmqpTemplate amqpTemplate;

    @Autowired
    public MyBean(AmqpAdmin amqpAdmin, AmqpTemplate amqpTemplate) {
        this.amqpAdmin = amqpAdmin;
        this.amqpTemplate = amqpTemplate;
    }

    // ...

}
RabbitMessagingTemplate (英語) は、同様の方法で注入できます。MessageConverter Bean が定義されている場合、自動構成された AmqpTemplate に自動的に関連付けられます。

必要に応じて、Bean として定義されている org.springframework.amqp.core.Queue は、RabbitMQ インスタンスで対応するキューを宣言するために自動的に使用されます。

操作を再試行するには、AmqpTemplate で再試行を有効にします(たとえば、ブローカー接続が失われた場合)。

spring.rabbitmq.template.retry.enabled=true
spring.rabbitmq.template.retry.initial-interval=2s

再試行はデフォルトで無効になっています。RabbitRetryTemplateCustomizer Bean を宣言することにより、プログラムで RetryTemplate をカスタマイズすることもできます。

さらに RabbitTemplate インスタンスを作成する必要がある場合、またはデフォルトをオーバーライドする場合、Spring Boot は RabbitTemplateConfigurer Bean を提供します。これを使用して、自動構成で使用されるファクトリと同じ設定で RabbitTemplate を初期化できます。

14.2.3. メッセージを受信する

Rabbit インフラストラクチャが存在する場合、@RabbitListener で Bean にアノテーションを付けてリスナーエンドポイントを作成できます。RabbitListenerContainerFactory が定義されていない場合、デフォルトの SimpleRabbitListenerContainerFactory が自動的に構成され、spring.rabbitmq.listener.type プロパティを使用して直接コンテナーに切り替えることができます。MessageConverter または MessageRecoverer Bean が定義されている場合、自動的にデフォルトファクトリに関連付けられます。

次のサンプルコンポーネントは、someQueue キューにリスナーエンドポイントを作成します。

@Component
public class MyBean {

    @RabbitListener(queues = "someQueue")
    public void processMessage(String content) {
        // ...
    }

}
詳細については、@EnableRabbit の Javadoc を参照して (英語) ください。

さらに RabbitListenerContainerFactory インスタンスを作成する必要がある場合、またはデフォルトをオーバーライドする場合、Spring Boot は SimpleRabbitListenerContainerFactoryConfigurer および DirectRabbitListenerContainerFactoryConfigurer を提供します。これらを使用して、自動構成で使用されるファクトリと同じ設定で SimpleRabbitListenerContainerFactory および DirectRabbitListenerContainerFactory を初期化できます。

選択したコンテナーの種類は関係ありません。これらの 2 つの Bean は、自動構成によって公開されます。

たとえば、次の構成クラスは、特定の MessageConverter を使用する別のファクトリを公開します。

@Configuration(proxyBeanMethods = false)
static class RabbitConfiguration {

    @Bean
    public SimpleRabbitListenerContainerFactory myFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer) {
        SimpleRabbitListenerContainerFactory factory =
                new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        factory.setMessageConverter(myMessageConverter());
        return factory;
    }

}

次に、次のように、任意の @RabbitListener アノテーション付きメソッドでファクトリを使用できます。

@Component
public class MyBean {

    @RabbitListener(queues = "someQueue", containerFactory="myFactory")
    public void processMessage(String content) {
        // ...
    }

}

再試行を有効にして、リスナーが例外をスローする状況を処理できます。デフォルトでは、RejectAndDontRequeueRecoverer が使用されますが、独自の MessageRecoverer を定義できます。再試行が使い果たされると、ブローカーがそうするように構成されている場合、メッセージは拒否され、送達不能交換にドロップまたはルーティングされます。デフォルトでは、再試行は無効になっています。RabbitRetryTemplateCustomizer Bean を宣言することにより、RetryTemplate をプログラムでカスタマイズすることもできます。

デフォルトでは、再試行が無効になっていて、リスナーが例外をスローした場合、配信は無期限に再試行されます。この動作は次の 2 つの方法で変更できます。defaultRequeueRejected プロパティを false に設定して再配信をゼロにするか、AmqpRejectAndDontRequeueException をスローしてメッセージを拒否することを通知します。後者は、再試行が有効で、配信試行の最大数に達したときに使用されるメカニズムです。

14.3. Apache Kafka のサポート

Apache Kafka (英語) は、spring-kafka プロジェクトの自動構成を提供することによりサポートされます。

Kafka 構成は、spring.kafka.* の外部構成プロパティによって制御されます。例: application.properties で次のセクションを宣言できます。

spring.kafka.bootstrap-servers=localhost:9092
spring.kafka.consumer.group-id=myGroup
起動時にトピックを作成するには、タイプ NewTopic の Bean を追加します。トピックが既に存在する場合、Bean は無視されます。

サポートされるオプションの詳細については、KafkaProperties (GitHub) を参照してください。

14.3.1. メッセージを送る

Spring の KafkaTemplate は自動構成されており、次の例に示すように、独自の Bean に直接オートワイヤーできます。

@Component
public class MyBean {

    private final KafkaTemplate kafkaTemplate;

    @Autowired
    public MyBean(KafkaTemplate kafkaTemplate) {
        this.kafkaTemplate = kafkaTemplate;
    }

    // ...

}
プロパティ spring.kafka.producer.transaction-id-prefix が定義されている場合、KafkaTransactionManager が自動的に構成されます。また、RecordMessageConverter Bean が定義されている場合、自動構成された KafkaTemplate に自動的に関連付けられます。

14.3.2. メッセージを受信する

Apache Kafka インフラストラクチャが存在する場合、Bean に @KafkaListener のアノテーションを付けてリスナーエンドポイントを作成できます。KafkaListenerContainerFactory が定義されていない場合は、spring.kafka.listener.* で定義されたキーを使用してデフォルトが自動的に構成されます。

次のコンポーネントは、someTopic トピックにリスナーエンドポイントを作成します。

@Component
public class MyBean {

    @KafkaListener(topics = "someTopic")
    public void processMessage(String content) {
        // ...
    }

}

KafkaTransactionManager Bean が定義されている場合、コンテナーファクトリに自動的に関連付けられます。同様に、ErrorHandlerAfterRollbackProcessor または ConsumerAwareRebalanceListener Bean が定義されている場合、自動的にデフォルトファクトリに関連付けられます。

リスナーのタイプに応じて、RecordMessageConverter または BatchMessageConverter Bean がデフォルトファクトリに関連付けられます。RecordMessageConverter Bean のみがバッチリスナーに存在する場合、BatchMessageConverter にラップされます。

カスタム ChainedKafkaTransactionManager は、通常、自動構成された KafkaTransactionManager Bean を参照するため、@Primary とマークする必要があります。

14.3.3. Kafka ストリーム

Spring for Apache Kafka は、StreamsBuilder オブジェクトを作成し、そのストリームのライフサイクルを管理するファクトリ Bean を提供します。Spring Boot は、kafka-streams がクラスパス上にあり、Kafka ストリームが @EnableKafkaStreams アノテーションを介して有効になっている限り、必要な KafkaStreamsConfiguration Bean を自動構成します。

Kafka ストリームを有効にすると、アプリケーション ID とブートストラップサーバーを設定する必要があります。前者は spring.kafka.streams.application-id を使用して設定でき、設定されていない場合はデフォルトで spring.application.name になります。後者はグローバルに設定することも、ストリームに対してのみ具体的にオーバーライドすることもできます。

専用プロパティを使用して、いくつかの追加プロパティを利用できます。他の任意の Kafka プロパティは、spring.kafka.streams.properties 名前空間を使用して設定できます。詳細については、Kafka の追加プロパティも参照してください。

ファクトリ Bean を使用するには、次の例に示すように、StreamsBuilder を @Bean に接続します。

@Configuration(proxyBeanMethods = false)
@EnableKafkaStreams
public static class KafkaStreamsExampleConfiguration {

    @Bean
    public KStream<Integer, String> kStream(StreamsBuilder streamsBuilder) {
        KStream<Integer, String> stream = streamsBuilder.stream("ks1In");
        stream.map((k, v) -> new KeyValue<>(k, v.toUpperCase())).to("ks1Out",
                Produced.with(Serdes.Integer(), new JsonSerde<>()));
        return stream;
    }

}

デフォルトでは、作成する StreamBuilder オブジェクトによって管理されるストリームは自動的に開始されます。spring.kafka.streams.auto-startup プロパティを使用して、この動作をカスタマイズできます。

14.3.4. Kafka の追加プロパティ

自動構成でサポートされるプロパティは appendix-application-properties.html に示されています。ほとんどの場合、これらのプロパティ(ハイフン付きまたはキャメルケース)は、Apache Kafka ドット付きプロパティに直接マップされることに注意してください。詳細については、Apache Kafka のドキュメントを参照してください。

これらのプロパティの最初のいくつかはすべてのコンポーネント(プロデューサー、コンシューマー、管理者、およびストリーム)に適用されますが、異なる値を使用する場合はコンポーネントレベルで指定できます。Apache Kafka は、重要度が高、中、または低のプロパティを指定します。Spring Boot 自動構成は、すべての重要度の高いプロパティ、一部の選択された MEDIUM および LOW プロパティ、およびデフォルト値を持たないプロパティをサポートします。

Kafka でサポートされているプロパティのサブセットのみが、KafkaProperties クラスから直接利用できます。直接サポートされていない追加のプロパティを使用してプロデューサーまたはコンシューマーを構成する場合は、次のプロパティを使用します。

spring.kafka.properties.prop.one=first
spring.kafka.admin.properties.prop.two=second
spring.kafka.consumer.properties.prop.three=third
spring.kafka.producer.properties.prop.four=fourth
spring.kafka.streams.properties.prop.five=fifth

これにより、共通の prop.one Kafka プロパティが first (プロデューサー、コンシューマー、および管理者に適用)、prop.two admin プロパティが second に、prop.three コンシューマープロパティが third に、prop.four プロデューサープロパティが fourth に、prop.five ストリームプロパティが fifth に設定されます。

Spring Kafka JsonDeserializer は、次のように構成することもできます。

spring.kafka.consumer.value-deserializer=org.springframework.kafka.support.serializer.JsonDeserializer
spring.kafka.consumer.properties.spring.json.value.default.type=com.example.Invoice
spring.kafka.consumer.properties.spring.json.trusted.packages=com.example,org.acme

同様に、型情報をヘッダーで送信する JsonSerializer のデフォルトの動作を無効にできます。

spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer
spring.kafka.producer.properties.spring.json.add.type.headers=false
この方法で設定されたプロパティは、Spring Boot が明示的にサポートする構成アイテムをオーバーライドします。

14.3.5. 組み込み Kafka を使用したテスト

Spring for Apache Kafka は、組み込み Apache Kafka ブローカーを使用してプロジェクトをテストする便利な方法を提供します。この機能を使用するには、spring-kafka-test モジュールの @EmbeddedKafka でテストクラスにアノテーションを付けます。詳細については、Spring for Apache Kafka リファレンスマニュアル (英語) を参照してください。

前述の組み込み Apache Kafka ブローカーで Spring Boot の自動構成を機能させるには、組み込みブローカーアドレスのシステムプロパティ(EmbeddedKafkaBroker が入力)を Apache Kafka の Spring Boot 構成プロパティに再マッピングする必要があります。それにはいくつかの方法があります。

  • 組み込みブローカーアドレスをテストクラスの spring.kafka.bootstrap-servers にマップするシステムプロパティを提供します。

static {
    System.setProperty(EmbeddedKafkaBroker.BROKER_LIST_PROPERTY, "spring.kafka.bootstrap-servers");
}
  • @EmbeddedKafka アノテーションでプロパティ名を構成します。

@EmbeddedKafka(topics = "someTopic",
        bootstrapServersProperty = "spring.kafka.bootstrap-servers")
  • 構成プロパティでプレースホルダーを使用します。

spring.kafka.bootstrap-servers=${spring.embedded.kafka.brokers}

15. RestTemplate を使用した REST サービスの呼び出し

アプリケーションからリモート REST サービスを呼び出す必要がある場合は、Spring Framework の RestTemplate(Javadoc) クラスを使用できます。RestTemplate インスタンスは使用する前にカスタマイズする必要があることが多いため、Spring Boot は単一の自動構成 RestTemplate Bean を提供しません。ただし、必要に応じて RestTemplate インスタンスを作成するために使用できる RestTemplateBuilder を自動構成します。自動構成された RestTemplateBuilder は、実用的な HttpMessageConverters が RestTemplate インスタンスに確実に適用されるようにします。

次のコードは典型的な例を示しています。

@Service
public class MyService {

    private final RestTemplate restTemplate;

    public MyService(RestTemplateBuilder restTemplateBuilder) {
        this.restTemplate = restTemplateBuilder.build();
    }

    public Details someRestCall(String name) {
        return this.restTemplate.getForObject("/{name}/details", Details.class, name);
    }

}
RestTemplateBuilder には、RestTemplate をすばやく構成するために使用できる多くの便利なメソッドが含まれています。例:BASIC 認証サポートを追加するには、builder.basicAuthentication("user", "password").build() を使用できます。

15.1. RestTemplate のカスタマイズ

RestTemplate カスタマイズには、カスタマイズの適用範囲に応じて 3 つの主なアプローチがあります。

カスタマイズの範囲をできる限り狭くするには、自動構成された RestTemplateBuilder を挿入し、必要に応じてそのメソッドを呼び出します。各メソッド呼び出しは新しい RestTemplateBuilder インスタンスを返すため、カスタマイズはこのビルダーの使用にのみ影響します。

アプリケーション全体で追加のカスタマイズを行うには、RestTemplateCustomizer Bean を使用します。このような Bean はすべて、自動構成された RestTemplateBuilder に自動的に登録され、それを使用して作成されたすべてのテンプレートに適用されます。

次の例は、192.168.0.5 を除くすべてのホストに対してプロキシの使用を構成するカスタマイザーを示しています。

static class ProxyCustomizer implements RestTemplateCustomizer {

    @Override
    public void customize(RestTemplate restTemplate) {
        HttpHost proxy = new HttpHost("proxy.example.com");
        HttpClient httpClient = HttpClientBuilder.create().setRoutePlanner(new DefaultProxyRoutePlanner(proxy) {

            @Override
            public HttpHost determineProxy(HttpHost target, HttpRequest request, HttpContext context)
                    throws HttpException {
                if (target.getHostName().equals("192.168.0.5")) {
                    return null;
                }
                return super.determineProxy(target, request, context);
            }

        }).build();
        restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
    }

}

最後に、最も極端な(そしてめったに使用されない)オプションは、独自の RestTemplateBuilder Bean を作成することです。これにより、RestTemplateBuilder の自動構成がオフになり、RestTemplateCustomizer Bean が使用されなくなります。

16. WebClient を使用した REST サービスの呼び出し

クラスパスに Spring WebFlux がある場合、WebClient を使用してリモート REST サービスを呼び出すこともできます。RestTemplate と比較して、このクライアントはより関数感触を持ち、完全に反応的です。WebClient の詳細については、Spring Framework ドキュメントの専用のセクションを参照してください。

Spring Boot は、WebClient.Builder を作成して事前設定します。コンポーネントに注入し、WebClient インスタンスを作成するために使用することを強くお勧めします。Spring Boot は、そのビルダーを構成して、HTTP リソースを共有し、コーデックのセットアップをサーバーのものと同じ方法で反映します(WebFlux HTTP コーデックの自動構成を参照)。

次のコードは典型的な例を示しています。

@Service
public class MyService {

    private final WebClient webClient;

    public MyService(WebClient.Builder webClientBuilder) {
        this.webClient = webClientBuilder.baseUrl("https://example.org").build();
    }

    public Mono<Details> someRestCall(String name) {
        return this.webClient.get().uri("/{name}/details", name)
                        .retrieve().bodyToMono(Details.class);
    }

}

16.1. WebClient ランタイム

Spring Boot は、アプリケーションクラスパスで利用可能なライブラリに応じて、どの ClientHttpConnector を使用して WebClient を駆動するかを自動検出します。今のところ、Reactor Netty および Jetty RS クライアントがサポートされています。

spring-boot-starter-webflux スターターは、デフォルトで io.projectreactor.netty:reactor-netty に依存しており、サーバーとクライアントの両方の実装をもたらします。代わりに Jetty をリアクティブサーバーとして使用することを選択した場合、Jetty Reactive HTTP クライアントライブラリ org.eclipse.jetty:jetty-reactive-httpclient への依存関係を追加する必要があります。サーバーとクライアントに同じテクノロジーを使用すると、クライアントとサーバー間で HTTP リソースが自動的に共有されるため、利点があります。

開発者は、カスタム ReactorResourceFactory または JettyResourceFactory Bean を提供することにより、Jetty および Reactor Netty のリソース構成をオーバーライドできます。これは、クライアントとサーバーの両方に適用されます。

クライアントのその選択をオーバーライドする場合は、独自の ClientHttpConnector Bean を定義し、クライアント構成を完全に制御できます。

16.2. WebClient のカスタマイズ

WebClient カスタマイズには、カスタマイズの適用範囲に応じて 3 つの主なアプローチがあります。

カスタマイズの範囲をできる限り狭くするには、自動構成された WebClient.Builder を挿入し、必要に応じてそのメソッドを呼び出します。WebClient.Builder インスタンスはステートフルです:ビルダーでの変更は、その後作成されたすべてのクライアントに反映されます。同じビルダーで複数のクライアントを作成する場合は、WebClient.Builder other = builder.clone(); でビルダーを複製することも検討できます。

アプリケーション全体で、すべての WebClient.Builder インスタンスに追加のカスタマイズを行うには、WebClientCustomizer Bean を宣言し、注入の時点で WebClient.Builder をローカルに変更します。

最後に、元の API にフォールバックして WebClient.create() を使用できます。その場合、自動構成または WebClientCustomizer は適用されません。

17. 検証

Bean 検証 1.1 でサポートされるメソッド検証機能は、JSR-303 実装(Hibernate バリデーターなど)がクラスパス上にある限り、自動的に有効になります。これにより、Bean メソッドに、パラメーターおよび / または戻り値の javax.validation 制約をアノテーションできます。このようなアノテーション付きメソッドを持つターゲットクラスには、インライン制約アノテーションを検索するメソッドの型レベルで @Validated アノテーションを付ける必要があります。

たとえば、次のサービスは最初の引数の検証をトリガーし、そのサイズが 8 〜 10 であることを確認します。

@Service
@Validated
public class MyBean {

    public Archive findByCodeAndAuthor(@Size(min = 8, max = 10) String code,
            Author author) {
        ...
    }

}

18. メール送信

Spring Framework は、JavaMailSender インターフェースを使用してメールを送信するための抽象化を提供し、Spring Boot は、自動構成とスターターモジュールを提供します。

JavaMailSender の使用方法の詳細については、リファレンスドキュメントを参照してください。

spring.mail.host および関連するライブラリ(spring-boot-starter-mail で定義されている)が使用可能な場合、存在しない場合はデフォルトの JavaMailSender が作成されます。送信者は、spring.mail 名前空間の構成アイテムによってさらにカスタマイズできます。詳細については、MailProperties (GitHub) を参照してください。

特に、特定のデフォルトのタイムアウト値は無限であり、次の例に示すように、応答しないメールサーバーによってスレッドがブロックされるのを避けるために、これを変更することができます。

spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=3000
spring.mail.properties.mail.smtp.writetimeout=5000

JNDI の既存の Session を使用して JavaMailSender を構成することもできます。

spring.mail.jndi-name=mail/Session

jndi-name が設定されると、他のすべてのセッション関連の設定よりも優先されます。

19. JTA を使用した分散トランザクション

Spring Boot は、Atomikos (英語) 組み込みトランザクションマネージャーを使用して、複数の XA リソースに分散された JTA トランザクションをサポートします。Bitronix (GitHub) 組み込みトランザクションマネージャーを使用するための非推奨のサポートも提供されていますが、将来のリリースでは削除される予定です。JTA トランザクションは、適切な Java EE アプリケーションサーバーにデプロイするときにもサポートされます。

JTA 環境が検出されると、Spring の JtaTransactionManager を使用してトランザクションが管理されます。自動構成された JMS、DataSource、および JPA Bean は、XA トランザクションをサポートするためにアップグレードされます。@Transactional などの標準的な Spring イディオムを使用して、分散トランザクションに参加できます。JTA 環境内でローカルトランザクションを使用する場合は、spring.jta.enabled プロパティを false に設定して、JTA 自動構成を無効にすることができます。

19.1. Atomikos Transaction Manager を使用する

Atomikos (英語) は、Spring Boot アプリケーションに組み込むことができる一般的なオープンソーストランザクションマネージャーです。spring-boot-starter-jta-atomikos スターターを使用して、適切な Atomikos ライブラリをプルできます。Spring Boot は、Atomikos を自動構成し、適切な depends-on 設定が Spring Bean に適用され、起動とシャットダウンの順序が正しくなるようにします。

デフォルトでは、Atomikos トランザクションログは、アプリケーションのホームディレクトリ(アプリケーション jar ファイルが存在するディレクトリ)の transaction-logs ディレクトリに書き込まれます。application.properties ファイルで spring.jta.log-dir プロパティを設定することにより、このディレクトリの場所をカスタマイズできます。spring.jta.atomikos.properties で始まるプロパティは、Atomikos UserTransactionServiceImp のカスタマイズにも使用できます。詳細については、AtomikosProperties Javadoc を参照してください。

複数のトランザクションマネージャーが同じリソースマネージャーを安全に調整できるようにするには、各 Atomikos インスタンスに一意の ID を設定する必要があります。デフォルトでは、この ID は Atomikos が実行されているマシンの IP アドレスです。本番環境での一意性を確保するには、アプリケーションのインスタンスごとに異なる値を使用して spring.jta.transaction-manager-id プロパティを構成する必要があります。

19.2. Bitronix Transaction Manager の使用

Spring Boot 2.3, の時点で、Bitronix のサポートは推奨されておらず、将来のリリースで削除される予定です。

spring-boot-starter-jta-bitronix スターターを使用して、適切な Bitronix 依存関係をプロジェクトに追加できます。Atomikos と同様に、Spring Boot は自動的に Bitronix を構成し、Bean を後処理して、起動とシャットダウンの順序が正しいことを確認します。

デフォルトでは、Bitronix トランザクションログファイル(part1.btm および part2.btm)は、アプリケーションホームディレクトリの transaction-logs ディレクトリに書き込まれます。spring.jta.log-dir プロパティを設定することにより、このディレクトリの場所をカスタマイズできます。spring.jta.bitronix.properties で始まるプロパティも bitronix.tm.Configuration Bean にバインドされており、完全なカスタマイズが可能です。詳細については、Bitronix のドキュメント (GitHub) を参照してください。

複数のトランザクションマネージャーが同じリソースマネージャーを安全に調整できるようにするには、各 Bitronix インスタンスを一意の ID で構成する必要があります。デフォルトでは、この ID は Bitronix が実行されているマシンの IP アドレスです。本番環境での一意性を確保するには、アプリケーションのインスタンスごとに異なる値を使用して spring.jta.transaction-manager-id プロパティを構成する必要があります。

19.3. Java EE マネージドトランザクションマネージャーの使用

Spring Boot アプリケーションを war または ear ファイルとしてパッケージ化し、Java EE アプリケーションサーバーにデプロイする場合、アプリケーションサーバーの組み込みトランザクションマネージャーを使用できます。Spring Boot は、一般的な JNDI ロケーション(java:comp/UserTransactionjava:comp/TransactionManager など)を見て、トランザクションマネージャーの自動構成を試みます。アプリケーションサーバーが提供するトランザクションサービスを使用する場合は、通常、すべてのリソースがサーバーによって管理され、JNDI で公開されることも確認する必要があります。Spring Boot は、JNDI パス(java:/JmsXA または java:/XAConnectionFactory)で ConnectionFactory を探すことで JMS の自動構成を試行します。spring.datasource.jndi-name プロパティを使用して DataSource を構成できます。

19.4. XA と非 XA JMS 接続の混在

JTA を使用する場合、プライマリ JMS ConnectionFactory Bean は XA 対応であり、分散トランザクションに参加します。状況によっては、非 XA ConnectionFactory を使用して特定の JMS メッセージを処理したい場合があります。例:JMS 処理ロジックは XA タイムアウトよりも時間がかかる場合があります。

非 XA ConnectionFactory を使用する場合は、@PrimaryjmsConnectionFactory Bean ではなく、nonXaJmsConnectionFactory Bean を注入できます。一貫性を保つため、Bean エイリアス xaJmsConnectionFactory を使用して jmsConnectionFactory Bean も提供されます。

次の例は、ConnectionFactory インスタンスを注入する方法を示しています。

// Inject the primary (XA aware) ConnectionFactory
@Autowired
private ConnectionFactory defaultConnectionFactory;

// Inject the XA aware ConnectionFactory (uses the alias and injects the same as above)
@Autowired
@Qualifier("xaJmsConnectionFactory")
private ConnectionFactory xaConnectionFactory;

// Inject the non-XA aware ConnectionFactory
@Autowired
@Qualifier("nonXaJmsConnectionFactory")
private ConnectionFactory nonXaConnectionFactory;

19.5. 代替の組み込みトランザクションマネージャーのサポート

XAConnectionFactoryWrapper (GitHub) および XADataSourceWrapper (GitHub) インターフェースを使用して、代替の組み込みトランザクションマネージャーをサポートできます。インターフェースは、XAConnectionFactory および XADataSource Bean をラップし、通常の ConnectionFactory および DataSource Bean として公開し、分散トランザクションに透過的に登録します。JtaTransactionManager Bean および適切な XA ラッパー Bean が ApplicationContext 内に登録されている場合、DataSource および JMS 自動構成は JTA バリアントを使用します。

AtomikosXAConnectionFactoryWrapper (GitHub) および AtomikosXADataSourceWrapper (GitHub) は、XA ラッパーの作成方法の良い例を提供します。

20. Hazelcast

Hazelcast (英語) がクラスパス上にあり、適切な構成が見つかった場合、Spring Boot は、アプリケーションに挿入できる HazelcastInstance を自動構成します。

com.hazelcast.config.Config Bean を定義すると、Spring Boot はそれを使用します。構成がインスタンス名を定義している場合、Spring Boot は新しいインスタンスを作成するのではなく、既存のインスタンスを見つけようとします。

次の例に示すように、構成で使用する Hazelcast 構成ファイルを指定することもできます。

spring.hazelcast.config=classpath:config/my-hazelcast.xml

それ以外の場合、Spring Boot は、デフォルトの場所(作業ディレクトリまたはクラスパスのルートにある hazelcast.xml、または同じ場所にある .yaml の対応する場所)から Hazelcast 構成を見つけようとします。hazelcast.config システムプロパティが設定されているかどうかも確認します。詳細については、Hazelcast のドキュメント (英語) を参照してください。

hazelcast-client がクラスパスに存在する場合、Spring Boot は最初に次の構成オプションを確認してクライアントを作成しようとします。

  • com.hazelcast.client.config.ClientConfig Bean の存在。

  • spring.hazelcast.config プロパティによって定義された構成ファイル。

  • hazelcast.client.config システムプロパティの存在。

  • 作業ディレクトリまたはクラスパスのルートにある hazelcast-client.xml

  • 作業ディレクトリまたはクラスパスのルートにある hazelcast-client.yaml

Spring Boot には、Hazelcast の明示的なキャッシュサポートもあります。キャッシュが有効になっている場合、HazelcastInstance は CacheManager 実装に自動的にラップされます。

21. Quartz スケジューラー

Spring Boot は、spring-boot-starter-quartz 「スターター」を含む、Quartz スケジューラー (英語) を操作するためのいくつかの便利な機能を提供します。Quartz が使用可能な場合、Scheduler は(SchedulerFactoryBean 抽象化により)自動構成されます。

次のタイプの Bean が自動的に取得され、Scheduler に関連付けられます。

  • JobDetail: 特定のジョブを定義します。JobDetail インスタンスは、JobBuilder API を使用して構築できます。

  • Calendar.

  • Trigger: 特定のジョブがいつトリガーされるかを定義します。

デフォルトでは、インメモリ JobStore が使用されます。ただし、次の例に示すように、DataSource Bean がアプリケーションで利用可能であり、それに応じて spring.quartz.job-store-type プロパティが構成されている場合、JDBC ベースのストアを構成できます。

spring.quartz.job-store-type=jdbc

JDBC ストアを使用すると、次の例に示すように、起動時にスキーマを初期化できます。

spring.quartz.jdbc.initialize-schema=always
デフォルトでは、Quartz ライブラリで提供される標準スクリプトを使用して、データベースが検出および初期化されます。これらのスクリプトは既存のテーブルを削除し、再起動するたびにすべてのトリガーを削除します。spring.quartz.jdbc.schema プロパティを設定して、カスタムスクリプトを提供することもできます。

Quartz にアプリケーションのメイン DataSource 以外の DataSource を使用させるには、DataSource Bean を宣言し、@Bean メソッドに @QuartzDataSource でアノテーションを付けます。これにより、SchedulerFactoryBean とスキーマの初期化の両方で Quartz 固有の DataSource が使用されるようになります。

デフォルトでは、構成によって作成されたジョブは、永続ジョブストアから読み取られた登録済みのジョブを上書きしません。既存のジョブ定義の上書きを有効にするには、spring.quartz.overwrite-existing-jobs プロパティを設定します。

Quartz スケジューラー構成は、spring.quartz プロパティおよび SchedulerFactoryBeanCustomizer Bean を使用してカスタマイズできます。これにより、プログラムによる SchedulerFactoryBean のカスタマイズが可能になります。spring.quartz.properties.* を使用して、高度な Quartz 構成プロパティをカスタマイズできます。

特に、Quartz は spring.quartz.properties を介してスケジューラーを構成する方法を提供するため、Executor Bean はスケジューラーに関連付けられていません。タスクエグゼキューターをカスタマイズする必要がある場合は、SchedulerFactoryBeanCustomizer の実装を検討してください。

ジョブは、setter を定義してデータマッププロパティを挿入できます。次の例に示すように、通常の Bean も同様の方法で注入できます。

public class SampleJob extends QuartzJobBean {

    private MyService myService;

    private String name;

    // Inject "MyService" bean
    public void setMyService(MyService myService) { ... }

    // Inject the "name" job data property
    public void setName(String name) { ... }

    @Override
    protected void executeInternal(JobExecutionContext context)
            throws JobExecutionException {
        ...
    }

}

22. タスクの実行とスケジューリング

コンテキストに Executor Bean がない場合、Spring Boot は、非同期タスク実行(@EnableAsync)および Spring MVC 非同期リクエスト処理に自動的に関連付けることができる実用的なデフォルトで ThreadPoolTaskExecutor を自動構成します。

コンテキストでカスタム Executor を定義した場合、通常のタスク実行(つまり @EnableAsync)はそれを透過的に使用しますが、AsyncTaskExecutor 実装(applicationTaskExecutor という名前)が必要なため、Spring MVC サポートは構成されません。ターゲットの配置に応じて、Executor を ThreadPoolTaskExecutor に変更するか、カスタム Executor をラップする ThreadPoolTaskExecutor と AsyncConfigurer の両方を定義できます。

自動構成された TaskExecutorBuilder を使用すると、自動構成がデフォルトで行うことを再現するインスタンスを簡単に作成できます。

スレッドプールは、負荷に応じて拡大および縮小できる 8 つのコアスレッドを使用します。これらのデフォルト設定は、次の例に示すように、spring.task.execution 名前空間を使用して微調整できます。

spring.task.execution.pool.max-size=16
spring.task.execution.pool.queue-capacity=100
spring.task.execution.pool.keep-alive=10s

これにより、キューがいっぱい(100 タスク)になったときにスレッドプールが最大 16 スレッドに増加するように、スレッドプールが制限キューを使用するように変更されます。プールの縮小は、スレッドが 10 秒間(デフォルトでは 60 秒ではなく)アイドル状態のときに回収されるため、より積極的です。

スケジュールされたタスクの実行(@EnableScheduling)に関連付ける必要がある場合は、ThreadPoolTaskScheduler を自動構成することもできます。スレッドプールはデフォルトで 1 つのスレッドを使用し、これらの設定は spring.task.scheduling 名前空間を使用して微調整できます。

カスタム executor またはスケジューラーを作成する必要がある場合、コンテキストで TaskExecutorBuilder Bean と TaskSchedulerBuilder Bean の両方が使用可能になります。

23. Spring Integration

Spring Boot は、spring-boot-starter-integration 「スターター」を含む、Spring Integration で作業するためのいくつかの便利な機能を提供します。Spring Integration は、メッセージング、および HTTP、TCP などのその他のトランスポートを抽象化します。Spring Integration がクラスパスで使用可能な場合、@EnableIntegration アノテーションを介して初期化されます。

Spring Boot は、追加の Spring Integration モジュールの存在によってトリガーされるいくつかの機能も構成します。spring-integration-jmx もクラスパス上にある場合、メッセージ処理統計は JMX を介して公開されます。spring-integration-jdbc が利用可能な場合、次の行に示すように、起動時にデフォルトのデータベーススキーマを作成できます。

spring.integration.jdbc.initialize-schema=always

spring-integration-rsocket が使用可能な場合、開発者は "spring.rsocket.server.*" プロパティを使用して RSocket サーバーを構成し、IntegrationRSocketEndpoint または RSocketOutboundGateway コンポーネントを使用して受信 RSocket メッセージを処理できます。このインフラストラクチャは、Spring Integration RSocket チャネルアダプターと @MessageMapping ハンドラーを処理できます("spring.integration.rsocket.server.message-mapping-enabled" が構成されている場合)。

Spring Boot は、構成プロパティを使用して ClientRSocketConnector を自動構成することもできます。

# Connecting to a RSocket server over TCP
spring.integration.rsocket.client.host=example.org
spring.integration.rsocket.client.port=9898

# Connecting to a RSocket Server over WebSocket
spring.integration.rsocket.client.uri=ws://example.org

詳細については、IntegrationAutoConfiguration (GitHub) および IntegrationProperties (GitHub) クラスを参照してください。

デフォルトでは、Micrometer meterRegistry Bean が存在する場合、Spring Integration メトリックは Micrometer によって管理されます。レガシー Spring Integration メトリックを使用する場合は、DefaultMetricsFactory Bean をアプリケーションコンテキストに追加します。

24. Spring Session

Spring Boot は、広範囲のデータストアに Spring Session 自動構成を提供します。サーブレット Web アプリケーションを構築する場合、次のストアを自動構成できます。

  • JDBC

  • Redis

  • Hazelcast

  • MongoDB

リアクティブ Web アプリケーションを構築する場合、次のストアを自動構成できます。

  • Redis

  • MongoDB

単一の Spring Session モジュールがクラスパスに存在する場合、Spring Boot はそのストア実装を自動的に使用します。実装が複数ある場合は、セッションの保存に使用する StoreType (GitHub) を選択する必要があります。たとえば、JDBC をバックエンドストアとして使用するには、次のようにアプリケーションを構成できます。

spring.session.store-type=jdbc
store-type を none に設定することにより、Spring Session を無効にできます。

各ストアには特定の追加設定があります。たとえば、次の例に示すように、JDBC ストアのテーブルの名前をカスタマイズできます。

spring.session.jdbc.table-name=SESSIONS

セッションのタイムアウトを設定するには、spring.session.timeout プロパティを使用できます。そのプロパティが設定されていない場合、自動構成は server.servlet.session.timeout の値にフォールバックします。

25. JMX を介した監視と管理

Java Management Extensions(JMX)は、アプリケーションを監視および管理するための標準メカニズムを提供します。Spring Boot は、ID が mbeanServer の Bean として最適な MBeanServer を公開します。Spring JMX アノテーション(@ManagedResource@ManagedAttribute、または @ManagedOperation)でアノテーションが付けられた Bean はすべて公開されます。

プラットフォームが標準の MBeanServer を提供する場合、Spring Boot はそれを使用し、必要に応じてデフォルトで VM MBeanServer を使用します。すべてが失敗すると、新しい MBeanServer が作成されます。

詳細については、JmxAutoConfiguration (GitHub) クラスを参照してください。

26. テスト

Spring Boot は、アプリケーションをテストするときに役立つ多くのユーティリティとアノテーションを提供します。テストサポートは 2 つのモジュールによって提供されます。spring-boot-test にはコアアイテムが含まれ、spring-boot-test-autoconfigure はテストの自動構成をサポートします。

ほとんどの開発者は、Spring Boot テストモジュールと JUnit Jupiter、AssertJ、Hamcrest、およびその他の便利なライブラリの両方をインポートする spring-boot-starter-test “ Starter ”を使用します。

また、スターターは Vintage エンジンを提供するため、JUnit 4 と JUnit 5 の両方のテストを実行できます。テストを JUnit 5 に移行した場合、次の例に示すように、JUnit 4 サポートを除外する必要があります。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
        </exclusion>
    </exclusions>
</dependency>

26.1. テスト範囲の依存関係

spring-boot-starter-test 「スターター」(testscope 内)には、以下の提供ライブラリが含まれています。

  • JUnit 5 (英語) (JUnit 4 との後方互換性のための Vintage エンジンを含む):Java アプリケーションの単体テストのための事実上の標準。

  • Spring テストおよび Spring Boot テスト:Spring Boot アプリケーションのユーティリティおよび統合テストのサポート。

  • AssertJ (英語) : 流れるようなアサーションライブラリ。

  • Hamcrest (GitHub) : マッチャーオブジェクトのライブラリ(制約または述語として知られる)。

  • Mockito (英語) : Java モックフレームワーク。

  • JSONassert (GitHub) : JSON のアサーションライブラリ。

  • JsonPath (GitHub) : JSON の XPath。

通常、これらの一般的なライブラリは、テストを作成するときに役立つことがわかります。これらのライブラリがニーズに合わない場合は、独自のテスト依存関係を追加できます。

26.2. Spring アプリケーションのテスト

依存性注入の主な利点の 1 つは、コードを単体テストしやすくすることです。Spring を使用しなくても、new 演算子を使用してオブジェクトをインスタンス化できます。実際の依存関係の代わりにモックオブジェクトを使用することもできます

多くの場合、単体テストを超えて統合テストを開始する必要があります(Spring ApplicationContext を使用)。アプリケーションのデプロイを必要とせずに、または他のインフラストラクチャに接続する必要なく、統合テストを実行できると便利です。

Spring Framework には、このような統合テスト専用のテストモジュールが含まれています。org.springframework:spring-test に直接依存関係を宣言するか、spring-boot-starter-test 「スターター」を使用して依存関係を一時的にプルできます。

spring-test モジュールを使用したことがない場合は、Spring Framework リファレンスドキュメントの関連セクションを読むことから始めてください。

26.3. Spring Boot アプリケーションのテスト

Spring Boot アプリケーションは Spring ApplicationContext であるため、バニラ Spring コンテキストで通常行うことを超えてテストするために特別なことは何もする必要はありません。

Spring Boot の外部プロパティ、ロギング、およびその他の機能は、SpringApplication を使用して作成する場合にのみ、デフォルトでコンテキストにインストールされます。

Spring Boot は @SpringBootTest アノテーションを提供します。これは、Spring Boot 機能が必要な場合に標準の spring-test@ContextConfiguration アノテーションの代替として使用できます。アノテーションは、SpringApplication を使用してテストで使用される ApplicationContext を作成することにより機能します@SpringBootTest に加えて、アプリケーションのより具体的なスライスをテストするために、他の多くのアノテーションも提供されています。

JUnit 4 を使用している場合は、@RunWith(SpringRunner.class) もテストに追加することを忘れないでください。追加しないと、アノテーションは無視されます。JUnit 5 を使用している場合、同等の @ExtendWith(SpringExtension.class) を @SpringBootTest として追加する必要はなく、他の @ … Test アノテーションには既にアノテーションが付けられています。

デフォルトでは、@SpringBootTest はサーバーを起動しません。@SpringBootTest の webEnvironment 属性を使用して、テストの実行方法をさらに絞り込むことができます。

  • MOCK(デフォルト): Web ApplicationContext をロードし、モック Web 環境を提供します。このアノテーションを使用すると、組み込みサーバーは起動しません。Web 環境がクラスパスで利用できない場合、このモードは通常の非 Web ApplicationContext の作成に透過的にフォールバックします。Web アプリケーションのモックベースのテストのために、@AutoConfigureMockMvc または @AutoConfigureWebTestClient と組み合わせて使用できます。

  • RANDOM_PORTWebServerApplicationContext をロードし、実際の Web 環境を提供します。組み込みサーバーが起動され、ランダムポートでリッスンします。

  • DEFINED_PORTWebServerApplicationContext をロードし、実際の Web 環境を提供します。組み込みサーバーが開始され、定義済みのポート(application.properties から)またはデフォルトのポート 8080 で listen します。

  • NONESpringApplication を使用して ApplicationContext をロードしますが Web 環境(モックまたはその他)を提供しません。

テストが @Transactional の場合、デフォルトで各テストメソッドの最後にトランザクションをロールバックします。ただし、RANDOM_PORT または DEFINED_PORT のいずれかでこの配置を使用すると、実際のサーブレット環境が暗黙的に提供されるため、HTTP クライアントとサーバーは別々のスレッドで、別々のトランザクションで実行されます。この場合、サーバーで開始されたトランザクションはロールバックしません。
@SpringBootTest と webEnvironment = WebEnvironment.RANDOM_PORT は、アプリケーションが管理サーバーに異なるポートを使用している場合、別のランダムポートで管理サーバーを起動します。

26.3.1. Web アプリケーションタイプの検出

Spring MVC が利用可能な場合、通常の MVC ベースのアプリケーションコンテキストが設定されます。Spring と WebFlux しかない場合は、それを検出し、代わりに WebFlux ベースのアプリケーションコンテキストを構成します。

両方が存在する場合、Spring MVC が優先されます。このシナリオでリアクティブ Web アプリケーションをテストする場合は、spring.main.web-application-type プロパティを設定する必要があります。

@SpringBootTest(properties = "spring.main.web-application-type=reactive")
class MyWebFluxTests { ... }

26.3.2. テスト構成の検出

Spring テストフレームワークに精通している場合、どの Spring @Configuration をロードするかを指定するために @ContextConfiguration(classes=…​) を使用することに慣れているかもしれません。あるいは、テスト内でネストされた @Configuration クラスを頻繁に使用した可能性があります。

Spring Boot アプリケーションをテストする場合、これは多くの場合必要ありません。Spring Boot の @*Test アノテーションは、明示的に定義しない限り、プライマリ設定を自動的に検索します。

検索アルゴリズムは、@SpringBootApplication または @SpringBootConfiguration アノテーションが付けられたクラスを見つけるまで、テストを含むパッケージから機能します。実用的なメソッドでコードを構造化する限り、通常、メイン構成が見つかります。

@SpringBootApplication の基礎となるコンポーネントスキャン構成は、スライシングが期待どおりに機能することを確認するために使用される除外フィルターを定義します。@SpringBootApplication アノテーション付きクラスで明示的な @ComponentScan ディレクティブを使用している場合、これらのフィルターが無効になることに注意してください。スライスを使用している場合は、再度定義する必要があります。

プライマリ設定をカスタマイズする場合は、ネストされた @TestConfiguration クラスを使用できます。アプリケーションのプライマリ設定の代わりに使用されるネストされた @Configuration クラスとは異なり、ネストされた @TestConfiguration クラスはアプリケーションのプライマリ設定に加えて使用されます。

Spring のテストフレームワークは、テスト間のアプリケーションコンテキストをキャッシュします。テストが同じ構成を共有している限り(検出方法に関係なく)、コンテキストをロードする潜在的に時間のかかるプロセスは 1 回しか発生しません。

26.3.3. テスト構成の除外

アプリケーションがコンポーネントスキャンを使用している場合(たとえば、@SpringBootApplication または @ComponentScan を使用している場合)、特定のテスト用に作成した最上位の構成クラスが誤ってどこでも取得される可能性があります。

前に見たように、@TestConfiguration をテストの内部クラスで使用して、プライマリ構成をカスタマイズできます。@TestConfiguration は、最上位クラスに配置されると、src/test/java のクラスをスキャンで取得しないことを示します。その後、次の例に示すように、必要な場所にそのクラスを明示的にインポートできます。

@SpringBootTest
@Import(MyTestsConfiguration.class)
class MyTests {

    @Test
    void exampleTest() {
        ...
    }

}
@ComponentScan を直接使用する場合(つまり、@SpringBootApplication を使用しない場合)、TypeExcludeFilter を登録する必要があります。詳細については、Javadoc を参照してください。

26.3.4. アプリケーション引数の使用

アプリケーションで引数が必要な場合は、args 属性を使用して @SpringBootTest に引数を注入させることができます。

@SpringBootTest(args = "--app.test=one")
class ApplicationArgumentsExampleTests {

    @Test
    void applicationArgumentsPopulated(@Autowired ApplicationArguments args) {
        assertThat(args.getOptionNames()).containsOnly("app.test");
        assertThat(args.getOptionValues("app.test")).containsOnly("one");
    }

}

26.3.5. モック環境でのテスト

デフォルトでは、@SpringBootTest はサーバーを起動しません。このモック環境に対してテストする Web エンドポイントがある場合、次の例に示すように MockMvc を追加で構成できます。

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
class MockMvcExampleTests {

    @Test
    void exampleTest(@Autowired MockMvc mvc) throws Exception {
        mvc.perform(get("/")).andExpect(status().isOk()).andExpect(content().string("Hello World"));
    }

}
完全な ApplicationContext を開始せずに Web レイヤーのみに焦点を合わせたい場合は、代わりに @WebMvcTest の使用を検討してください

または、次の例に示すように WebTestClient を構成できます。

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.reactive.server.WebTestClient;

@SpringBootTest
@AutoConfigureWebTestClient
class MockWebTestClientExampleTests {

    @Test
    void exampleTest(@Autowired WebTestClient webClient) {
        webClient.get().uri("/").exchange().expectStatus().isOk().expectBody(String.class).isEqualTo("Hello World");
    }

}

モック環境内でのテストは、通常、完全なサーブレットコンテナーで実行するよりも高速です。ただし、モックは Spring MVC レイヤーで発生するため、下位レベルのサーブレットコンテナーの動作に依存するコードは MockMvc で直接テストできません。

例:Spring Boot のエラー処理は、サーブレットコンテナーによって提供される「エラーページ」サポートに基づいています。これは、MVC レイヤーが期待どおりに例外をスローおよび処理することをテストできますが、特定のカスタムエラーページがレンダリングされることを直接テストできないことを意味します。これらの下位レベルの懸念事項をテストする必要がある場合は、次のセクションで説明するように、完全に実行されているサーバーを起動できます。

26.3.6. 実行中のサーバーでテストする

完全に稼働しているサーバーを起動する必要がある場合は、ランダムなポートを使用することをお勧めします。@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) を使用すると、テストを実行するたびに使用可能なポートがランダムに選択されます。

@LocalServerPort アノテーションを使用して、テストに実際に使用されるポートを挿入できます。便宜上、開始されたサーバーに対して REST 呼び出しを行う必要があるテストでは、@Autowire に WebTestClient を追加できます。これは、実行中のサーバーへの相対リンクを解決し、次の例に示すように、レスポンスを検証する専用 API を備えています:

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.web.reactive.server.WebTestClient;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class RandomPortWebTestClientExampleTests {

    @Test
    void exampleTest(@Autowired WebTestClient webClient) {
        webClient.get().uri("/").exchange().expectStatus().isOk().expectBody(String.class).isEqualTo("Hello World");
    }

}

このセットアップでは、クラスパスに spring-webflux が必要です。Webflux を追加できない場合、または追加しない場合、Spring Boot は TestRestTemplate 機能も提供します。

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class RandomPortTestRestTemplateExampleTests {

    @Test
    void exampleTest(@Autowired TestRestTemplate restTemplate) {
        String body = restTemplate.getForObject("/", String.class);
        assertThat(body).isEqualTo("Hello World");
    }

}

26.3.7. WebTestClient のカスタマイズ

WebTestClient Bean をカスタマイズするには、WebTestClientBuilderCustomizer Bean を構成します。このような Bean は、WebTestClient の作成に使用される WebTestClient.Builder で呼び出されます。

26.3.8. JMX を使用する

テストコンテキストフレームワークはコンテキストをキャッシュするため、JMX はデフォルトで無効になり、同一ドメインに同一のコンポーネントが登録されないようにします。そのようなテストが MBeanServer にアクセスする必要がある場合、同様にダーティマークを付けることを検討してください。

@ExtendWith(SpringExtension.class)
@SpringBootTest(properties = "spring.jmx.enabled=true")
@DirtiesContext
class SampleJmxTests {

    @Autowired
    private MBeanServer mBeanServer;

    @Test
    void exampleTest() {
        // ...
    }

}

26.3.9. Bean のモックとスパイ

テストを実行するとき、アプリケーションコンテキスト内の特定のコンポーネントをモックする必要がある場合があります。例:開発中は利用できないリモートサービスのファサードがある場合があります。モックは、実際の環境では引き起こしにくい障害をシミュレートする場合にも役立ちます。

Spring Boot には、ApplicationContext 内の Bean の Mockito モックを定義するために使用できる @MockBean アノテーションが含まれています。アノテーションを使用して、新しい Bean を追加したり、単一の既存の Bean 定義を置き換えることができます。アノテーションは、テストクラス、テスト内のフィールド、または @Configuration クラスとフィールドで直接使用できます。フィールドで使用すると、作成されたモックのインスタンスも注入されます。モック Bean は、各テストメソッドの後に自動的にリセットされます。

テストで Spring Boot のテストアノテーションの 1 つ(@SpringBootTest など)を使用する場合、この機能は自動的に有効になります。別の配置でこの機能を使用するには、次の例に示すように、リスナーを明示的に追加する必要があります。

@TestExecutionListeners(MockitoTestExecutionListener.class)

次の例では、既存の RemoteService Bean をモック実装に置き換えます。

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.context.*;
import org.springframework.boot.test.mock.mockito.*;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;

@SpringBootTest
class MyTests {

    @MockBean
    private RemoteService remoteService;

    @Autowired
    private Reverser reverser;

    @Test
    void exampleTest() {
        // RemoteService has been injected into the reverser bean
        given(this.remoteService.someCall()).willReturn("mock");
        String reverse = reverser.reverseSomeCall();
        assertThat(reverse).isEqualTo("kcom");
    }

}
@MockBean を使用して、アプリケーションコンテキストのリフレッシュ中に実行される Bean の動作をモックすることはできません。テストが実行されるまでに、アプリケーションコンテキストのリフレッシュが完了し、モック動作を構成するには遅すぎます。この状況では、@Bean メソッドを使用してモックを作成および構成することをお勧めします。

さらに、@SpyBean を使用して、既存の Bean を Mockito spy でラップすることができます。詳細については、Javadoc を参照してください。

スコープ付き Bean 用に作成されたものなどの CGLib プロキシは、プロキシされたメソッドを final として宣言します。これにより、Mockito はデフォルト設定で final メソッドをモックまたはスパイできないため、Mockito が正しく機能しなくなります。このような Bean をモックまたはスパイしたい場合は、org.mockito:mockito-inline をアプリケーションのテスト依存関係に追加して、Mockito がインラインモックメーカーを使用するように構成します。これにより、Mockito は final メソッドをモックおよびスパイできます。
Spring のテストフレームワークはテスト間でアプリケーションコンテキストをキャッシュし、同じ構成を共有するテストでコンテキストを再利用しますが、@MockBean または @SpyBean の使用はキャッシュキーに影響し、コンテキストの数を増やす可能性が高くなります。
@SpyBean を使用して、名前でパラメーターを参照する @Cacheable メソッドで Bean をスパイする場合、アプリケーションは -parameters でコンパイルする必要があります。これにより、Bean がスパイされると、パラメーター名がキャッシュインフラストラクチャで使用可能になります。
@SpyBean を使用して、Spring によってプロキシされている Bean をスパイしている場合、given または when を使用して期待値を設定する場合など、状況によっては Spring のプロキシを削除する必要がある場合があります。これを行うには、AopTestUtils.getTargetObject(yourProxiedSpy) を使用します。

26.3.10. 自動構成されたテスト

Spring Boot の自動構成システムは、アプリケーションではうまく機能しますが、テストでは少し大きすぎる場合があります。多くの場合、アプリケーションの「スライス」をテストするために必要な構成の部分のみをロードすると役立ちます。例:Spring MVC コントローラーが URL を正しくマッピングしていることをテストしたい場合があり、それらのテストにデータベース呼び出しを含めたくない場合、または JPA エンティティをテストしたい場合、それらのテスト時に Web レイヤーに関心がない場合実行。

spring-boot-test-autoconfigure モジュールには、このような「スライス」を自動的に構成するために使用できる多くのアノテーションが含まれています。それぞれが同様に機能し、ApplicationContext をロードする @…​Test アノテーションと、自動構成設定のカスタマイズに使用できる 1 つ以上の @AutoConfigure…​ アノテーションを提供します。

各スライスは、コンポーネントスキャンを適切なコンポーネントに制限し、非常に制限された自動構成クラスのセットをロードします。それらのいずれかを除外する必要がある場合、ほとんどの @…​Test アノテーションは excludeAutoConfiguration 属性を提供します。または、@ImportAutoConfiguration#exclude を使用できます。
1 つのテストで複数の @…​Test アノテーションを使用して複数の「スライス」を含めることはサポートされていません。複数の「スライス」が必要な場合は、@…​Test アノテーションの 1 つを選択し、他の「スライス」の @AutoConfigure…​ アノテーションを手動で含めます。
@AutoConfigure…​ アノテーションを標準の @SpringBootTest アノテーションとともに使用することもできます。アプリケーションの「スライス」に興味はないが、自動構成されたテスト Bean の一部が必要な場合は、この組み合わせを使用できます。

26.3.11. 自動構成された JSON テスト

オブジェクトの JSON 直列化と逆直列化が期待どおりに機能することをテストするには、@JsonTest アノテーションを使用できます。@JsonTest は、使用可能なサポートされている JSON マッパーを自動構成します。これは、次のライブラリのいずれかです。

  • Jackson ObjectMapper@JsonComponent Bean および Jackson Modules

  • Gson

  • Jsonb

@JsonTest によって有効にされる自動構成のリストは、付録に記載されています。

自動構成の要素を構成する必要がある場合は、@AutoConfigureJsonTesters アノテーションを使用できます。

Spring Boot には、JSONAssert および JsonPath ライブラリと連携して JSON が期待どおりに表示されることを確認する AssertJ ベースのヘルパーが含まれています。JacksonTesterGsonTesterJsonbTester および BasicJsonTester クラスは、それぞれ Jackson、Gson、Jsonb、および Strings に使用できます。@JsonTest を使用する場合、テストクラスのヘルパーフィールドは @Autowired になります。次の例は、Jackson のテストクラスを示しています。

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.json.*;
import org.springframework.boot.test.context.*;
import org.springframework.boot.test.json.*;

import static org.assertj.core.api.Assertions.*;

@JsonTest
class MyJsonTests {

    @Autowired
    private JacksonTester<VehicleDetails> json;

    @Test
    void testSerialize() throws Exception {
        VehicleDetails details = new VehicleDetails("Honda", "Civic");
        // Assert against a `.json` file in the same package as the test
        assertThat(this.json.write(details)).isEqualToJson("expected.json");
        // Or use JSON path based assertions
        assertThat(this.json.write(details)).hasJsonPathStringValue("@.make");
        assertThat(this.json.write(details)).extractingJsonPathStringValue("@.make")
                .isEqualTo("Honda");
    }

    @Test
    void testDeserialize() throws Exception {
        String content = "{\"make\":\"Ford\",\"model\":\"Focus\"}";
        assertThat(this.json.parse(content))
                .isEqualTo(new VehicleDetails("Ford", "Focus"));
        assertThat(this.json.parseObject(content).getMake()).isEqualTo("Ford");
    }

}
JSON ヘルパークラスは、標準の単体テストで直接使用することもできます。これを行うには、@JsonTest を使用しない場合、@Before メソッドでヘルパーの initFields メソッドを呼び出します。

Spring Boot の AssertJ ベースのヘルパーを使用して、特定の JSON パスで数値をアサートする場合、タイプによっては isEqualTo を使用できない場合があります。代わりに、AssertJ の satisfies を使用して、値が指定された条件に一致することをアサートできます。たとえば、次の例では、実際の数値が 0.01 のオフセット内で 0.15 に近い浮動小数点値であることを表明しています。

assertThat(json.write(message))
    .extractingJsonPathNumberValue("@.test.numberValue")
    .satisfies((number) -> assertThat(number.floatValue()).isCloseTo(0.15f, within(0.01f)));

26.3.12. 自動構成された Spring MVC テスト

Spring MVC コントローラーが期待どおりに機能しているかどうかをテストするには、@WebMvcTest アノテーションを使用します。@WebMvcTest は、Spring MVC インフラストラクチャを自動構成し、スキャンされる Bean を @Controller@ControllerAdvice@JsonComponentConverterGenericConverterFilterHandlerInterceptorWebMvcConfigurer および HandlerMethodArgumentResolver に制限します。@WebMvcTest アノテーションが使用されている場合、通常の @Component および @ConfigurationProperties Bean はスキャンされません。@EnableConfigurationProperties を使用して、@ConfigurationProperties Bean を含めることができます。

@WebMvcTest によって有効にされる自動構成設定のリストは、付録に記載されています。
Jackson Module などの追加コンポーネントを登録する必要がある場合は、テストで @Import を使用して追加の構成クラスをインポートできます。

多くの場合、@WebMvcTest は単一のコントローラーに限定され、@MockBean と組み合わせて使用され、必要なコラボレーターにモック実装を提供します。

@WebMvcTest は MockMvc も自動構成します。Mock MVC は、完全な HTTP サーバーを起動する必要なく、MVC コントローラーをすばやくテストする強力な方法を提供します。

@AutoConfigureMockMvc でアノテーションを付けることにより、非 @WebMvcTest (@SpringBootTest など)で MockMvc を自動構成することもできます。次の例では、MockMvc を使用しています。
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.web.servlet.*;
import org.springframework.boot.test.mock.mockito.*;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@WebMvcTest(UserVehicleController.class)
class MyControllerTests {

    @Autowired
    private MockMvc mvc;

    @MockBean
    private UserVehicleService userVehicleService;

    @Test
    void testExample() throws Exception {
        given(this.userVehicleService.getVehicleDetails("sboot"))
                .willReturn(new VehicleDetails("Honda", "Civic"));
        this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
                .andExpect(status().isOk()).andExpect(content().string("Honda Civic"));
    }

}
自動構成の要素を構成する必要がある場合(たとえば、サーブレットフィルターを適用する必要がある場合)、@AutoConfigureMockMvc アノテーションの属性を使用できます。

HtmlUnit または Selenium を使用する場合、自動構成は HtmlUnit WebClient Bean および / または Selenium WebDriver Bean も提供します。次の例では、HtmlUnit を使用しています。

import com.gargoylesoftware.htmlunit.*;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.web.servlet.*;
import org.springframework.boot.test.mock.mockito.*;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;

@WebMvcTest(UserVehicleController.class)
class MyHtmlUnitTests {

    @Autowired
    private WebClient webClient;

    @MockBean
    private UserVehicleService userVehicleService;

    @Test
    void testExample() throws Exception {
        given(this.userVehicleService.getVehicleDetails("sboot"))
                .willReturn(new VehicleDetails("Honda", "Civic"));
        HtmlPage page = this.webClient.getPage("/sboot/vehicle.html");
        assertThat(page.getBody().getTextContent()).isEqualTo("Honda Civic");
    }

}
デフォルトでは、Spring Boot は WebDriver Bean を特別な「スコープ」に入れて、各テスト後にドライバーが終了し、新しいインスタンスが挿入されるようにします。この動作が望ましくない場合は、@Scope("singleton") を WebDriver@Bean 定義に追加できます。
Spring Boot によって作成された webDriver スコープは、同じ名前のユーザー定義スコープを置き換えます。独自の webDriver スコープを定義すると、@WebMvcTest を使用すると動作が停止する場合があります。

クラスパスに Spring Security がある場合、@WebMvcTest は WebSecurityConfigurer Bean もスキャンします。そのようなテストのセキュリティを完全に無効にする代わりに、Spring Security のテストサポートを使用できます。Spring Security の MockMvc サポートの使用方法の詳細については、この howto.html使い方セクションを参照してください。

Spring MVC テストを書くだけでは十分でない場合があります。Spring Boot は、実際のサーバーで完全なエンドツーエンドテストを実行するのに役立ちます。

26.3.13. 自動構成された Spring WebFlux テスト

Spring WebFlux コントローラーが期待どおりに動作していることをテストするには、@WebFluxTest アノテーションを使用できます。@WebFluxTest は Spring WebFlux インフラストラクチャを自動構成し、スキャンされる Bean を @Controller@ControllerAdvice@JsonComponentConverterGenericConverterWebFilter および WebFluxConfigurer に制限します。@WebFluxTest アノテーションが使用されている場合、通常の @Component および @ConfigurationProperties Bean はスキャンされません。@EnableConfigurationProperties を使用して、@ConfigurationProperties Bean を含めることができます。

@WebFluxTest によって有効にされる自動構成のリストは、付録に記載されています。
Jackson Module などの追加コンポーネントを登録する必要がある場合は、テストで @Import を使用して追加の構成クラスをインポートできます。

多くの場合、@WebFluxTest は単一のコントローラーに限定され、@MockBean アノテーションと組み合わせて使用され、必要なコラボレーターにモック実装を提供します。

@WebFluxTest は WebTestClient も自動構成します。これにより、完全な HTTP サーバーを起動する必要なく、WebFlux コントローラーを迅速にテストする強力な方法が提供されます。

@AutoConfigureWebTestClient でアノテーションを付けることにより、非 @WebFluxTest (@SpringBootTest など)で WebTestClient を自動構成することもできます。次の例は、@WebFluxTest と WebTestClient の両方を使用するクラスを示しています。
import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.reactive.server.WebTestClient;

@WebFluxTest(UserVehicleController.class)
class MyControllerTests {

    @Autowired
    private WebTestClient webClient;

    @MockBean
    private UserVehicleService userVehicleService;

    @Test
    void testExample() throws Exception {
        given(this.userVehicleService.getVehicleDetails("sboot"))
                .willReturn(new VehicleDetails("Honda", "Civic"));
        this.webClient.get().uri("/sboot/vehicle").accept(MediaType.TEXT_PLAIN)
                .exchange()
                .expectStatus().isOk()
                .expectBody(String.class).isEqualTo("Honda Civic");
    }

}
モック Web アプリケーションで WebTestClient を使用するのは、現時点では WebFlux でのみ機能するため、このセットアップは WebFlux アプリケーションでのみサポートされます。
@WebFluxTest は、関数 Web フレームワークを介して登録されたルートを検出できません。コンテキストで RouterFunction Bean をテストするには、@Import または @SpringBootTest を使用して、RouterFunction を自分でインポートすることを検討してください。
@WebFluxTest は、タイプ SecurityWebFilterChain の @Bean を介して登録されたカスタムセキュリティ構成を検出できません。これをテストに含めるには、@Import 経由で Bean を登録する構成をインポートするか、@SpringBootTest を使用する必要があります。
Spring WebFlux テストを書くだけでは十分でない場合があります。Spring Boot は、実際のサーバーで完全なエンドツーエンドテストを実行するのに役立ちます。

26.3.14. 自動構成されたデータ JPA テスト

@DataJpaTest アノテーションを使用して、JPA アプリケーションをテストできます。デフォルトでは、@Entity クラスをスキャンし、Spring Data JPA リポジトリを構成します。組み込みデータベースがクラスパスで使用可能な場合は、それも構成します。@DataJpaTest アノテーションが使用されている場合、通常の @Component および @ConfigurationProperties Bean はスキャンされません。@EnableConfigurationProperties を使用して、@ConfigurationProperties Bean を含めることができます。

@DataJpaTest によって有効にされる自動構成設定のリストは、付録に記載されています。

デフォルトでは、データ JPA テストはトランザクションであり、各テストの終了時にロールバックされます。詳細については、Spring Framework リファレンスドキュメントの関連セクションを参照してください。それが望んでいない場合、次のようにテストまたはクラス全体のトランザクション管理を無効にできます。

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@DataJpaTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class ExampleNonTransactionalTests {

}

データ JPA テストは、TestEntityManager (GitHub) Bean を挿入することもできます。これは、テスト用に特別に設計された標準の JPA EntityManager の代替を提供します。@DataJpaTest インスタンスの外部で TestEntityManager を使用する場合は、@AutoConfigureTestEntityManager アノテーションも使用できます。JdbcTemplate も必要な場合に利用できます。次の例は、使用中の @DataJpaTest アノテーションを示しています。

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.orm.jpa.*;

import static org.assertj.core.api.Assertions.*;

@DataJpaTest
class ExampleRepositoryTests {

    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private UserRepository repository;

    @Test
    void testExample() throws Exception {
        this.entityManager.persist(new User("sboot", "1234"));
        User user = this.repository.findByUsername("sboot");
        assertThat(user.getUsername()).isEqualTo("sboot");
        assertThat(user.getVin()).isEqualTo("1234");
    }

}

メモリ内の組み込みデータベースは、高速でインストールを必要としないため、一般にテストに適しています。ただし、次の例に示すように、実際のデータベースに対してテストを実行する場合は、@AutoConfigureTestDatabase アノテーションを使用できます。

@DataJpaTest
@AutoConfigureTestDatabase(replace=Replace.NONE)
class ExampleRepositoryTests {

    // ...

}

26.3.15. 自動構成された JDBC テスト

@JdbcTest は @DataJpaTest に似ていますが、DataSource のみを必要とし、Spring Data JDBC を使用しないテスト用です。デフォルトでは、メモリ内埋め込みデータベースと JdbcTemplate を構成します。@JdbcTest アノテーションが使用されている場合、通常の @Component および @ConfigurationProperties Bean はスキャンされません。@EnableConfigurationProperties を使用して、@ConfigurationProperties Bean を含めることができます。

@JdbcTest によって有効にされる自動構成のリストは、付録に記載されています。

デフォルトでは、JDBC テストはトランザクション対応であり、各テストの終わりにロールバックします。詳細については、Spring Framework リファレンスドキュメントの関連セクションを参照してください。それが望んでいない場合は、次のように、テストまたはクラス全体のトランザクション管理を無効にできます。

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@JdbcTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class ExampleNonTransactionalTests {

}

テストを実際のデータベースに対して実行したい場合は、DataJpaTest と同じ方法で @AutoConfigureTestDatabase アノテーションを使用できます。(「自動構成されたデータ JPA テスト」を参照してください。)

26.3.16. 自動構成されたデータ JDBC テスト

@DataJdbcTest は @JdbcTest に似ていますが、Spring Data JDBC リポジトリを使用するテスト用です。デフォルトでは、メモリ内埋め込みデータベース、JdbcTemplate、および Spring Data JDBC リポジトリを構成します。@DataJdbcTest アノテーションが使用されている場合、通常の @Component および @ConfigurationProperties Bean はスキャンされません。@EnableConfigurationProperties を使用して、@ConfigurationProperties Bean を含めることができます。

@DataJdbcTest によって有効にされる自動構成のリストは、付録に記載されています。

デフォルトでは、データ JDBC テストはトランザクションであり、各テストの終了時にロールバックされます。詳細については、Spring Framework リファレンスドキュメントの関連セクションを参照してください。それが望んでいない場合、JDBC の例に示すように、テストまたはテストクラス全体のトランザクション管理を無効にすることができます。

テストを実際のデータベースに対して実行したい場合は、DataJpaTest と同じ方法で @AutoConfigureTestDatabase アノテーションを使用できます。(「自動構成されたデータ JPA テスト」を参照してください。)

26.3.17. 自動構成された jOOQ テスト

@JdbcTest と同様の方法で @JooqTest を使用できますが、jOOQ 関連のテストに使用できます。jOOQ はデータベーススキーマに対応する Java ベースのスキーマに大きく依存しているため、既存の DataSource が使用されます。これをインメモリデータベースに置き換える場合は、@AutoConfigureTestDatabase を使用してこれらの設定を上書きできます。(Spring Boot での jOOQ の使用の詳細については、この章の前半の「jOOQ を使用する」を参照してください) @JooqTest アノテーションが使用されている場合、通常の @Component および @ConfigurationProperties Bean はスキャンされません。@EnableConfigurationProperties を使用して、@ConfigurationProperties Bean を含めることができます。

@JooqTest によって有効にされる自動構成のリストは、付録に記載されています。

@JooqTest は DSLContext を構成します。次の例は、使用中の @JooqTest アノテーションを示しています。

import org.jooq.DSLContext;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.jooq.JooqTest;

@JooqTest
class ExampleJooqTests {

    @Autowired
    private DSLContext dslContext;
}

JOOQ テストはトランザクション対応であり、デフォルトでは各テストの終わりにロールバックします。それが望んでいない場合、JDBC の例に示すように、テストまたはテストクラス全体のトランザクション管理を無効にすることができます。

26.3.18. 自動構成されたデータ MongoDB テスト

@DataMongoTest を使用して MongoDB アプリケーションをテストできます。デフォルトでは、メモリに埋め込まれた MongoDB(利用可能な場合)を構成し、MongoTemplate を構成し、@Document クラスをスキャンし、Spring Data MongoDB リポジトリを構成します。@DataMongoTest アノテーションが使用されている場合、通常の @Component および @ConfigurationProperties Bean はスキャンされません。@EnableConfigurationProperties を使用して、@ConfigurationProperties Bean を含めることができます。(Spring Boot での MongoDB の使用の詳細については、この章で前述した「MongoDB」を参照してください。)

@DataMongoTest によって有効にされる自動構成設定のリストは、付録に記載されています。

次のクラスは、使用中の @DataMongoTest アノテーションを示しています。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.data.mongodb.core.MongoTemplate;

@DataMongoTest
class ExampleDataMongoTests {

    @Autowired
    private MongoTemplate mongoTemplate;

    //
}

メモリ内に埋め込まれた MongoDB は、高速で開発者がインストールする必要がないため、一般にテストに適しています。ただし、実際の MongoDB サーバーに対してテストを実行する場合は、次の例に示すように、組み込みの MongoDB 自動構成を除外する必要があります。

import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;

@DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class)
class ExampleDataMongoNonEmbeddedTests {

}

26.3.19. 自動構成されたデータ Neo4j テスト

@DataNeo4jTest を使用して Neo4j アプリケーションをテストできます。デフォルトでは、メモリ内の埋め込み Neo4j(埋め込みドライバーが使用可能な場合)を使用し、@NodeEntity クラスをスキャンして、Spring Data Neo4j リポジトリを構成します。@DataNeo4jTest アノテーションが使用されている場合、通常の @Component および @ConfigurationProperties Bean はスキャンされません。@EnableConfigurationProperties を使用して、@ConfigurationProperties Bean を含めることができます。(Neo4J を Spring Boot で使用する方法の詳細については、この章で前述した「Neo4j」を参照してください。)

@DataNeo4jTest によって有効にされる自動構成設定のリストは、付録に記載されています。

次の例は、Spring Boot で Neo4J テストを使用するための一般的なセットアップを示しています。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest;

@DataNeo4jTest
class ExampleDataNeo4jTests {

    @Autowired
    private YourRepository repository;

    //
}

デフォルトでは、Data Neo4j テストはトランザクション対応であり、各テストの終わりにロールバックします。詳細については、Spring Framework リファレンスドキュメントの関連セクションを参照してください。それが望んでいない場合は、次のように、テストまたはクラス全体のトランザクション管理を無効にできます。

import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@DataNeo4jTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class ExampleNonTransactionalTests {

}

26.3.20. 自動構成データ Redis テスト

@DataRedisTest を使用して Redis アプリケーションをテストできます。デフォルトでは、@RedisHash クラスをスキャンし、Spring Data Redis リポジトリを構成します。@DataRedisTest アノテーションが使用されている場合、通常の @Component および @ConfigurationProperties Bean はスキャンされません。@EnableConfigurationProperties を使用して、@ConfigurationProperties Bean を含めることができます。(Redis を Spring Boot とともに使用する方法の詳細については、この章で前述した「Redis」を参照してください。)

@DataRedisTest によって有効にされる自動構成設定のリストは、付録に記載されています。

次の例は、使用中の @DataRedisTest アノテーションを示しています。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.redis.DataRedisTest;

@DataRedisTest
class ExampleDataRedisTests {

    @Autowired
    private YourRepository repository;

    //
}

26.3.21. 自動構成データ LDAP テスト

@DataLdapTest を使用して LDAP アプリケーションをテストできます。デフォルトでは、インメモリ組み込み LDAP(使用可能な場合)を構成し、LdapTemplate を構成し、@Entry クラスをスキャンし、Spring Data LDAP リポジトリを構成します。@DataLdapTest アノテーションが使用されている場合、通常の @Component および @ConfigurationProperties Bean はスキャンされません。@EnableConfigurationProperties を使用して、@ConfigurationProperties Bean を含めることができます。(Spring Boot での LDAP の使用の詳細については、この章で前述した「LDAP」を参照してください。)

@DataLdapTest によって有効にされる自動構成設定のリストは、付録に記載されています。

次の例は、使用中の @DataLdapTest アノテーションを示しています。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest;
import org.springframework.ldap.core.LdapTemplate;

@DataLdapTest
class ExampleDataLdapTests {

    @Autowired
    private LdapTemplate ldapTemplate;

    //
}

メモリ内の組み込み LDAP は、高速であり、開発者がインストールする必要がないため、一般にテストに適しています。ただし、実際の LDAP サーバーに対してテストを実行する場合は、次の例に示すように、組み込みの LDAP 自動構成を除外する必要があります。

import org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration;
import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest;

@DataLdapTest(excludeAutoConfiguration = EmbeddedLdapAutoConfiguration.class)
class ExampleDataLdapNonEmbeddedTests {

}

26.3.22. 自動構成された REST クライアント

@RestClientTest アノテーションを使用して REST クライアントをテストできます。デフォルトでは、Jackson、GSON、および Jsonb のサポートを自動構成し、RestTemplateBuilder を構成して、MockRestServiceServer のサポートを追加します。@RestClientTest アノテーションが使用されている場合、通常の @Component および @ConfigurationProperties Bean はスキャンされません。@EnableConfigurationProperties を使用して、@ConfigurationProperties Bean を含めることができます。

@RestClientTest によって有効にされる自動構成設定のリストは、付録に記載されています。

テストする特定の Bean は、次の例に示すように、@RestClientTest の value または components 属性を使用して指定する必要があります。

@RestClientTest(RemoteVehicleDetailsService.class)
class ExampleRestClientTest {

    @Autowired
    private RemoteVehicleDetailsService service;

    @Autowired
    private MockRestServiceServer server;

    @Test
    void getVehicleDetailsWhenResultIsSuccessShouldReturnDetails()
            throws Exception {
        this.server.expect(requestTo("/greet/details"))
                .andRespond(withSuccess("hello", MediaType.TEXT_PLAIN));
        String greeting = this.service.callRestService();
        assertThat(greeting).isEqualTo("hello");
    }

}

26.3.23. 自動構成された Spring REST Docs テスト

@AutoConfigureRestDocs アノテーションを使用して、Mock MVC、REST Assured、または WebTestClient を使用したテストで Spring REST Docs を使用できます。Spring REST Docs の JUnit 拡張機能の必要性がなくなります。

@AutoConfigureRestDocs を使用して、デフォルトの出力ディレクトリをオーバーライドできます(Maven を使用している場合は target/generated-snippets、Gradle を使用している場合は build/generated-snippets)。また、ドキュメント化された URI に表示されるホスト、スキーム、およびポートの構成にも使用できます。

Mock MVC で自動構成された Spring REST Docs テスト

@AutoConfigureRestDocs は、サーブレットベースの Web アプリケーションをテストするときに Spring REST Docs を使用するように MockMvc Bean をカスタマイズします。次の例に示すように、モック MVC と Spring REST Docs を使用する場合と同じように、@Autowired を使用して注入し、テストで使用できます。

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@WebMvcTest(UserController.class)
@AutoConfigureRestDocs
class UserDocumentationTests {

    @Autowired
    private MockMvc mvc;

    @Test
    void listUsers() throws Exception {
        this.mvc.perform(get("/users").accept(MediaType.TEXT_PLAIN))
                .andExpect(status().isOk())
                .andDo(document("list-users"));
    }

}

@AutoConfigureRestDocs の属性で提供されるよりも Spring REST Docs 構成をより詳細に制御する必要がある場合は、次の例に示すように、RestDocsMockMvcConfigurationCustomizer Bean を使用できます。

@TestConfiguration
static class CustomizationConfiguration
        implements RestDocsMockMvcConfigurationCustomizer {

    @Override
    public void customize(MockMvcRestDocumentationConfigurer configurer) {
        configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
    }

}

パラメーター化された出力ディレクトリの Spring REST Docs サポートを利用する場合は、RestDocumentationResultHandler Bean を作成できます。自動構成は、この結果ハンドラーを使用して alwaysDo を呼び出します。これにより、各 MockMvc 呼び出しでデフォルトのスニペットが自動的に生成されます。次の例は、定義されている RestDocumentationResultHandler を示しています。

@TestConfiguration(proxyBeanMethods = false)
static class ResultHandlerConfiguration {

    @Bean
    public RestDocumentationResultHandler restDocumentation() {
        return MockMvcRestDocumentation.document("{method-name}");
    }

}
WebTestClient で自動構成された Spring REST Docs テスト

@AutoConfigureRestDocs は、リアクティブ Web アプリケーションをテストするときに WebTestClient と共に使用することもできます。次の例に示すように、@Autowired を使用して注入し、@WebFluxTest および Spring REST Docs を使用する場合と同じようにテストで使用できます。

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.test.web.reactive.server.WebTestClient;

import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.document;

@WebFluxTest
@AutoConfigureRestDocs
class UsersDocumentationTests {

    @Autowired
    private WebTestClient webTestClient;

    @Test
    void listUsers() {
        this.webTestClient.get().uri("/").exchange().expectStatus().isOk().expectBody()
                .consumeWith(document("list-users"));
    }

}

@AutoConfigureRestDocs の属性で提供されるよりも Spring REST Docs 構成をより詳細に制御する必要がある場合は、次の例に示すように、RestDocsWebTestClientConfigurationCustomizer Bean を使用できます。

@TestConfiguration(proxyBeanMethods = false)
public static class CustomizationConfiguration implements RestDocsWebTestClientConfigurationCustomizer {

    @Override
    public void customize(WebTestClientRestDocumentationConfigurer configurer) {
        configurer.snippets().withEncoding("UTF-8");
    }

}
REST Assured で自動構成された Spring REST Docs テスト

@AutoConfigureRestDocs は、Spring REST Docs を使用するように事前構成された RequestSpecification Bean をテストで使用できるようにします。次の例に示すように、REST Assured および Spring REST Docs を使用する場合と同様に、@Autowired を使用して注入し、テストで使用できます。

import io.restassured.specification.RequestSpecification;
import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.web.server.LocalServerPort;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.is;
import static org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.document;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureRestDocs
class UserDocumentationTests {

    @Test
    void listUsers(@Autowired RequestSpecification documentationSpec, @LocalServerPort int port) {
        given(documentationSpec).filter(document("list-users")).when().port(port).get("/").then().assertThat()
                .statusCode(is(200));
    }

}

@AutoConfigureRestDocs の属性で提供されるよりも Spring REST Docs 構成をより詳細に制御する必要がある場合、次の例に示すように、RestDocsRestAssuredConfigurationCustomizer Bean を使用できます。

@TestConfiguration(proxyBeanMethods = false)
public static class CustomizationConfiguration implements RestDocsRestAssuredConfigurationCustomizer {

    @Override
    public void customize(RestAssuredRestDocumentationConfigurer configurer) {
        configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
    }

}

26.3.24. 自動構成された Spring Web Services テスト

@WebServiceClientTest を使用すると、Spring Web Services プロジェクトを使用して Web サービスを呼び出すアプリケーションをテストできます。デフォルトでは、モック WebServiceServer Bean を構成し、WebServiceTemplateBuilder を自動的にカスタマイズします。(Spring Boot で Web サービスを使用する方法の詳細については、この章で前述した「Web サービス」を参照してください。)

@WebServiceClientTest によって有効にされる自動構成設定のリストは、付録に記載されています。

次の例は、使用中の @WebServiceClientTest アノテーションを示しています。

@WebServiceClientTest(ExampleWebServiceClient.class)
class WebServiceClientIntegrationTests {

    @Autowired
    private MockWebServiceServer server;

    @Autowired
    private ExampleWebServiceClient client;

    @Test
    void mockServerCall() {
        this.server.expect(payload(new StringSource("<request/>"))).andRespond(
                withPayload(new StringSource("<response><status>200</status></response>")));
        assertThat(this.client.test()).extracting(Response::getStatus).isEqualTo(200);
    }

}

26.3.25. 追加の自動構成とスライス

各スライスは、スライスの一部として含まれるべき自動構成を定義する 1 つ以上の @AutoConfigure…​ アノテーションを提供します。次の例に示すように、カスタム @AutoConfigure…​ アノテーションを作成するか、@ImportAutoConfiguration をテストに追加することにより、テストごとに自動構成を追加できます。

@JdbcTest
@ImportAutoConfiguration(IntegrationAutoConfiguration.class)
class ExampleJdbcTests {

}
自動構成は Spring Boot によって特定の方法で処理されるため、通常の @Import アノテーションを使用して自動構成をインポートしないようにしてください。

または、次の例に示すように、META-INF/spring.factories にスライスアノテーションを登録することで、スライスアノテーションを使用するための追加の自動構成を追加できます。

org.springframework.boot.test.autoconfigure.jdbc.JdbcTest=com.example.IntegrationAutoConfiguration
スライスまたは @AutoConfigure…​ アノテーションは、@ImportAutoConfiguration でメタアノテーションが付けられている限り、この方法でカスタマイズできます。

26.3.26. ユーザー設定とスライス

コードを適切な方法で構成する場合、@SpringBootApplication クラスはデフォルトでテストの構成として使用されます

その場合、アプリケーションのメインクラスに、その機能の特定の領域に固有の構成設定を散らかさないことが重要になります。

Spring Batch を使用しており、自動構成に依存していると仮定します。@SpringBootApplication は次のように定義できます。

@SpringBootApplication
@EnableBatchProcessing
public class SampleApplication { ... }

このクラスはテストのソース構成であるため、スライステストは実際に Spring Batch を開始しようとしますが、これは間違いなく実行したいことではありません。推奨されるアプローチは、次の例に示すように、アプリケーションと同じレベルの別の @Configuration クラスにそのエリア固有の構成を移動することです。

@Configuration(proxyBeanMethods = false)
@EnableBatchProcessing
public class BatchConfiguration { ... }
アプリケーションの複雑さに応じて、カスタマイズ用に単一の @Configuration クラスを用意するか、ドメイン領域ごとに 1 つのクラスを用意します。後者のアプローチでは、@Import アノテーションを使用して、必要に応じてテストの 1 つで有効にすることができます。

テストスライスは、@Configuration クラスをスキャンから除外します。例: @WebMvcTest の場合、次の構成では、テストスライスによってロードされたアプリケーションコンテキストに特定の WebMvcConfigurer Bean は含まれません。

@Configuration
public class WebConfiguration {
    @Bean
    public WebMvcConfigurer testConfigurer() {
        return new WebMvcConfigurer() {
            ...
        };
    }
}

ただし、以下の構成では、テストスライスによってカスタム WebMvcConfigurer がロードされます。

@Component
public class TestWebMvcConfigurer implements WebMvcConfigurer {
    ...
}

混乱のもう 1 つの原因は、クラスパススキャンです。実用的な方法でコードを構造化しながら、追加のパッケージをスキャンする必要があると仮定します。アプリケーションは次のコードのようになります。

@SpringBootApplication
@ComponentScan({ "com.example.app", "org.acme.another" })
public class SampleApplication { ... }

そうすることで、デフォルトのコンポーネントスキャンディレクティブが効果的にオーバーライドされ、選択したスライスに関係なく、これら 2 つのパッケージがスキャンされるという副作用があります。たとえば、@DataJpaTest は、アプリケーションのコンポーネントとユーザー構成を突然スキャンするようです。繰り返しますが、カスタムディレクティブを別のクラスに移動することは、この課題を解決するための良い方法です。

これが選択肢ではない場合は、テストの階層のどこかに @SpringBootConfiguration を作成して、代わりに使用することができます。あるいは、テストのソースを指定して、デフォルトのソースを見つける動作を無効にすることもできます。

26.3.27. Spock を使用して Spring Boot アプリケーションをテストする

Spock を使用して Spring Boot アプリケーションをテストする場合は、Spock の spock-spring モジュールへの依存関係をアプリケーションのビルドに追加する必要があります。spock-spring は、Spring のテストフレームワークを Spock に統合します。Spock 1.2 以降を使用して、Spock の Spring Framework および Spring Boot 統合に対する多くの改善の恩恵を受けることをお勧めします。詳細については、Spock の Spring モジュールのドキュメントを参照して (英語) ください。

26.4. テストユーティリティ

アプリケーションのテスト時に一般的に役立ついくつかのテストユーティリティクラスは、spring-boot の一部としてパッケージ化されています。

26.4.1. ConfigFileApplicationContextInitializer

ConfigFileApplicationContextInitializer は、Spring Boot application.properties ファイルをロードするテストに適用できる ApplicationContextInitializer です。次の例に示すように、@SpringBootTest が提供する機能の完全なセットが不要な場合に使用できます。

@ContextConfiguration(classes = Config.class,
    initializers = ConfigFileApplicationContextInitializer.class)
ConfigFileApplicationContextInitializer を単独で使用しても、@Value("${…​}") インジェクションはサポートされません。その唯一のジョブは、application.properties ファイルが Spring の Environment にロードされるようにすることです。@Value をサポートするには、PropertySourcesPlaceholderConfigurer を追加で構成するか、@SpringBootTest を使用して自動で構成する必要があります。

26.4.2. TestPropertyValues

TestPropertyValues を使用すると、ConfigurableEnvironment または ConfigurableApplicationContext にプロパティをすばやく追加できます。次のように、key=value 文字列で呼び出すことができます。

TestPropertyValues.of("org=Spring", "name=Boot").applyTo(env);

26.4.3. OutputCapture

OutputCapture は、System.out および System.err 出力のキャプチャーに使用できる JUnit Extension です。@ExtendWith(OutputCaptureExtension.class) を追加し、テストクラスのコンストラクターまたはテストメソッドへの引数として CapturedOutput を挿入するには、次のようにします。

@ExtendWith(OutputCaptureExtension.class)
class OutputCaptureTests {

    @Test
    void testName(CapturedOutput output) {
        System.out.println("Hello World!");
        assertThat(output).contains("World");
    }

}

26.4.4. TestRestTemplate

TestRestTemplate は、統合テストで役立つ Spring の RestTemplate の便利な代替手段です。バニラテンプレートまたは基本 HTTP 認証を送信するテンプレート(ユーザー名とパスワード付き)を取得できます。どちらの場合でも、テンプレートはサーバー側のエラーで例外をスローしないことにより、テストに適した方法で動作します。

Spring Framework 5.0 は、WebFlux 統合テストおよび WebFlux および MVC のエンドツーエンドテストの両方で機能する新しい WebTestClient を提供します。TestRestTemplate とは異なり、アサーションのための流れるような API を提供します。

Apache HTTP クライアント(バージョン 4.3.2 以降)を使用することをお勧めしますが、必須ではありません。クラスパスにそれがある場合、TestRestTemplate はクライアントを適切に構成することにより応答します。Apache の HTTP クライアントを使用する場合、いくつかの追加のテストフレンドリー機能が有効になります。

  • リダイレクトは追跡されません(したがって、レスポンスの場所をアサートできます)。

  • Cookie は無視されます(したがって、テンプレートはステートレスです)。

TestRestTemplate は、次の例に示すように、統合テストで直接インスタンス化できます。

public class MyTest {

    private TestRestTemplate template = new TestRestTemplate();

    @Test
    public void testRequest() throws Exception {
        HttpHeaders headers = this.template.getForEntity(
                "https://myhost.example.com/example", String.class).getHeaders();
        assertThat(headers.getLocation()).hasHost("other.example.com");
    }

}

あるいは、WebEnvironment.RANDOM_PORT または WebEnvironment.DEFINED_PORT で @SpringBootTest アノテーションを使用する場合、完全に構成された TestRestTemplate を注入して使用を開始できます。必要に応じて、RestTemplateBuilder Bean を通じて追加のカスタマイズを適用できます。次の例に示すように、ホストとポートを指定しない URL はすべて、組み込みサーバーに自動的に接続します。

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class SampleWebClientTests {

    @Autowired
    private TestRestTemplate template;

    @Test
    void testRequest() {
        HttpHeaders headers = this.template.getForEntity("/example", String.class).getHeaders();
        assertThat(headers.getLocation()).hasHost("other.example.com");
    }

    @TestConfiguration(proxyBeanMethods = false)
    static class Config {

        @Bean
        RestTemplateBuilder restTemplateBuilder() {
            return new RestTemplateBuilder().setConnectTimeout(Duration.ofSeconds(1))
                    .setReadTimeout(Duration.ofSeconds(1));
        }

    }

}

27. WebSocket

Spring Boot は、組み込み Tomcat、Jetty、および Undertow の WebSockets 自動構成を提供します。war ファイルをスタンドアロンコンテナーにデプロイする場合、Spring Boot は、コンテナーが WebSocket サポートの構成を担当していると想定します。

Spring Framework は、spring-boot-starter-websocket モジュールを介して簡単にアクセスできる MVC Web アプリケーションの豊富な WebSocket サポートを提供します。

WebSocket サポートは、リアクティブ Web アプリケーションでも利用可能であり、spring-boot-starter-webflux と一緒に WebSocket API を含める必要があります。

<dependency>
    <groupId>javax.websocket</groupId>
    <artifactId>javax.websocket-api</artifactId>
</dependency>

28. Web サービス

Spring Boot は Web サービスの自動構成を提供するため、Endpoints を定義するだけです。

Spring Web Services の機能 (英語) は、spring-boot-starter-webservices モジュールで簡単にアクセスできます。

SimpleWsdl11Definition および SimpleXsdSchema Bean は、それぞれ WSDL および XSD に対して自動的に作成できます。これを行うには、次の例に示すように、場所を構成します。

spring.webservices.wsdl-locations=classpath:/wsdl

28.1. WebServiceTemplate を使用した Web サービスの呼び出し

アプリケーションからリモート Web サービスを呼び出す必要がある場合は、WebServiceTemplate (英語) クラスを使用できます。WebServiceTemplate インスタンスは、使用する前にカスタマイズする必要があることが多いため、Spring Boot は単一の自動構成 WebServiceTemplate Bean を提供しません。ただし、必要に応じて WebServiceTemplate インスタンスを作成するために使用できる WebServiceTemplateBuilder を自動構成します。

次のコードは典型的な例を示しています。

@Service
public class MyService {

    private final WebServiceTemplate webServiceTemplate;

    public MyService(WebServiceTemplateBuilder webServiceTemplateBuilder) {
        this.webServiceTemplate = webServiceTemplateBuilder.build();
    }

    public DetailsResp someWsCall(DetailsReq detailsReq) {
         return (DetailsResp) this.webServiceTemplate.marshalSendAndReceive(detailsReq, new SoapActionCallback(ACTION));
    }

}

デフォルトでは、WebServiceTemplateBuilder は、クラスパスで使用可能な HTTP クライアントライブラリを使用して、適切な HTTP ベースの WebServiceMessageSender を検出します。次のように、読み取りタイムアウトと接続タイムアウトをカスタマイズすることもできます。

@Bean
public WebServiceTemplate webServiceTemplate(WebServiceTemplateBuilder builder) {
    return builder.messageSenders(new HttpWebServiceMessageSenderBuilder()
            .setConnectTimeout(5000).setReadTimeout(2000).build()).build();
}

29. 独自の自動構成の作成

共有ライブラリを開発している会社で働いている場合、またはオープンソースまたは有償ライブラリで作業している場合、独自の自動構成を開発することができます。自動構成クラスは外部 jar にバンドルでき、Spring Boot で引き続き取得できます。

自動構成は、自動構成コードと、使用する一般的なライブラリを提供する「スターター」に関連付けることができます。最初に、独自の自動構成を構築するために知っておく必要があることを説明し、次にカスタムスターターの作成に必要な一般的な手順に進みます

スターターを段階的に作成する方法を紹介するデモプロジェクト (GitHub) が用意されています。

29.1. 自動構成された Bean について

内部では、自動構成は標準の @Configuration クラスで実装されます。追加の @Conditional アノテーションは、自動構成をいつ適用するかを制限するために使用されます。通常、自動構成クラスは @ConditionalOnClass および @ConditionalOnMissingBean アノテーションを使用します。これにより、関連するクラスが見つかった場合、および独自の @Configuration を宣言していない場合にのみ、自動構成が適用されます。

spring-boot-autoconfigure (GitHub) のソースコードを参照して、Spring が提供する @Configuration クラスを確認できます(META-INF/spring.factories (GitHub) ファイルを参照)。

29.2. 自動構成候補の特定

Spring Boot は、公開された jar 内の META-INF/spring.factories ファイルの存在を確認します。このファイルには、次の例に示すように、EnableAutoConfiguration キーに構成クラスがリストされている必要があります。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration
自動構成はその方法でのみロードする必要があります。それらが特定のパッケージスペースで定義され、コンポーネントスキャンの対象にならないことを確認してください。さらに、自動構成クラスでは、追加のコンポーネントを見つけるためのコンポーネントスキャンを有効にしないでください。代わりに、特定の @Import を使用する必要があります。

構成を特定の順序で適用する必要がある場合は、@AutoConfigureAfter (GitHub) または @AutoConfigureBefore (GitHub) アノテーションを使用できます。例:Web 固有の構成を提供する場合、WebMvcAutoConfiguration の後にクラスを適用する必要がある場合があります。

相互の直接的な知識がないはずの特定の自動構成を並べ替える場合は、@AutoConfigureOrder も使用できます。そのアノテーションは、通常の @Order アノテーションと同じセマンティックを持ちますが、自動構成クラスに専用の順序を提供します。

標準の @Configuration クラスと同様に、自動構成クラスが適用される順序は、それらの Bean が定義される順序にのみ影響します。これらの Bean が後で作成される順序は影響を受けず、各 Bean の依存関連と @DependsOn 関連によって決定されます。

29.3. 条件アノテーション

ほとんどの場合、1 つ以上の @Conditional アノテーションを自動構成クラスに含める必要があります。@ConditionalOnMissingBean アノテーションは、デフォルトに満足できない場合に開発者が自動構成をオーバーライドできるようにするために使用される一般的な例の 1 つです。

Spring Boot には、@Configuration クラスまたは個々の @Bean メソッドにアノテーションを付けることにより、独自のコードで再利用できる多数の @Conditional アノテーションが含まれています。これらのアノテーションは次のとおりです。

29.3.1. クラス Conditions

@ConditionalOnClass および @ConditionalOnMissingClass アノテーションにより、特定のクラスの有無に基づいて @Configuration クラスを含めることができます。アノテーションメタデータは ASM (英語) を使用して解析されるという事実により、value 属性を使用して、実際のクラスを参照できます。ただし、そのクラスは実行中のアプリケーションクラスパスに実際には表示されない場合があります。String 値を使用してクラス名を指定する場合は、name 属性も使用できます。

このメカニズムは、通常戻り型が条件のターゲットである @Bean メソッドに同じ方法を適用しません。メソッドの条件が適用される前に、JVM はクラスをロードし、クラスが処理されると失敗する可能性のあるメソッド参照を処理します。現在ではない。

このシナリオを処理するには、次の例に示すように、別個の @Configuration クラスを使用して条件を分離できます。

@Configuration(proxyBeanMethods = false)
// Some conditions
public class MyAutoConfiguration {

    // Auto-configured beans

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnClass(EmbeddedAcmeService.class)
    static class EmbeddedConfiguration {

        @Bean
        @ConditionalOnMissingBean
        public EmbeddedAcmeService embeddedAcmeService() { ... }

    }

}
メタアノテーションの一部として @ConditionalOnClass または @ConditionalOnMissingClass を使用して独自の合成アノテーションを作成する場合、そのような場合はクラスを参照しないため、name を使用する必要があります。

29.3.2. Bean 条件

@ConditionalOnBean および @ConditionalOnMissingBean アノテーションにより、特定の Bean の有無に基づいて Bean を含めることができます。value 属性を使用して、タイプごとに Bean を指定したり、name を使用して名前ごとに Bean を指定したりできます。search 属性を使用すると、Bean を検索するときに考慮する必要がある ApplicationContext 階層を制限できます。

@Bean メソッドに配置すると、次の例に示すように、ターゲットタイプはデフォルトでメソッドの戻り値タイプになります。

@Configuration(proxyBeanMethods = false)
public class MyAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public MyService myService() { ... }

}

上記の例では、MyService タイプの Bean が ApplicationContext に含まれていない場合、myService Bean が作成されます。

これらの条件はこれまでに処理されたものに基づいて評価されるため、Bean 定義が追加される順序には非常に注意する必要があります。このため、自動構成クラスでは @ConditionalOnBean および @ConditionalOnMissingBean アノテーションのみを使用することをお勧めします(これらはユーザー定義の Bean 定義が追加された後にロードされることが保証されているため)。
@ConditionalOnBean および @ConditionalOnMissingBean は、@Configuration クラスの作成を妨げません。クラスレベルでこれらの条件を使用することと、含まれる各 @Bean メソッドをアノテーションでマークすることの唯一の違いは、条件が一致しない場合、前者は @Configuration クラスを Bean として登録できないことです。

29.3.3. プロパティ条件

@ConditionalOnProperty アノテーションにより、Spring 環境プロパティに基づいて構成を含めることができます。prefix および name 属性を使用して、チェックするプロパティを指定します。デフォルトでは、存在し、false と等しくないプロパティはすべて一致します。havingValue および matchIfMissing 属性を使用して、より高度なチェックを作成することもできます。

29.3.4. リソース条件

@ConditionalOnResource アノテーションを使用すると、特定のリソースが存在する場合にのみ構成を含めることができます。次の例に示すように、リソースは通常の Spring 規則を使用して指定できます: file:/home/user/test.dat

29.3.5. Web アプリケーション条件

@ConditionalOnWebApplication および @ConditionalOnNotWebApplication アノテーションにより、アプリケーションが「Web アプリケーション」であるかどうかに応じて構成を含めることができます。サーブレットベースの Web アプリケーションは、Spring WebApplicationContext を使用するアプリケーション、session スコープを定義するアプリケーション、または ConfigurableWebEnvironment を持つアプリケーションです。リアクティブ Web アプリケーションは、ReactiveWebApplicationContext を使用するか、ConfigurableReactiveWebEnvironment を持つアプリケーションです。

@ConditionalOnWarDeployment アノテーションを使用すると、アプリケーションがコンテナーにデプロイされる従来の WAR アプリケーションであるかどうかに応じて、構成を含めることができます。この条件は、組み込みサーバーで実行されるアプリケーションには一致しません。

29.3.6. SpEL 式の条件

@ConditionalOnExpression アノテーションにより、SpEL 式の結果に基づいて構成を含めることができます。

29.4. 自動構成のテスト

自動構成は、ユーザー構成(@Bean 定義および Environment カスタマイズ)、条件評価(特定のライブラリの存在)など、多くの要因の影響を受ける可能性があります。具体的には、各テストで、これらのカスタマイズの組み合わせを表す、明確に定義された ApplicationContext を作成する必要があります。ApplicationContextRunner はそれを達成するための素晴らしい方法を提供します。

ApplicationContextRunner は通常、基本の共通構成を収集するためのテストクラスのフィールドとして定義されます。次の例では、UserServiceAutoConfiguration が常に呼び出されるようにします。

private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
        .withConfiguration(AutoConfigurations.of(UserServiceAutoConfiguration.class));
複数の自動構成を定義する必要がある場合、宣言はアプリケーションの実行時とまったく同じ順序で呼び出されるため、宣言を順序付ける必要はありません。

各テストでは、ランナーを使用して特定のユースケースを表すことができます。たとえば、次のサンプルはユーザー構成(UserConfiguration)を呼び出し、自動構成が適切にバックオフすることを確認します。run を呼び出すと、AssertJ で使用できるコールバックコンテキストが提供されます。

@Test
void defaultServiceBacksOff() {
    this.contextRunner.withUserConfiguration(UserConfiguration.class).run((context) -> {
        assertThat(context).hasSingleBean(UserService.class);
        assertThat(context).getBean("myUserService").isSameAs(context.getBean(UserService.class));
    });
}

@Configuration(proxyBeanMethods = false)
static class UserConfiguration {

    @Bean
    UserService myUserService() {
        return new UserService("mine");
    }

}

次の例に示すように、Environment を簡単にカスタマイズすることもできます。

@Test
void serviceNameCanBeConfigured() {
    this.contextRunner.withPropertyValues("user.name=test123").run((context) -> {
        assertThat(context).hasSingleBean(UserService.class);
        assertThat(context.getBean(UserService.class).getName()).isEqualTo("test123");
    });
}

ランナーを使用して ConditionEvaluationReport を表示することもできます。レポートは、INFO または DEBUG レベルで出力できます。次の例は、ConditionEvaluationReportLoggingListener を使用して自動構成テストでレポートを出力する方法を示しています。

@Test
public void autoConfigTest {
    ConditionEvaluationReportLoggingListener initializer = new ConditionEvaluationReportLoggingListener(
            LogLevel.INFO);
    ApplicationContextRunner contextRunner = new ApplicationContextRunner()
            .withInitializer(initializer).run((context) -> {
                    // Do something...
            });
}

29.4.1. Web コンテキストのシミュレーション

サーブレットまたはリアクティブ Web アプリケーションコンテキストでのみ動作する自動構成をテストする必要がある場合は、それぞれ WebApplicationContextRunner または ReactiveWebApplicationContextRunner を使用します。

29.4.2. クラスパスのオーバーライド

実行時に特定のクラスやパッケージが存在しない場合に何が起こるかをテストすることもできます。Spring Boot には、ランナーが簡単に使用できる FilteredClassLoader が付属しています。次の例では、UserService が存在しない場合、自動構成が適切に無効になっていると断言します。

@Test
void serviceIsIgnoredIfLibraryIsNotPresent() {
    this.contextRunner.withClassLoader(new FilteredClassLoader(UserService.class))
            .run((context) -> assertThat(context).doesNotHaveBean("userService"));
}

29.5. 独自のスターターを作成する

典型的な Spring Boot スターターには、特定のテクノロジーのインフラストラクチャを自動構成してカスタマイズするコードが含まれています。これを「acme」と呼びましょう。簡単に拡張できるようにするために、専用の名前空間にある多数の構成キーを環境に公開できます。最後に、ユーザーができるだけ簡単に開始できるように、単一の「スターター」依存関係が提供されています。

具体的には、カスタムスターターには次のものを含めることができます。

  • 「acme」の自動構成コードを含む autoconfigure モジュール。

  • autoconfigure モジュールへの依存関係を提供する starter モジュール、および「acme」と通常役立つその他の依存関係。簡単に言えば、スターターを追加すると、そのライブラリの使用を開始するために必要なすべてが提供されます。

この 2 つのモジュールでの分離は、決して必要ではありません。「acme」にいくつかのフレーバー、オプション、またはオプション機能がある場合、一部の機能がオプションであることを明確に表現できるため、自動構成を分離することをお勧めします。さらに、これらのオプションの依存関係について意見を述べるスターターを作成することができます。同時に、autoconfigure モジュールのみに依存して、さまざまな意見を持つ独自のスターターを作成することもできます。

自動構成が比較的簡単でオプションの機能がない場合、スターターで 2 つのモジュールをマージすることは間違いなくオプションです。

29.5.1. ネーミング

スターターに適切な名前空間を提供するようにしてください。別の Maven groupId を使用している場合でも、モジュール名を spring-boot で始めないでください。将来的に自動構成するものについては、公式サポートを提供する場合があります。

経験則として、組み合わせたモジュールにはスターターにちなんで名前を付ける必要があります。例:「acme」のスターターを作成し、自動構成モジュールに acme-spring-boot およびスターター acme-spring-boot-starter の名前を付けると仮定します。2 つを結合するモジュールが 1 つしかない場合は、acme-spring-boot-starter という名前を付けます。

29.5.2. 構成キー

スターターが構成キーを提供する場合、それらに固有の名前空間を使用します。特に、Spring Boot が使用するネームスペース(servermanagementspring など)にはキーを含めないでください。同じ名前空間を使用する場合、これらの名前空間をモジュールを破壊する方法で将来変更する可能性があります。経験則として、所有する名前空間(たとえば acme)をすべてのキーの前に付けます。

次の例に示すように、プロパティごとにフィールド javadoc を追加して、構成キーがドキュメント化されていることを確認します。

@ConfigurationProperties("acme")
public class AcmeProperties {

    /**
     * Whether to check the location of acme resources.
     */
    private boolean checkLocation = true;

    /**
     * Timeout for establishing a connection to the acme server.
     */
    private Duration loginTimeout = Duration.ofSeconds(3);

    // getters & setters

}
それらは JSON に追加される前に処理されないため、@ConfigurationProperties フィールドの Javadoc でプレーンテキストのみを使用する必要があります。

説明が一貫していることを確認するために、内部で従ういくつかのルールを次に示します。

  • 「The」または「A」で説明を始めないでください。

  • boolean タイプの場合、説明を「Whether」または「Enable」で開始します。

  • コレクションベースのタイプの場合、説明を「カンマ区切りリスト」で開始する

  • long ではなく java.time.Duration を使用し、デフォルトの単位がミリ秒と異なる場合、たとえば「期間サフィックスが指定されていない場合、秒が使用されます」。

  • 実行時に決定する必要がない限り、説明にデフォルト値を指定しないでください。

メタデータ生成をトリガーして、キーでも IDE 支援が利用できるようにしてください。生成されたメタデータ(META-INF/spring-configuration-metadata.json)を確認して、キーが適切にドキュメント化されていることを確認してください。互換性のある IDE で独自のスターターを使用することも、メタデータの品質を検証するための良いアイデアです。

29.5.3. 「自動構成」モジュール

autoconfigure モジュールには、ライブラリの使用を開始するために必要なすべてのものが含まれています。また、構成キーの定義(@ConfigurationProperties など)と、コンポーネントの初期化方法をさらにカスタマイズするために使用できるコールバックインターフェースも含まれている場合があります。

ライブラリへの依存関係をオプションとしてマークして、autoconfigure モジュールをプロジェクトに簡単に含めることができるようにする必要があります。そのようにすると、ライブラリは提供されず、デフォルトで Spring Boot はオフに戻ります。

Spring Boot は、アノテーションプロセッサを使用して、メタデータファイル(META-INF/spring-autoconfigure-metadata.properties)の自動構成の条件を収集します。そのファイルが存在する場合、一致しない自動構成を積極的にフィルタリングするために使用され、起動時間が改善されます。自動構成を含むモジュールに次の依存関係を追加することをお勧めします。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure-processor</artifactId>
    <optional>true</optional>
</dependency>

アプリケーションで直接自動構成を定義している場合は、spring-boot-maven-plugin を構成して、repackage のゴールによって依存関係が fat jar に追加されないようにします。

<project>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-autoconfigure-processor</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Gradle 4.5 以前では、次の例に示すように、compileOnly 構成で依存関係を宣言する必要があります。

dependencies {
    compileOnly "org.springframework.boot:spring-boot-autoconfigure-processor"
}

Gradle 4.6 以降では、次の例に示すように、annotationProcessor 構成で依存関係を宣言する必要があります。

dependencies {
    annotationProcessor "org.springframework.boot:spring-boot-autoconfigure-processor"
}

29.5.4. スターターモジュール

スターターは本当に空の jar です。その唯一の目的は、ライブラリを操作するために必要な依存関係を提供することです。それは、始めるために何が必要であるかについての意見に基づく見解と考えることができます。

スターターが追加されるプロジェクトについて想定しないでください。通常、自動構成するライブラリに他のスターターが必要な場合は、それらにもメンションしてください。オプションの依存関係の数が多い場合、ライブラリの通常の使用には不要な依存関係を含めることを避ける必要があるため、適切なデフォルトの依存関係のセットを提供するのは難しい場合があります。つまり、オプションの依存関係を含めないでください。

どちらの方法でも、スターターはコア Spring Boot スターター(spring-boot-starter)を直接または間接的に参照する必要があります(つまり、スターターが別のスターターに依存している場合は追加する必要はありません)。カスタムスターターのみでプロジェクトが作成された場合、Spring Boot のコア機能はコアスターターの存在によって尊重されます。

30. Kotlin サポート

Kotlin (英語) は、JVM(および他のプラットフォーム)を対象とする静的に型付けされた言語で、Java で記述された既存のライブラリとの相互運用性 (英語) を提供しながら、簡潔でエレガントなコードを記述できます。

Spring Boot は、Spring Framework、Spring Data、Reactor などの他の Spring プロジェクトのサポートを活用することにより、Kotlin サポートを提供します。詳細については、Spring Framework Kotlin サポートドキュメントを参照してください。

Spring Boot と Kotlin から始める最も簡単な方法は、この包括的なチュートリアルに従うことです。start.spring.io (英語) を介して新しい Kotlin プロジェクトを作成できます。サポートが必要な場合は、Kotlin Slack (英語) の #spring チャンネルに参加するか、スタックオーバーフロー (英語) の spring および kotlin タグで質問してください。

30.1. 要件

Spring Boot は Kotlin 1.3.x. をサポートします。Kotlin を使用するには、org.jetbrains.kotlin:kotlin-stdlib および org.jetbrains.kotlin:kotlin-reflect がクラスパスに存在する必要があります。kotlin-stdlib バリアント kotlin-stdlib-jdk7 および kotlin-stdlib-jdk8 も使用できます。

Kotlin クラスはデフォルトで final (英語) から、kotlin-spring (英語) プラグインを構成して、Springannotated クラスを自動的に開いてプロキシ化できるようにすることができます。

Jackson の Kotlin モジュール (GitHub) は、Kotlin で JSON データをシリアライズ / デシリアライズするために必要です。クラスパスで見つかると自動的に登録されます。Jackson および Kotlin が存在するが、Jackson Kotlin モジュールが存在しない場合、警告メッセージがログに記録されます。

これらの依存関係とプラグインは、start.spring.io (英語) で Kotlin プロジェクトをブートストラップする場合にデフォルトで提供されます。

30.2. null セーフ

Kotlin の主要な機能の 1 つは、null-safety (英語) です。問題を実行時まで延期して NullPointerException を検出するのではなく、コンパイル時に null 値を処理します。これは、Optional のようなラッパーのコストを支払うことなく、バグの一般的な原因を排除できます。また、Kotlin では、Kotlin の null の安全性に関するこの包括的なガイド (英語) で説明されているように、null 可能な値を持つ関数構造を使用できます。

Java では、型システムで null セーフを表現することはできませんが、Spring Framework、Spring Data、および Reactor は、ツールに優しいアノテーションを介して API の null セーフを提供するようになりました。デフォルトでは、Kotlin で使用される Java API の型 (英語) は、null チェックが緩和されるプラットフォーム型 (英語) として認識されます。Kotlin による JSR 305 アノテーションのサポート (英語) と NULL 可能性アノテーションを組み合わせることにより、Kotlin の関連する Spring API に NULL 安全性が提供されます。

JSR 305 チェックは、-Xjsr305 コンパイラフラグに次のオプションを追加することで構成できます。-Xjsr305={strict|warn|ignore} デフォルトの動作は -Xjsr305=warn と同じです。strict 値は、Spring API から推測された Kotlin タイプで null の安全性を考慮に入れる必要がありますが、Spring API の null 可能性宣言はマイナーリリース間でも発展する可能性があり、今後さらにチェックが追加される可能性があるという知識とともに使用する必要があります)。

ジェネリック型の引数、可変引数、および配列要素の nullability はまだサポートされていません。最新情報については、SPR-15942 (英語) を参照してください。また、Spring Boot の独自の API にはまだアノテーションが付けられていない (GitHub) ことに注意してください。

30.3. Kotlin API

30.3.1. runApplication

Spring Boot は、次の例に示すように、runApplication<MyApplication>(*args) でアプリケーションを実行する慣用的な方法を提供します。

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class MyApplication

fun main(args: Array<String>) {
    runApplication<MyApplication>(*args)
}

これは SpringApplication.run(MyApplication::class.java, *args) のドロップイン代替です。また、次の例に示すように、アプリケーションをカスタマイズできます。

runApplication<MyApplication>(*args) {
    setBannerMode(OFF)
}

30.3.2. 拡張

Kotlin 拡張機能 (英語) は、追加機能を使用して既存のクラスを継承する機能を提供します。Spring Boot Kotlin API は、これらの拡張機能を利用して、既存の API に新しい Kotlin 固有の便利な機能を追加します。

Spring Framework の RestOperations に対して Spring Framework によって提供されるものと同様の TestRestTemplate 拡張機能が提供されます。特に、拡張機能により、Kotlin の型指定されたパラメーターを利用できるようになります。

30.4. 依存関係の管理

異なるバージョンの Kotlin 依存関係のクラスパスへの混在を避けるために、Spring Boot は Kotlin BOM をインポートします。

Maven では、kotlin.version プロパティを介して Kotlin バージョンをカスタマイズでき、kotlin-maven-plugin のプラグイン管理が提供されます。Gradle では、Spring Boot プラグインは kotlin.version を Kotlin プラグインのバージョンに自動的に合わせます。

Spring Boot は、Kotlin コルーチン BOM をインポートすることにより、コルーチンの依存関係のバージョンも管理します。バージョンは、kotlin-coroutines.version プロパティを介してカスタマイズできます。

start.spring.io (英語) に少なくとも 1 つのリアクティブ依存関係がある Kotlin プロジェクトをブートストラップする場合、org.jetbrains.kotlinx:kotlinx-coroutines-reactor 依存関係がデフォルトで提供されます。

30.5. @ConfigurationProperties

@ConstructorBinding と組み合わせて使用する場合、@ConfigurationProperties は、次の例に示すように、不変の val プロパティを持つクラスをサポートします。

@ConstructorBinding
@ConfigurationProperties("example.kotlin")
data class KotlinExampleProperties(
        val name: String,
        val description: String,
        val myService: MyService) {

    data class MyService(
            val apiToken: String,
            val uri: URI
    )
}
アノテーションプロセッサーを使用して独自のメタデータを生成するには、kapt を spring-boot-configuration-processor 依存関係で構成する必要があります (英語) 。kapt が提供するモデルの制限により、一部の機能(デフォルト値の検出や非推奨のアイテムなど)が機能しないことに注意してください。

30.6. テスト

JUnit 4 を使用して Kotlin コードをテストすることは可能ですが、JUnit 5 はデフォルトで提供されており、推奨されています。JUnit 5 では、テストクラスを 1 回インスタンス化し、クラスのすべてのテストに再利用できます。これにより、非静的メソッドで @BeforeAll および @AfterAll アノテーションを使用できるようになり、Kotlin に適しています。

JUnit 5 がデフォルトであり、Vintage エンジンは JUnit 4 との後方互換性のために提供されています。使用しない場合は、org.junit.vintage:junit-vintage-engine を除外してください。テストインスタンスのライフサイクルを「クラスごと」に切り替える (英語) も必要です。

Kotlin クラスをモックするには、MockK (英語) をお勧めします。Mockito 固有の @MockBean および @SpyBean アノテーションに相当する Mockk が必要な場合は、同様の @MockkBean および @SpykBean アノテーションを提供する SpringMockK (GitHub) を使用できます。

30.7. リソース

30.7.2. サンプル

31. コンテナーイメージの構築

31.1. Docker イメージの作成

典型的な Spring Boot fat jar は、Dockerfile に数行追加するだけで Docker イメージに変換でき、イメージの作成に使用できます。ただし、docker イメージのように fat jar をコピーして実行することには、さまざまな欠点があります。fat jar を開梱せずに実行すると、常にある程度のオーバーヘッドがあり、コンテナー化された環境では、これが顕著になることがあります。もう 1 つの課題は、アプリケーションのコードとそのすべての依存関係を Docker イメージの 1 つのレイヤーに配置するのが最適ではないことです。使用する Spring Boot のバージョンをアップグレードするよりも頻繁にコードを再コンパイルする可能性が高いため、多くの場合、物事を少し分離する方が良いでしょう。アプリケーションクラスの前のレイヤーに jar ファイルを配置する場合、Docker は多くの場合、一番下のレイヤーを変更するだけで、他のレイヤーをキャッシュから取得できます。

31.1.1. Docker イメージのレイヤー化

dockerfile で構築できる最適化された Docker イメージを簡単に作成できるように、Spring Boot はレイヤーインデックスファイルの jar への追加をサポートしています。レイヤーのリストと、レイヤー内に含まれる jar のパーツを提供します。インデックス内のレイヤーのリストは、Docker/OCI イメージにレイヤーを追加する順序に基づいて並べられます。すぐに使用できる次のレイヤーがサポートされています。

  • dependencies (定期的にリリースされる依存関係の場合)

  • spring-boot-loader ( org/springframework/boot/loader のすべての)

  • snapshot-dependencies (スナップショットの依存関係)

  • application (アプリケーションのクラスとリソース)

layers.idx ファイルの例を次に示します。

- "dependencies":
  - BOOT-INF/lib/library1.jar
  - BOOT-INF/lib/library2.jar
- "spring-boot-loader":
  - org/springframework/boot/loader/JarLauncher.class
  - org/springframework/boot/loader/jar/JarEntry.class
- "snapshot-dependencies":
  - BOOT-INF/lib/library3-SNAPSHOT.jar
- "application":
  - META-INF/MANIFEST.MF
  - BOOT-INF/classes/a/b/C.class

この階層化は、アプリケーションのビルド間で変更される可能性に基づいてコードを分離するように設計されています。ライブラリコードはビルド間で変更される可能性が低いため、ツールがキャッシュからレイヤーを再利用できるように独自のレイヤーに配置されます。アプリケーションコードはビルド間で変更される可能性が高いため、別のレイヤーに分離されます。

Maven の場合、レイヤーインデックスを jar に追加する方法の詳細については、レイヤー化された jar ファイルのパッケージ化のセクションを参照してください。Gradle については、Gradle プラグインのドキュメントのパッケージ化された jar のセクションを参照してください。

31.1.2. Dockerfile の作成

レイヤーインデックスファイルを含む jar を作成すると、spring-boot-jarmode-layertools jar が依存関係として jar に追加されます。クラスパス上のこの jar を使用すると、アプリケーションを特別なモードで起動して、ブートストラップコードがアプリケーションとはまったく異なるもの(レイヤーを抽出するものなど)を実行できるようにすることができます。

layertools モードは、起動スクリプトを含む完全に実行可能な Spring Boot アーカイブでは使用できません。layertools で使用することを目的とした jar ファイルをビルドするときは、起動スクリプト構成を無効にします。

layertools jar モードで jar を起動する方法は次のとおりです。

$ java -Djarmode=layertools -jar my-app.jar

これにより、次の出力が提供されます。

Usage:
  java -Djarmode=layertools -jar my-app.jar

Available commands:
  list     List layers from the jar that can be extracted
  extract  Extracts layers from the jar for image creation
  help     Help about any command

extract コマンドを使用して、アプリケーションをドッカーファイルに追加するレイヤーに簡単に分割できます。jarmode を使用した Dockerfile の例を次に示します。

FROM adoptopenjdk:11-jre-hotspot as builder
WORKDIR application
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract

FROM adoptopenjdk:11-jre-hotspot
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

上記の Dockerfile が現在のディレクトリにあると仮定すると、docker build . を使用して docker イメージを構築できます。または、次の例に示すように、アプリケーション jar へのパスをオプションで指定できます。

docker build --build-arg JAR_FILE=path/to/myapp.jar .

これはマルチステージの dockerfile です。ビルダーステージは、後で必要になるディレクトリを抽出します。各 COPY コマンドは、jarmode によって抽出されたレイヤーに関連しています。

もちろん、Dockerfile は jarmode を使用せずに作成できます。unzip と mv の組み合わせを使用して、適切なレイヤーに移動できますが、jarmode はそれを単純化します。

31.2. ビルドパック

Dockerfile は、docker イメージを作成するための 1 つの方法にすぎません。docker イメージを構築する別の方法は、ビルドパックを使用して、Maven または Gradle プラグインから直接行うことです。Cloud Foundry や Heroku などのアプリケーションプラットフォームを使用したことがある場合は、おそらくビルドパックを使用したことがあります。ビルドパックは、アプリケーションを取得し、プラットフォームが実際に実行できるものに変換するプラットフォームの一部です。例:Cloud Foundry の Java ビルドパックは、.jar ファイルをプッシュしていることを認識し、関連する JRE を自動的に追加します。

Cloud Native Buildpacks を使用すると、どこでも実行できる Docker 互換のイメージを作成できます。Spring Boot には、Maven と Gradle の両方のビルドパックサポートが直接含まれています。つまり、1 つのコマンドを入力するだけで、ローカルで実行されている Docker デーモンに適切なイメージをすばやく取得できます。

Maven および Gradle でビルドパックを使用する方法については、個々のプラグインのドキュメントを参照してください。

32. 次のステップ

このセクションで説明したクラスについて詳しく知りたい場合は、Spring Boot API ドキュメントをチェックアウトするか、ソースコードを直接 (GitHub) 参照できます。特定の質問がある場合は、使い方セクションを参照してください。

Spring Boot のコア機能に慣れている場合は、引き続き本番環境向けの機能について読み進めてください。

Translated by cypher256 GitHub. See the original content.