このセクションでは、Spring Boot を使用するときによく発生するいくつかの一般的な「それを行う方法」の質問に対する回答を提供します。そのカバレッジは網羅的ではありませんが、非常に多くの部分をカバーしています。
ここで取り上げていない特定の問題がある場合は、stackoverflow.com (英語) をチェックして、誰かがすでに回答を提供しているかどうかを確認します。また、新しい質問をするのに最適な場所です(spring-boot
タグを使用してください)。
また、このセクションを拡充できることは我々にとっても幸せです。「使い方」を追加する場合は、プルリクエスト: GitHub (英語) を送信してください。
1. Spring Boot アプリケーション
このセクションには、Spring Boot アプリケーションに直接関連するトピックが含まれています。
1.1. 独自の FailureAnalyzer を作成する
FailureAnalyzer
(Javadoc) は、起動時に例外をインターセプトし、それを FailureAnalysis
(Javadoc) にラップされた人間が読み取れるメッセージに変換する優れた方法です。Spring Boot は、アプリケーションコンテキスト関連の例外、JSR-303 検証などのためのこのようなアナライザーを提供します。独自に作成することもできます。
AbstractFailureAnalyzer
は、FailureAnalyzer
の便利な拡張機能であり、処理する例外の指定された例外タイプの存在を確認します。それを継承して、実装が例外が実際に存在する場合にのみ例外を処理する機会を得ることができます。何らかの理由で例外を処理できない場合は、null
を返して、別の実装に例外を処理する機会を与えます。
FailureAnalyzer
実装は META-INF/spring.factories
に登録する必要があります。次の例では、ProjectConstraintViolationFailureAnalyzer
を登録します。
org.springframework.boot.diagnostics.FailureAnalyzer=\
com.example.ProjectConstraintViolationFailureAnalyzer
BeanFactory または Environment へのアクセスが必要な場合、FailureAnalyzer はそれぞれ BeanFactoryAware または EnvironmentAware を実装できます。 |
1.2. 自動構成のトラブルシューティング
Spring Boot 自動構成は、「正しい動作をする」ために最善を尽くしますが、時には失敗することがあり、その理由を説明するのは難しい場合があります。
Spring Boot ApplicationContext
には、本当に便利な ConditionEvaluationReport
があります。DEBUG
ロギング出力を有効にすると、それを見ることができます。spring-boot-actuator
を使用する場合(アクチュエーターの章を参照)、JSON でレポートをレンダリングする conditions
エンドポイントもあります。そのエンドポイントを使用してアプリケーションをデバッグし、実行時に Spring Boot によって追加された機能(および追加されていない機能)を確認します。
ソースコードと Javadoc を見ると、さらに多くの質問に答えることができます。コードを読むときは、次の経験則を覚えておいてください。
*AutoConfiguration
と呼ばれるクラスを探し、そのソースを参照してください。@Conditional*
アノテーションに特に注意して、有効にする機能とタイミングを確認してください。コマンドラインまたはシステムプロパティ-Ddebug
に--debug
を追加して、アプリで行われたすべての自動構成決定のログをコンソールに取得します。アクチュエーターを有効にした実行中のアプリケーションで、同じ情報についてconditions
エンドポイント(/actuator/conditions
または同等の JMX)を調べます。@ConfigurationProperties
(ServerProperties
: GitHub (英語) など)であるクラスを探し、そこから利用可能な外部構成オプションを読み取ります。@ConfigurationProperties
アノテーションには、外部プロパティのプレフィックスとして機能するname
属性があります。ServerProperties
にはprefix="server"
があり、その構成プロパティはserver.port
、server.address
などです。アクチュエーターを有効にした実行中のアプリケーションで、configprops
エンドポイントを参照してください。Binder
でbind
メソッドの使用を探して、緩和された方法でEnvironment
から明示的に構成値をプルします。多くの場合、接頭辞とともに使用されます。Environment
に直接バインドする@Value
アノテーションを探します。通常
Environment
から解決されたプレースホルダーで評価される SpEL 式にレスポンスして、機能のオンとオフを切り替える@ConditionalOnExpression
アノテーションを探します。
1.3. 開始する前に環境または ApplicationContext をカスタマイズする
SpringApplication
には、コンテキストまたは環境にカスタマイズを適用するために使用される ApplicationListeners
および ApplicationContextInitializers
があります。Spring Boot は、META-INF/spring.factories
から内部的に使用するために、このようなカスタマイズの多くをロードします。追加のカスタマイズを登録する方法は複数あります。
プログラムごとに、アプリケーションごとに、
SpringApplication
でaddListeners
およびaddInitializers
メソッドを呼び出してから実行します。宣言的に、アプリケーションごとに、
context.initializer.classes
またはcontext.listener.classes
プロパティを設定することにより。宣言的に、すべてのアプリケーションについて、
META-INF/spring.factories
を追加し、すべてのアプリケーションがライブラリとして使用する jar ファイルをパッケージ化します。
SpringApplication
はいくつかの特別な ApplicationEvents
をリスナーに送信し(コンテキストが作成される前でも)、ApplicationContext
によって公開されたイベントのリスナーも登録します。完全なリストについては、「Spring Boot 機能」セクションの「アプリケーションイベントとリスナー」を参照してください。
EnvironmentPostProcessor
を使用して、アプリケーションコンテキストをリフレッシュする前に Environment
をカスタマイズすることもできます。次の例に示すように、各実装は META-INF/spring.factories
に登録する必要があります。
org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor
実装は任意のファイルをロードし、Environment
に追加できます。たとえば、次の例では、クラスパスから YAML 構成ファイルをロードします。
public class EnvironmentPostProcessorExample implements EnvironmentPostProcessor {
private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
Resource path = new ClassPathResource("com/example/myapp/config.yml");
PropertySource<?> propertySource = loadYaml(path);
environment.getPropertySources().addLast(propertySource);
}
private PropertySource<?> loadYaml(Resource path) {
if (!path.exists()) {
throw new IllegalArgumentException("Resource " + path + " does not exist");
}
try {
return this.loader.load("custom-resource", path).get(0);
}
catch (IOException ex) {
throw new IllegalStateException("Failed to load yaml configuration from " + path, ex);
}
}
}
Environment は、デフォルトで Spring Boot がロードするすべての通常のプロパティソースで既に準備されています。環境からファイルの場所を取得することが可能です。上記の例では、リストの最後に custom-resource プロパティソースを追加して、他の通常の場所のいずれかで定義されたキーが優先されるようにします。カスタム実装では、別の順序を定義できます。 |
@SpringBootApplication で @PropertySource を使用することは、Environment にカスタムリソースをロードする便利な方法のように思えるかもしれませんが、お勧めしません。このようなプロパティソースは、アプリケーションコンテキストがリフレッシュされるまで Environment に追加されません。これは、リフレッシュが開始される前に読み込まれる logging.* や spring.main.* などの特定のプロパティを構成するには遅すぎます。 |
1.4. ApplicationContext 階層を構築する (親またはルートコンテキストの追加)
ApplicationBuilder
クラスを使用して、親 / 子 ApplicationContext
階層を作成できます。詳細については、「Spring Boot 機能」セクションの「spring-boot-features.html」を参照してください。
1.5. 非 Web アプリケーションを作成する
すべての Spring アプリケーションが Web アプリケーション(または Web サービス)である必要はありません。main
メソッドでコードを実行するだけでなく、Spring アプリケーションをブートストラップして、使用するインフラストラクチャをセットアップする場合は、Spring Boot の SpringApplication
機能を使用できます。SpringApplication
は、Web アプリケーションが必要かどうかに応じて、ApplicationContext
クラスを変更します。これを支援するために最初にできることは、サーバー関連の依存関係(サーブレット API など)をクラスパスから除外することです。それができない場合(たとえば、同じコードベースから 2 つのアプリケーションを実行する場合)、SpringApplication
インスタンスで setWebApplicationType(WebApplicationType.NONE)
を明示的に呼び出すか、applicationContextClass
プロパティを設定できます(Java API または外部プロパティを使用)。ビジネスロジックとして実行するアプリケーションコードは、CommandLineRunner
として実装し、@Bean
定義としてコンテキストにドロップできます。
2. プロパティと構成
このセクションには、プロパティおよび構成設定の設定と読み取り、および Spring Boot アプリケーションとの相互作用に関するトピックが含まれています。
2.1. ビルド時にプロパティを自動的に展開
プロジェクトのビルド構成でも指定されている一部のプロパティをハードコードするのではなく、既存のビルド構成を代わりに使用して自動的に展開できます。これは、Maven と Gradle の両方で可能です。
2.1.1. Maven を使用した自動プロパティ拡張
リソースフィルタリングを使用して、Maven プロジェクトのプロパティを自動的に展開できます。spring-boot-starter-parent
を使用する場合、次の例に示すように、@[email protected] (英語)
プレースホルダーで Maven の「プロジェクトプロパティ」を参照できます。
app:
encoding: "@[email protected] (英語) "
java:
version: "@[email protected] (英語) "
そのようにフィルタリングされるのは本番構成のみです(言い換えると、src/test/resources にはフィルタリングは適用されません)。 |
addResources フラグを有効にすると、spring-boot:run ゴールは src/main/resources をクラスパスに直接追加できます(ホットリロードの目的で)。そうすると、リソースのフィルタリングとこの機能が回避されます。代わりに、exec:java ゴールを使用するか、プラグインの構成をカスタマイズできます。詳細については、プラグインの使用方法のページを参照してください。 |
スターターの親を使用しない場合は、pom.xml
の <build/>
要素内に次の要素を含める必要があります。
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
また、<plugins/>
内に次の要素を含める必要があります。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
<delimiters>
<delimiter>@</delimiter>
</delimiters>
<useDefaultDelimiters>false</useDefaultDelimiters>
</configuration>
</plugin>
構成で標準 Spring プレースホルダー(${placeholder} など)を使用する場合、useDefaultDelimiters プロパティは重要です。そのプロパティが false に設定されていない場合、これらはビルドによって拡張される可能性があります。 |
2.1.2. Gradle を使用した自動プロパティ拡張
次の例に示すように、Java プラグインの processResources
タスクを構成することにより、Gradle プロジェクトからプロパティを自動的に展開できます。
processResources {
expand(project.properties)
}
その後、次の例に示すように、プレースホルダーを使用して Gradle プロジェクトのプロパティを参照できます。
app.name=${name}
app.description=${description}
app:
name: "${name}"
description: "${description}"
Gradle の expand メソッドは、Groovy の SimpleTemplateEngine を使用して、${..} トークンを変換します。${..} スタイルは、Spring 独自のプロパティプレースホルダーメカニズムと競合します。Spring プロパティプレースホルダーと自動展開を併用するには、Spring プロパティプレースホルダーを次のようにエスケープします: \${..} 。 |
2.2. SpringApplication の構成の外部化
SpringApplication
には Bean プロパティ(主に setter)があるため、アプリケーションを作成するときに Java API を使用して動作を変更できます。または、spring.main.*
でプロパティを設定することにより、構成を外部化できます。例: application.properties
では、次の設定があります。
spring.main.web-application-type=none
spring.main.banner-mode=off
spring:
main:
web-application-type: "none"
banner-mode: "off"
その場合、起動時に Spring Boot バナーは出力されず、アプリケーションは組み込み Web サーバーを起動しません。
外部構成で定義されたプロパティは、ApplicationContext
の作成に使用されるソースの顕著な例外を除き、Java API で指定された値をオーバーライドします。次のアプリケーションを検討してください。
new SpringApplicationBuilder()
.bannerMode(Banner.Mode.OFF)
.sources(demo.MyApp.class)
.run(args);
次に、次の構成を検討します。
spring.main.sources=com.acme.Config,com.acme.ExtraConfig
spring.main.banner-mode=console
spring:
main:
sources: "com.acme.Config,com.acme.ExtraConfig"
banner-mode: "console"
実際のアプリケーションは(構成によって上書きされるように)バナーを示し、(次の順序で) ApplicationContext
ための 3 つのソースを使用: demo.MyApp
、com.acme.Config
、及び com.acme.ExtraConfig
。
2.3. アプリケーションの外部プロパティの場所を変更する
デフォルトでは、異なるソースのプロパティが定義済みの順序で Spring Environment
に追加されます(正確な順序については、「Spring Boot 機能」セクションの「spring-boot-features.html」を参照してください)。
次のシステムプロパティ(または環境変数)を指定して、動作を変更することもできます。
spring.config.name
(SPRING_CONFIG_NAME
): ファイル名のルートとしてのデフォルトはapplication
です。spring.config.location
(SPRING_CONFIG_LOCATION
): ロードするファイル(クラスパスリソースや URL など)。このドキュメントには別のEnvironment
プロパティソースが設定されており、システムプロパティ、環境変数、またはコマンドラインによってオーバーライドできます。
環境の設定に関係なく、Spring Boot は上記のように application.properties
を常にロードします。デフォルトでは、YAML が使用されている場合、「.yml」拡張子を持つファイルもリストに追加されます。
Spring Boot は、DEBUG
レベルでロードされた構成ファイルと、TRACE
レベルで見つからなかった候補をログに記録します。
詳細については、ConfigFileApplicationListener
: GitHub (英語) を参照してください。
2.4. 「短い」コマンドライン引数を使用する
コマンドラインで設定プロパティを設定するために、--server.port=9000
の代わりに --port=9000
を使用したい人もいます。次の例に示すように、application.properties
のプレースホルダーを使用して、この動作を有効にできます。
server.port=${port:8080}
server:
port: "${port:8080}"
spring-boot-starter-parent POM から継承する場合、maven-resources-plugins のデフォルトのフィルタートークンは ${*} から @ (つまり、${maven.token} ではなく @[email protected] (英語) )に変更され、Spring スタイルのプレースホルダーとの競合を防ぎます。application.properties の Maven フィルタリングを直接有効にしている場合は、デフォルトのフィルタートークンを変更して、他の区切り文字: Apache (英語) を使用することもできます。 |
この特定のケースでは、ポートバインディングは Heroku や Cloud Foundry などの PaaS 環境で機能します。これら 2 つのプラットフォームでは、PORT 環境変数が自動的に設定され、Spring は Environment プロパティの大文字のシノニムにバインドできます。 |
2.5. 外部プロパティに YAML を使用する
YAML は JSON のスーパーセットであるため、次の例に示すように、外部プロパティを階層形式で保存するための便利な構文です。
spring:
application:
name: "cruncher"
datasource:
driver-class-name: "com.mysql.jdbc.Driver"
url: "jdbc:mysql://localhost/test"
server:
port: 9000
application.yml
というファイルを作成し、クラスパスのルートに配置します。次に、snakeyaml
を依存関係に追加します(Maven は org.yaml:snakeyaml
を調整します。spring-boot-starter
を使用する場合は既に含まれています)。YAML ファイルは Java Map<String,Object>
(JSON オブジェクトのように)に解析され、Spring Boot はマップをフラット化して、Java の Properties
ファイルで多くの人が慣れているように、1 レベルの深さでピリオドで区切られたキーを持つようにします。
前述の YAML の例は、次の application.properties
ファイルに対応しています。
spring.application.name=cruncher
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost/test
server.port=9000
YAML の詳細については、「Spring Boot 機能」セクションの「spring-boot-features.html」を参照してください。
2.6. アクティブ Spring プロファイルを設定する
Spring Environment
にはこのための API がありますが、通常はシステムプロパティ(spring.profiles.active
)または OS 環境変数(SPRING_PROFILES_ACTIVE
)を設定します。また、次のように、-D
引数を使用してアプリケーションを起動できます(メインクラスまたは jar アーカイブの前に配置することを忘れないでください)。
$ java -jar -Dspring.profiles.active=production demo-0.0.1-SNAPSHOT.jar
Spring Boot では、次の例に示すように、application.properties
でアクティブなプロファイルを設定することもできます。
spring.profiles.active=production
spring:
profiles:
active: "production"
この方法で設定された値は、SpringApplicationBuilder.profiles()
メソッドではなく、システムプロパティまたは環境変数の設定に置き換えられます。後者の Java API を使用して、デフォルトを変更せずにプロファイルを拡張できます。
詳細については、「Spring Boot 機能」セクションの「spring-boot-features.html」を参照してください。
2.7. 環境に応じて構成を変更する
Spring Boot は、アクティブなプロファイルに基づいて条件付きでアクティブ化できるマルチドキュメント YAML ファイルとプロパティファイル(詳細は spring-boot-features.html を参照)をサポートしています。
ドキュメントに spring.config.activate.on-profile
キーが含まれている場合、プロファイル値(プロファイルのコンマ区切りリストまたはプロファイル式)が Spring Environment.acceptsProfiles()
メソッドに入力されます。次の例に示すように、プロファイル式が一致する場合、そのドキュメントは最終的なマージに含まれます(そうでない場合は含まれません)。
server.port=9000
#---
spring.config.activate.on-profile=development
server.port=9001
#---
spring.config.activate.on-profile=production
server.port=0
server:
port: 9000
---
spring:
config:
activate:
on-profile: "development"
server:
port: 9001
---
spring:
config:
activate:
on-profile: "production"
server:
port: 0
上記の例では、デフォルトのポートは 9000 です。ただし、「開発」という Spring プロファイルがアクティブな場合、ポートは 9001 です。「本番」がアクティブな場合、ポートは 0 です。
ドキュメントは、検出された順序でマージされます。後の値は前の値を上書きします。 |
2.8. 外部プロパティの組み込みオプションを理解する
Spring Boot は、実行時に application.properties
(または .yml
ファイルおよびその他の場所)から外部プロパティをアプリケーションにバインドします。1 つの場所にすべてのサポートされているプロパティの完全なリストはありません(技術的にはできません)。これは、クラスパス上の追加の jar ファイルから提供される可能性があるためです。
アクチュエーター機能を備えた実行中のアプリケーションには、configprops
エンドポイントがあり、@ConfigurationProperties
を介して使用可能なすべてのバインド済みプロパティとバインド可能プロパティが表示されます。
付録には、Spring Boot でサポートされる最も一般的なプロパティのリストを含む application.properties
の例が含まれています。最終的なリストは、@ConfigurationProperties
および @Value
アノテーションのソースコードを検索することと、Binder
をときどき使用することから得られます。読み込みプロパティの正確な順序の詳細については、「spring-boot-features.html」を参照してください。
3. 組み込み Web サーバー
各 Spring Boot Web アプリケーションには、組み込み Web サーバーが含まれています。この機能は、組み込みサーバーの変更方法や組み込みサーバーの構成方法など、多くの使い方の質問につながります。このセクションでは、これらの質問に回答します。
3.1. 別の Web サーバーを使用する
多くの Spring Boot スターターには、デフォルトの組み込みコンテナーが含まれています。
サーブレットスタックアプリケーションの場合、
spring-boot-starter-web
にはspring-boot-starter-tomcat
を含めることで Tomcat が含まれますが、代わりにspring-boot-starter-jetty
またはspring-boot-starter-undertow
を使用できます。リアクティブスタックアプリケーションの場合、
spring-boot-starter-webflux
にはspring-boot-starter-reactor-netty
を含めることにより Reactor Netty が含まれますが、代わりにspring-boot-starter-tomcat
、spring-boot-starter-jetty
またはspring-boot-starter-undertow
を使用できます。
別の HTTP サーバーに切り替えるときは、代わりにデフォルトの依存関係を必要なものと交換する必要があります。このプロセスを支援するために、Spring Boot はサポートされる HTTP サーバーごとに個別のスターターを提供します。
次の Maven の例は、Tomcat を除外し、Spring MVC に Jetty を含める方法を示しています。
<properties>
<servlet-api.version>3.1.0</servlet-api.version>
</properties>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- Exclude the Tomcat dependency -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Use Jetty instead -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
Tomcat 9 や Undertow 2.0 とは異なり、Jetty 9.4 は Servlet 4.0. をサポートしていないため、サーブレット API のバージョンはオーバーライドされています。 |
次の Gradle の例は、Spring WebFlux の Reactor Netty の代わりに Undertow を使用する方法を示しています。
configurations.all {
resolutionStrategy.dependencySubstitution.all { dependency ->
if (dependency.requested instanceof ModuleComponentSelector && dependency.requested.module == 'spring-boot-starter-reactor-netty') {
dependency.useTarget("org.springframework.boot:spring-boot-starter-undertow:$dependency.requested.version", 'Use Undertow instead of Reactor Netty')
}
}
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter-webflux'
// ...
}
WebClient クラスを使用するには spring-boot-starter-reactor-netty が必要なので、別の HTTP サーバーを含める必要がある場合でも、Netty への依存関係を維持する必要があります。 |
3.2. Web サーバーの無効化
クラスパスに Web サーバーの起動に必要なビットが含まれている場合、Spring Boot は自動的に起動します。この動作を無効にするには、次の例に示すように、application.properties
で WebApplicationType
を構成します。
spring.main.web-application-type=none
spring:
main:
web-application-type: "none"
3.3. HTTP ポートを変更する
スタンドアロンアプリケーションでは、メイン HTTP ポートはデフォルトで 8080
になりますが、server.port
で設定できます(たとえば、application.properties
またはシステムプロパティとして)。Environment
値の緩いバインディングのおかげで、SERVER_PORT
を使用することもできます(たとえば、OS 環境変数として)。
HTTP エンドポイントを完全にオフにしながら WebApplicationContext
を作成するには、server.port=-1
を使用します(そうすることはテストに役立つことがあります)。
詳細については、「Spring Boot 機能」セクションの「spring-boot-features.html」、または ServerProperties
: GitHub (英語) ソースコードを参照してください。
3.5. 実行時に HTTP ポートを発見する
サーバーが実行されているポートには、ログ出力から、または WebServerApplicationContext
から WebServer
を介してアクセスできます。これを取得して初期化されていることを確認する最良の方法は、タイプ ApplicationListener<WebServerInitializedEvent>
の @Bean
を追加し、発行時にコンテナーをイベントからプルすることです。
次の例に示すように、@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
を使用するテストでは、@LocalServerPort
アノテーションを使用して、実際のポートをフィールドに挿入することもできます。
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
public class MyWebIntegrationTests {
@LocalServerPort
int port;
// ...
}
|
3.6. HTTP レスポンス圧縮を有効にする
HTTP レスポンス圧縮は、Jetty、Tomcat、Undertow でサポートされています。次のように、application.properties
で有効にできます。
server.compression.enabled=true
server:
compression:
enabled: true
デフォルトでは、圧縮を実行するには、レスポンスの長さが少なくとも 2048 バイトである必要があります。server.compression.min-response-size
プロパティを設定することにより、この動作を構成できます。
デフォルトでは、コンテンツタイプが次のいずれかである場合にのみ、レスポンスが圧縮されます。
text/html
text/xml
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
server.compression.mime-types
プロパティを設定することにより、この動作を構成できます。
3.7. SSL を構成する
SSL は、通常 application.properties
または application.yml
でさまざまな server.ssl.*
プロパティを設定することにより、宣言的に構成できます。次の例は、application.properties
での SSL プロパティの設定を示しています。
server.port=8443
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=secret
server.ssl.key-password=another-secret
server:
port: 8443
ssl:
key-store: "classpath:keystore.jks"
key-store-password: "secret"
key-password: "another-secret"
サポートされているすべてのプロパティの詳細については、Ssl
: GitHub (英語) を参照してください。
上記の例のような構成を使用すると、アプリケーションはポート 8080 でプレーン HTTP コネクターをサポートしなくなります。Spring Boot は、application.properties
を介した HTTP コネクターと HTTPS コネクターの両方の構成をサポートしません。両方が必要な場合は、どちらかをプログラムで設定する必要があります。HTTP コネクターはプログラムで簡単に構成できるため、application.properties
を使用して HTTPS を構成することをお勧めします。
3.8. HTTP/2 を構成する
server.http2.enabled
構成プロパティを使用して、Spring Boot アプリケーションで HTTP/2 サポートを有効にすることができます。このプロトコルは JDK8 のすべてのリリースですぐにサポートされているわけではないため、このサポートは選択した Web サーバーとアプリケーション環境に依存します。
Spring Boot は、HTTP/2 プロトコルのクリアテキストバージョンである |
3.8.1. Tomcat を使用した HTTP/2
Spring Boot はデフォルトで Tomcat 9.0.x に同梱されており、JDK 9 以降を使用している場合はそのままで HTTP/2 をサポートしています。または、libtcnative
ライブラリとその依存関係がホストオペレーティングシステムにインストールされている場合、JDK 8 で HTTP/2 を使用できます。
ライブラリディレクトリは、JVM ライブラリパスで使用できるようにする必要があります(まだ使用していない場合)。-Djava.library.path=/usr/local/opt/tomcat-native/lib
などの JVM 引数を使用してこれを行うことができます。詳細については、Tomcat の公式ドキュメントを参照してください: Apache (英語) 。
そのネイティブサポートなしで JDK 8 で Tomcat 9.0.x を起動すると、次のエラーが記録されます。
ERROR 8787 --- [ main] o.a.coyote.http11.Http11NioProtocol : The upgrade handler [org.apache.coyote.http2.Http2Protocol] for [h2] only supports upgrade via ALPN but has been configured for the ["https-jsse-nio-8443"] connector that does not support ALPN.
このエラーは致命的ではなく、アプリケーションは引き続き HTTP/1.1 SSL サポートで開始されます。
3.8.2. Jetty を使用した HTTP/2
HTTP/2 サポートの場合、Jetty には追加の org.eclipse.jetty.http2:http2-server
依存関係が必要です。デプロイに応じて、他の依存関係も選択する必要があります。
JDK9 + で実行されているアプリケーションの
org.eclipse.jetty:jetty-alpn-java-server
JDK8u252 + で実行されているアプリケーションの
org.eclipse.jetty:jetty-alpn-openjdk8-server
org.eclipse.jetty:jetty-alpn-conscrypt-server
および暗号化ライブラリ (英語) (JDK 要件なし)
3.8.3. Reactor Netty を使用した HTTP/2
spring-boot-webflux-starter
は、デフォルトで Reactor Netty をサーバーとして使用しています。Reactor Netty は、JDK 9 以降の JDK サポートを使用して HTTP/2 用に構成できます。JDK 8 環境の場合、または最適な実行時パフォーマンスのために、このサーバーはネイティブライブラリで HTTP/2 もサポートします。それを可能にするには、アプリケーションに追加の依存関係が必要です。
Spring Boot は、すべてのプラットフォームのネイティブライブラリを含む io.netty:netty-tcnative-boringssl-static
"uber jar" のバージョンを管理します。開発者は、分類子を使用して必要な依存関係のみをインポートすることを選択できます(Netty 公式ドキュメント (英語) を参照)。
3.8.5. サポートされているサーバーを使用した HTTP/2 Cleartext
クリアテキストをサポートする HTTP/2 を有効にするには、server.http2.enabled
プロパティを false
に設定したままにし、代わりに選択したサーバーに固有のカスタマイザーを適用する必要があります。
Tomcat の場合、アップグレードプロトコルを追加する必要があります。
@Bean
public TomcatConnectorCustomizer connectorCustomizer() {
return (connector) -> connector.addUpgradeProtocol(new Http2Protocol());
}
Jetty の場合、既存のコネクターに接続ファクトリを追加する必要があります。
@Bean
public JettyServerCustomizer serverCustomizer() {
return (server) -> {
HttpConfiguration configuration = new HttpConfiguration();
configuration.setSendServerVersion(false);
Arrays.stream(server.getConnectors())
.filter(connector -> connector instanceof ServerConnector)
.map(ServerConnector.class::cast)
.forEach(connector -> {
connector.addConnectionFactory(new HTTP2CServerConnectionFactory(configuration));
});
};
}
Netty の場合、サポートされているプロトコルとして h2c
を追加する必要があります。
@Bean
public NettyServerCustomizer serverCustomizer() {
return (server) -> server.protocol(HttpProtocol.H2C);
}
Undertow の場合、HTTP2 オプションを有効にする必要があります。
@Bean
public UndertowBuilderCustomizer builderCustomizer() {
return (builder) -> {
builder.setServerOption(ENABLE_HTTP2, true);
};
}
3.9. Web サーバーを構成する
一般に、まず多くの利用可能な構成キーのいずれかを使用することを検討し、application.properties
(または application.yml
または環境など。「外部プロパティの組み込みオプションを理解する」を参照)に新しいエントリを追加して Web サーバーをカスタマイズします。server.*
名前空間はここでは非常に便利で、サーバー固有の機能のために server.tomcat.*
、server.jetty.*
などの名前空間が含まれています。appendix-application-properties.html のリストを参照してください。
前のセクションでは、圧縮、SSL、HTTP/2 など、すでに多くの一般的なユースケースについて説明しました。ただし、ユースケースに設定キーが存在しない場合は、WebServerFactoryCustomizer
(Javadoc) を確認する必要があります。このようなコンポーネントを宣言し、選択に関連するサーバーファクトリにアクセスできます。選択したサーバー(Tomcat、Jetty、Reactor、Netty、Undertow)および選択した Web スタック(サーブレットまたはリアクティブ)のバリアントを選択する必要があります。
以下の例は、spring-boot-starter-web
(サーブレットスタック)を使用した Tomcat の場合です。
@Component
public class MyTomcatWebServerCustomizer
implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory factory) {
// customize the factory here
}
}
Spring Boot は、そのインフラストラクチャを内部的に使用してサーバーを自動構成します。自動構成された WebServerFactoryCustomizer Bean には 0 の順序があり、特に明記されていない限り、ユーザー定義のカスタマイザーの前に処理されます。 |
カスタマイザーを使用して WebServerFactory
にアクセスできるようになると、それを使用して、コネクター、サーバーリソース、サーバー自体などの特定の部分を構成できます。これらはすべてサーバー固有の API を使用します。
さらに、Spring Boot は以下を提供します。
サーバー | サーブレットスタック | リアクティブスタック |
---|---|---|
Tomcat |
|
|
Jetty |
|
|
Undertow |
|
|
Reactor | なし |
|
最後の手段として、独自の WebServerFactory
Bean を宣言することもできます。これは、Spring Boot によって提供されるものをオーバーライドします。その場合でも、自動構成されたカスタマイザーはカスタムファクトリに適用されるため、そのオプションは慎重に使用してください。
3.10. サーブレット、フィルター、またはリスナーをアプリケーションに追加する
サーブレットスタックアプリケーション、つまり spring-boot-starter-web
を使用する場合、Servlet
、Filter
、ServletContextListener
と、サーブレット API でサポートされる他のリスナーをアプリケーションに追加するには、2 つの方法があります。
3.10.1. Spring Bean を使用して、サーブレット、フィルター、またはリスナーを追加する
Spring Bean を使用して Servlet
、Filter
またはサーブレット *Listener
を追加するには、@Bean
定義を提供する必要があります。これは、構成または依存関係を注入する場合に非常に役立ちます。ただし、アプリケーションライフサイクルの非常に早い段階でコンテナーにインストールする必要があるため、他の Bean の初期化が頻繁に行われないように注意する必要があります。(例: DataSource
または JPA 構成に依存させるのは得策ではありません)初期化ではなく、最初に使用したときに遅延して Bean を初期化することにより、このような制限を回避できます。
Filters
および Servlets
の場合、基礎となるコンポーネントの代わりに、またはそれに加えて、FilterRegistrationBean
または ServletRegistrationBean
を追加することにより、マッピングおよび初期化パラメーターを追加することもできます。
フィルター登録で |
他の Spring Bean と同様に、サーブレットフィルター Bean の順序を定義できます。「spring-boot-features.html」セクションを必ず確認してください。
サーブレットまたはフィルターの登録を無効にする
前述のように、Servlet
または Filter
Bean は、サーブレットコンテナーに自動的に登録されます。特定の Filter
または Servlet
Bean の登録を無効にするには、次の例に示すように、登録 Bean を作成し、無効としてマークします。
@Bean
public FilterRegistrationBean registration(MyFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
registration.setEnabled(false);
return registration;
}
3.11. アクセスログを構成する
Tomcat、Undertow、Jetty のアクセスログは、それぞれのネームスペースを使用して構成できます。
たとえば、次の設定は、カスタムパターン: Apache (英語) で Tomcat へのアクセスを記録します。
server.tomcat.basedir=my-tomcat
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%t %a %r %s (%D ms)
server:
tomcat:
basedir: "my-tomcat"
accesslog:
enabled: true
pattern: "%t %a %r %s (%D ms)"
ログのデフォルトの場所は、Tomcat ベースディレクトリに相対的な logs ディレクトリです。デフォルトでは、logs ディレクトリは一時ディレクトリです。そのため、Tomcat のベースディレクトリを修正するか、ログに絶対パスを使用することができます。上記の例では、ログはアプリケーションの作業ディレクトリに関連する my-tomcat/logs で利用可能です。 |
Undertow のアクセスロギングは、次の例に示すように、同様の方法で構成できます。
server.undertow.accesslog.enabled=true
server.undertow.accesslog.pattern=%t %a %r %s (%D ms)
server:
undertow:
accesslog:
enabled: true
pattern: "%t %a %r %s (%D ms)"
ログは、アプリケーションの作業ディレクトリに相対的な logs
ディレクトリに保存されます。server.undertow.accesslog.dir
プロパティを設定することにより、この場所をカスタマイズできます。
最後に、Jetty のアクセスロギングは次のように構成することもできます。
server.jetty.accesslog.enabled=true
server.jetty.accesslog.filename=/var/log/jetty-access.log
server:
jetty:
accesslog:
enabled: true
filename: "/var/log/jetty-access.log"
デフォルトでは、ログは System.err
にリダイレクトされます。詳細については、Jetty のドキュメントを参照してください。
3.12. フロントエンドプロキシサーバーの背後で実行する
アプリケーションがプロキシ、ロードバランサー、またはクラウド内で実行されている場合、リクエスト情報(ホスト、ポート、スキームなど)は途中で変更される可能性があります。アプリケーションは 10.10.10.10:8080
で実行されている可能性がありますが、HTTP クライアントは example.org
のみを見るはずです。
RFC7239「転送ヘッダー」 (英語) は、Forwarded
HTTP ヘッダーを定義します。プロキシはこのヘッダーを使用して、元のリクエストに関する情報を提供できます。これらのヘッダーを読み取るようにアプリケーションを設定し、リンクを作成して HTTP 302 レスポンス、JSON ドキュメント、または HTML ページでクライアントに送信するときにその情報を自動的に使用できます。X-Forwarded-Host
、X-Forwarded-Port
、X-Forwarded-Proto
、X-Forwarded-Ssl
や X-Forwarded-Prefix
などの非標準ヘッダーもあります。
プロキシが一般的に使用される X-Forwarded-For
および X-Forwarded-Proto
ヘッダーを追加する場合、server.forward-headers-strategy
を NATIVE
に設定するだけでサポートできます。このオプションを使用すると、Web サーバー自体がこの機能をネイティブでサポートします。特定のドキュメントを確認して、特定の動作について学ぶことができます。
これで十分でない場合、Spring Framework は ForwardedHeaderFilter を提供します。server.forward-headers-strategy
を FRAMEWORK
に設定することにより、アプリケーションでサーブレットフィルターとして登録できます。
Tomcat を使用していて、プロキシで SSL を終了している場合は、server.tomcat.redirect-context-root を false に設定する必要があります。これにより、リダイレクトが実行される前に X-Forwarded-Proto ヘッダーを受け入れることができます。 |
アプリケーションが Cloud Foundry または Heroku で実行されている場合、server.forward-headers-strategy プロパティはデフォルトで NATIVE になります。他のすべてのインスタンスでは、デフォルトで NONE になります。 |
3.12.1. Tomcat のプロキシ設定をカスタマイズする
Tomcat を使用する場合は、次の例に示すように、「転送された」情報を伝達するために使用されるヘッダーの名前を追加で構成できます。
server.tomcat.remoteip.remote-ip-header=x-your-remote-ip-header
server.tomcat.remoteip.protocol-header=x-your-protocol-header
server:
tomcat:
remoteip:
remote-ip-header: "x-your-remote-ip-header"
protocol-header: "x-your-protocol-header"
Tomcat は、信頼される内部プロキシに一致するデフォルトの正規表現を使用して構成されます。デフォルトでは、10/8
、192.168/16
、169.254/16
および 127/8
の IP アドレスは信頼されています。次の例に示すように、application.properties
にエントリを追加することにより、バルブの構成をカスタマイズできます。
server.tomcat.remoteip.internal-proxies=192\\.168\\.\\d{1,3}\\.\\d{1,3}
server:
tomcat:
remoteip:
internal-proxies: "192\\.168\\.\\d{1,3}\\.\\d{1,3}"
internal-proxies を空に設定することにより、すべてのプロキシを信頼できます(ただし、運用環境ではそうしないでください)。 |
自動をオフに切り替え(そのためには、server.forward-headers-strategy=NONE
を設定します)、WebServerFactoryCustomizer
Bean を使用して新しいバルブインスタンスを追加することにより、Tomcat の RemoteIpValve
の構成を完全に制御できます。
3.13. Tomcat で複数のコネクターを有効にする
次の例に示すように、org.apache.catalina.connector.Connector
を TomcatServletWebServerFactory
に追加して、HTTP および HTTPS コネクターを含む複数のコネクターを許可できます。
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> sslConnectorCustomizer() {
return (tomcat) -> tomcat.addAdditionalTomcatConnectors(createSslConnector());
}
private Connector createSslConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
try {
URL keystore = ResourceUtils.getURL("keystore");
URL truststore = ResourceUtils.getURL("truststore");
connector.setScheme("https");
connector.setSecure(true);
connector.setPort(8443);
protocol.setSSLEnabled(true);
protocol.setKeystoreFile(keystore.toString());
protocol.setKeystorePass("changeit");
protocol.setTruststoreFile(truststore.toString());
protocol.setTruststorePass("changeit");
protocol.setKeyAlias("apitester");
return connector;
}
catch (IOException ex) {
throw new IllegalStateException("Fail to create ssl connector", ex);
}
}
3.14. Tomcat の LegacyCookieProcessor を使用する
デフォルトでは、Spring Boot で使用される組み込み Tomcat は Cookie 形式の「バージョン 0」をサポートしていないため、次のエラーが表示される場合があります。
java.lang.IllegalArgumentException: An invalid character [32] was present in the Cookie value
可能な限り、後の Cookie 仕様に準拠した値のみを保存するようにコードを更新することを検討してください。ただし、Cookie の作成方法を変更できない場合は、代わりに LegacyCookieProcessor
を使用するように Tomcat を構成できます。LegacyCookieProcessor
に切り替えるには、次の例に示すように、TomcatContextCustomizer
を追加する WebServerFactoryCustomizer
Bean を使用します。
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieProcessorCustomizer() {
return (factory) -> factory
.addContextCustomizers((context) -> context.setCookieProcessor(new LegacyCookieProcessor()));
}
3.15. Tomcat の MBean レジストリを有効にする
組み込み Tomcat の MBean レジストリはデフォルトで無効になっています。これにより、Tomcat のメモリフットプリントが最小限に抑えられます。Tomcat の MBean を使用して、たとえば、Micrometer を介してメトリクスを公開できるようにする場合は、次の例に示すように、server.tomcat.mbeanregistry.enabled
プロパティを使用する必要があります。
server.tomcat.mbeanregistry.enabled=true
server:
tomcat:
mbeanregistry:
enabled: true
3.16. Undertow で複数のリスナーを有効にする
次の例に示すように、UndertowBuilderCustomizer
を UndertowServletWebServerFactory
に追加し、リスナーを Builder
に追加します。
@Bean
public WebServerFactoryCustomizer<UndertowServletWebServerFactory> undertowListenerCustomizer() {
return (factory) -> {
factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
@Override
public void customize(Builder builder) {
builder.addHttpListener(8080, "0.0.0.0");
}
});
};
}
3.17. @ServerEndpoint を使用して WebSocket エンドポイントを作成する
埋め込みコンテナーを使用した Spring Boot アプリケーションで @ServerEndpoint
を使用する場合は、次の例に示すように、単一の ServerEndpointExporter
@Bean
を宣言する必要があります。
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
前の例に示されている Bean は、@ServerEndpoint
アノテーション付き Bean を基礎となる WebSocket コンテナーに登録します。スタンドアロンサーブレットコンテナーにデプロイされる場合、このロールはサーブレットコンテナー初期化子によって実行され、ServerEndpointExporter
Bean は必要ありません。
4. Spring MVC
Spring Boot には、Spring MVC を含む多くのスターターがあります。一部のスターターには、Spring MVC に直接依存するのではなく、Spring MVC に依存することに注意してください。このセクションでは、Spring MVC および Spring Boot に関する一般的な質問に回答します。
4.1. JSON REST サービスを作成する
次の例に示すように、Spring Boot アプリケーションの Spring @RestController
は、Jackson2 がクラスパス上にある限り、デフォルトで JSON レスポンスをレンダリングする必要があります。
@RestController
public class MyController {
@RequestMapping("/thing")
public MyThing thing() {
return new MyThing();
}
}
Jackson2 が MyThing
を直列化できる限り(通常の POJO または Groovy オブジェクトの場合は true)、localhost:8080/thing
はデフォルトで JSON 表現を提供します。ブラウザーは XML を好む Accept ヘッダーを送信する傾向があるため、ブラウザーでは XML レスポンスが表示されることがあります。
4.2. XML REST サービスを作成する
クラスパスに Jackson XML 拡張(jackson-dataformat-xml
)がある場合、それを使用して XML レスポンスをレンダリングできます。JSON に使用した前の例は機能します。Jackson XML レンダラーを使用するには、次の依存関係をプロジェクトに追加します。
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
Jackson の XML 拡張機能が利用できず、JAXB が利用可能な場合、次の例に示すように、MyThing
に @XmlRootElement
としてアノテーションを付けるという追加要件を使用して XML をレンダリングできます。
@XmlRootElement
public class MyThing {
private String name;
// .. getters and setters
}
JAXB は、Java 8 でそのまま使用できる場合にのみ使用できます。最新の Java 世代を使用している場合は、プロジェクトに次の依存関係を追加します。
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>
サーバーに JSON ではなく XML をレンダリングさせるには、Accept: text/xml ヘッダーを送信する(またはブラウザーを使用する)必要があります。 |
4.3. Jackson ObjectMapper をカスタマイズする
Spring MVC(クライアントおよびサーバー側)は、HttpMessageConverters
を使用して、HTTP 交換でのコンテンツ変換をネゴシエートします。Jackson がクラスパス上にある場合、Jackson2ObjectMapperBuilder
が提供するデフォルトのコンバーターをすでに取得しています。そのインスタンスは自動的に構成されます。
ObjectMapper
(または Jackson XML コンバーターの場合は XmlMapper
)インスタンス(デフォルトで作成)には、以下のカスタマイズされたプロパティがあります。
MapperFeature.DEFAULT_VIEW_INCLUSION
は無効ですDeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
は無効ですSerializationFeature.WRITE_DATES_AS_TIMESTAMPS
は無効です
Spring Boot には、この動作を簡単にカスタマイズできるいくつかの機能もあります。
環境を使用して、ObjectMapper
および XmlMapper
インスタンスを構成できます。Jackson は、処理のさまざまなアスペクトを構成するために使用できるオン / オフ機能の広範なスイートを提供します。これらの機能は、環境内のプロパティにマップする 6 つの列挙型(Jackson 内)で説明されています。
列挙型 | プロパティ | 値 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
例:プリティプリントを有効にするには、spring.jackson.serialization.indent_output=true
を設定します。緩いバインディングの使用のおかげで、indent_output
のケースは対応する列挙定数のケースと一致する必要がないことに注意してください。これは INDENT_OUTPUT
です。
この環境ベースの構成は、自動構成された Jackson2ObjectMapperBuilder
Bean に適用され、自動構成された ObjectMapper
Bean を含む、ビルダーを使用して作成されたすべてのマッパーに適用されます。
コンテキストの Jackson2ObjectMapperBuilder
は、1 つ以上の Jackson2ObjectMapperBuilderCustomizer
Bean によってカスタマイズできます。このようなカスタマイザー Bean は並べ替えることができ(ブートのカスタマイザーの順序は 0)、ブートのカスタマイズの前後に追加のカスタマイズを適用できます。
タイプ com.fasterxml.jackson.databind.Module
の Bean はすべて、自動構成された Jackson2ObjectMapperBuilder
に自動的に登録され、作成する ObjectMapper
インスタンスに適用されます。これにより、アプリケーションに新しい機能を追加するときにカスタムモジュールを提供するグローバルメカニズムが提供されます。
デフォルトの ObjectMapper
を完全に置き換える場合は、そのタイプの @Bean
を定義して @Primary
としてマークするか、ビルダーベースのアプローチを好む場合は Jackson2ObjectMapperBuilder
@Bean
を定義します。どちらの場合でも、そうすると ObjectMapper
のすべての自動構成が無効になることに注意してください。
タイプ MappingJackson2HttpMessageConverter
の @Beans
を指定すると、MVC 構成のデフォルト値が置き換えられます。また、タイプ HttpMessageConverters
の便利な Bean が提供されます(デフォルトの MVC 構成を使用する場合は常に利用可能です)。デフォルトおよびユーザー拡張のメッセージコンバーターにアクセスするための便利な方法がいくつかあります。
詳細については、「@ResponseBody レンダリングのカスタマイズ」セクションおよび WebMvcAutoConfiguration
: GitHub (英語) ソースコードを参照してください。
4.4. @ResponseBody レンダリングのカスタマイズ
Spring は HttpMessageConverters
を使用して @ResponseBody
(または @RestController
からのレスポンス)をレンダリングします。Spring Boot コンテキストに適切なタイプの Bean を追加することにより、追加のコンバーターを提供できます。追加する Bean が、デフォルトで含まれるタイプ(JSON 変換の MappingJackson2HttpMessageConverter
など)の場合、デフォルト値を置き換えます。タイプ HttpMessageConverters
の便利な Bean が提供され、デフォルトの MVC 構成を使用する場合は常に利用可能です。デフォルトおよびユーザー拡張のメッセージコンバーターにアクセスするための便利なメソッドがいくつかあります(例:カスタム RestTemplate
に手動で挿入したい場合に便利です)。
通常の MVC の使用と同様に、提供する WebMvcConfigurer
Bean は、configureMessageConverters
メソッドをオーバーライドすることでコンバーターに貢献することもできます。ただし、通常の MVC とは異なり、必要な追加のコンバーターのみを提供できます(Spring Boot は同じメカニズムを使用してデフォルトを提供するため)。最後に、独自の @EnableWebMvc
構成を提供して Spring Boot のデフォルト MVC 構成をオプトアウトした場合、WebMvcConfigurationSupport
から getMessageConverters
を使用して完全に制御し、すべてを手動で行うことができます。
詳細については、WebMvcAutoConfiguration
: GitHub (英語) ソースコードを参照してください。
4.5. マルチパートファイルのアップロードの処理
Spring Boot は、ファイルのアップロードをサポートする Servlet 3 javax.servlet.http.Part
API を採用しています。デフォルトでは、Spring Boot は、1 回のリクエストでファイルあたり最大 1MB、最大 10MB のファイルデータで Spring MVC を構成します。MultipartProperties
クラスで公開されているプロパティを使用して、これらの値、中間データが保存される場所(たとえば、/tmp
ディレクトリ)、およびデータがディスクにフラッシュされるしきい値をオーバーライドできます。例:ファイルを無制限に指定する場合は、spring.servlet.multipart.max-file-size
プロパティを -1
に設定します。
マルチパートサポートは、Spring MVC コントローラーハンドラーメソッドで、タイプ MultipartFile
の @RequestParam
アノテーション付きパラメーターとしてマルチパートエンコードされたファイルデータを受信する場合に役立ちます。
詳細については、MultipartAutoConfiguration
: GitHub (英語) ソースを参照してください。
Apache Commons File Upload のような追加の依存関係を導入するのではなく、コンテナーの組み込みのマルチパートアップロードサポートを使用することをお勧めします。 |
4.6. Spring MVC DispatcherServlet のスイッチを切る
デフォルトでは、すべてのコンテンツはアプリケーションのルート(/
)から提供されます。別のパスにマップする場合は、次のように構成できます。
spring.mvc.servlet.path=/acme
spring:
mvc:
servlet:
path: "/acme"
追加のサーブレットがある場合、タイプごとに Servlet
または ServletRegistrationBean
タイプの @Bean
を宣言でき、Spring Boot はそれらをコンテナーに透過的に登録します。サーブレットはその方法で登録されるため、DispatcherServlet
を呼び出さずに DispatcherServlet
のサブコンテキストにマッピングできます。
DispatcherServlet
を自分で構成することは珍しいことですが、本当に必要な場合は、DispatcherServletPath
タイプの @Bean
も提供して、カスタム DispatcherServlet
のパスを提供する必要があります。
4.7. デフォルトの MVC 設定をオフにする
MVC 設定を完全に制御する最も簡単な方法は、独自の @Configuration
に @EnableWebMvc
アノテーションを提供することです。これを行うと、すべての MVC 設定が手元に残ります。
4.8. ViewResolvers をカスタマイズする
ViewResolver
は Spring MVC のコアコンポーネントであり、@Controller
のビュー名を実際の View
実装に変換します。ViewResolvers
は、REST スタイルのサービスではなく、主に UI アプリケーションで使用されることに注意してください(View
は @ResponseBody
のレンダリングには使用されません)。ViewResolver
の実装には多くの選択肢がありますが、Spring 自体は、どの実装を使用すべきかについて意見がありません。一方、Spring Boot は、クラスパスおよびアプリケーションコンテキストで検出した内容に応じて、1 つまたは 2 つをインストールします。DispatcherServlet
は、アプリケーションコンテキストで見つかったすべてのリゾルバーを使用し、結果が得られるまで各リゾルバーを順番に試行します。独自のものを追加する場合、順序とリゾルバーが追加される位置に注意する必要があります。
WebMvcAutoConfiguration
は、次の ViewResolvers
をコンテキストに追加します。
「defaultViewResolver」という名前の
InternalResourceViewResolver
。これは、DefaultServlet
を使用してレンダリングできる物理リソース(静的リソースと JSP ページを使用する場合はそれらを含む)を見つけます。ビュー名にプレフィックスとサフィックスを適用し、サーブレットコンテキストでそのパスを持つ物理リソースを探します(デフォルトは両方とも空ですが、spring.mvc.view.prefix
およびspring.mvc.view.suffix
を介して外部構成からアクセスできます)。同じタイプの Bean を提供することにより、オーバーライドできます。「beanNameViewResolver」という名前の
BeanNameViewResolver
。これは、ビューリゾルバーチェーンの有用なメンバーであり、解決されるView
と同じ名前の Bean をピックアップします。オーバーライドまたは置換する必要はありません。「viewResolver」という名前の
ContentNegotiatingViewResolver
は、実際にタイプView
の Bean が存在する 場合にのみ追加されます。これは「マスター」リゾルバーであり、他のすべてに委譲し、クライアントから送信された「Accept」HTTP ヘッダーに一致するものを見つけようとします。ContentNegotiatingViewResolver
に関する有用なブログ (英語) があり、詳細を学ぶために勉強することができます。また、ソースコードを参照して詳細を調べることもできます。「viewResolver」という名前の Bean を定義することにより、自動構成されたContentNegotiatingViewResolver
をオフに切り替えることができます。Thymeleaf を使用する場合、「thymeleafViewResolver」という名前の
ThymeleafViewResolver
もあります。ビュー名をプレフィックスとサフィックスで囲むことにより、リソースを探します。プレフィックスはspring.thymeleaf.prefix
で、サフィックスはspring.thymeleaf.suffix
です。プレフィックスとサフィックスの値は、デフォルトでそれぞれ「classpath:/templates/」と「.html」になります。同じ名前の Bean を提供することにより、ThymeleafViewResolver
をオーバーライドできます。FreeMarker を使用する場合、「freeMarkerViewResolver」という名前の
FreeMarkerViewResolver
もあります。ビュー名を接頭辞と接尾辞で囲むことにより、ローダーパス(spring.freemarker.templateLoaderPath
に外部化され、デフォルト値が「classpath:/templates/」である)でリソースを探します。プレフィックスはspring.freemarker.prefix
に外部化され、サフィックスはspring.freemarker.suffix
に外部化されます。プレフィックスとサフィックスのデフォルト値は、それぞれ空と「.ftlh」です。同じ名前の Bean を提供することにより、FreeMarkerViewResolver
をオーバーライドできます。Groovy テンプレートを使用する場合(実際には、
groovy-templates
がクラスパスにある場合)、「groovyMarkupViewResolver」という名前のGroovyMarkupViewResolver
もあります。ビュー名を接頭辞と接尾辞(spring.groovy.template.prefix
およびspring.groovy.template.suffix
に外部化)で囲むことにより、ローダーパス内のリソースを探します。プレフィックスとサフィックスのデフォルト値はそれぞれ「classpath:/templates/」と「.tpl」です。同じ名前の Bean を提供することにより、GroovyMarkupViewResolver
をオーバーライドできます。Mustache を使用する場合、「mustacheViewResolver」という名前の
MustacheViewResolver
もあります。ビュー名をプレフィックスとサフィックスで囲むことにより、リソースを探します。プレフィックスはspring.mustache.prefix
で、サフィックスはspring.mustache.suffix
です。接頭辞と接尾辞の値は、デフォルトでそれぞれ「classpath:/templates/」と「.mustache」になります。同じ名前の Bean を提供することにより、MustacheViewResolver
をオーバーライドできます。
詳細については、次のセクションを参照してください。
5. Spring Security を使用したテスト
Spring Security は、特定のユーザーとしてテストを実行するためのサポートを提供します。例:以下のスニペットのテストは、ADMIN
ロールを持つ認証済みユーザーで実行されます。
@Test
@WithMockUser(roles="ADMIN")
public void requestProtectedUrlWithUser() throws Exception {
mvc
.perform(get("/"))
...
}
Spring Security は Spring MVC Test との包括的な統合を提供し、これは @WebMvcTest
スライスと MockMvc
を使用してコントローラーをテストするときにも使用できます。
Spring Security のテストサポートの詳細については、Spring Security のリファレンスドキュメントを参照してください。
6. Jersey
6.1. Spring Security を使用した Jersey エンドポイントの保護
Spring Security は、Spring MVC ベースの Web アプリケーションを保護するために使用できるのとほぼ同じ方法で、Jersey ベースの Web アプリケーションを保護するために使用できます。ただし、Jersey で Spring Security のメソッドレベルセキュリティを使用する場合は、sendError(int)
ではなく setStatus(int)
を使用するように Jersey を構成する必要があります。これにより、Spring Security がクライアントに認証または認可の失敗を報告する機会を得る前に、Jersey がレスポンスをコミットすることを防ぎます。
次の例に示すように、アプリケーションの ResourceConfig
Bean で jersey.config.server.response.setStatusOverSendError
プロパティを true
に設定する必要があります。
@Component
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(Endpoint.class);
setProperties(Collections.singletonMap("jersey.config.server.response.setStatusOverSendError", true));
}
}
6.2. 別の Web フレームワークと一緒に Jersey を使用する
Spring MVC などの別の Web フレームワークとともに Jersey を使用するには、他のフレームワークが処理できないリクエストを処理できるように構成する必要があります。最初に、filter
の値で spring.jersey.type
アプリケーションプロパティを設定することにより、サーブレットではなくフィルターを使用するように Jersey を設定します。次に、次の例に示すように、結果として 404 になるリクエストを転送するように ResourceConfig
を構成します。
@Component
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(Endpoint.class);
property(ServletProperties.FILTER_FORWARD_ON_404, true);
}
}
7. HTTP クライアント
Spring Boot は、HTTP クライアントで動作する多くのスターターを提供します。このセクションでは、それらの使用に関する質問に回答します。
7.1. プロキシを使用するための RestTemplate の構成
spring-boot-features.html に従って、RestTemplateCustomizer
と RestTemplateBuilder
を使用して、カスタマイズされた RestTemplate
を作成できます。これは、プロキシを使用するように構成された RestTemplate
を作成するための推奨アプローチです。
プロキシ構成の正確な詳細は、使用されている基礎となるクライアントリクエストファクトリによって異なります。次の例では、192.168.0.5
を除くすべてのホストにプロキシを使用する HttpClient
で HttpComponentsClientRequestFactory
を構成します。
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));
}
}
7.2. Reactor Netty ベースの WebClient が使用する TcpClient を構成する
Reactor Netty がクラスパスにある場合、Reactor Netty ベースの WebClient
が自動構成されます。クライアントのネットワーク接続の処理をカスタマイズするには、ClientHttpConnector
Bean を提供します。次の例では、60 秒の接続タイムアウトを構成し、ReadTimeoutHandler
を追加します。
@Bean
ClientHttpConnector clientHttpConnector(ReactorResourceFactory resourceFactory) {
HttpClient httpClient = HttpClient.create(resourceFactory.getConnectionProvider())
.runOn(resourceFactory.getLoopResources()).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 60000)
.doOnConnected((connection) -> connection.addHandlerLast(new ReadTimeoutHandler(60)));
return new ReactorClientHttpConnector(httpClient);
}
接続プロバイダーおよびイベントループリソースに ReactorResourceFactory を使用していることに注意してください。これにより、リクエストを受信するサーバーとリクエストを行うクライアントのリソースを効率的に共有できます。 |
8. ログ
Spring Framework の spring-jcl
モジュールによって通常提供される Commons Logging API を除いて、Spring Boot には必須のロギング依存関係はありません。Logback (英語) を使用するには、それと spring-jcl
をクラスパスに含める必要があります。そのための推奨される方法は、すべて spring-boot-starter-logging
に依存するスターターを使用することです。Web アプリケーションの場合、spring-boot-starter-web
のみが必要です。これは、ロギングスターターに推移的に依存するためです。Maven を使用する場合、次の依存関係によりログが追加されます。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Spring Boot には、クラスパスのコンテンツに基づいてロギングを構成しようとする LoggingSystem
抽象化があります。Logback が利用可能な場合、それが最初の選択肢です。
ロギングに対して行う必要がある唯一の変更がさまざまなロガーのレベルの設定である場合、次の例に示すように、「logging.level」プレフィックスを使用して application.properties
で設定できます。
logging.level.org.springframework.web=debug
logging.level.org.hibernate=error
logging:
level:
org.springframework.web: "debug"
org.hibernate: "error"
logging.file.name
を使用して、(コンソールに加えて)ログを書き込むファイルの場所を設定することもできます。
ロギングシステムのよりきめ細かい設定を構成するには、対象の LoggingSystem
でサポートされているネイティブ構成形式を使用する必要があります。デフォルトでは、Spring Boot はシステムのデフォルトの場所(Logback の場合は classpath:logback.xml
など)からネイティブ構成を選択しますが、logging.config
プロパティを使用して構成ファイルの場所を設定できます。
8.1. ロギング用に Logback を構成する
application.properties
で達成できるもの以外に logback にカスタマイズを適用する必要がある場合は、標準の logback 構成ファイルを追加する必要があります。logback が検索できるように、logback.xml
ファイルをクラスパスのルートに追加できます。Spring Boot Logback 拡張を使用する場合は、logback-spring.xml
も使用できます。
Logback のドキュメントには、構成を詳細にカバーする専用セクションがあります (英語) 。 |
Spring Boot は、独自の構成から included
である多数の logback 構成を提供します。これらのインクルードは、特定の一般的な Spring Boot 規則を再適用できるように設計されています。
以下のファイルが org/springframework/boot/logging/logback/
で提供されています。
defaults.xml
- 変換ルール、パターンプロパティ、一般的なロガー構成を提供します。console-appender.xml
-CONSOLE_LOG_PATTERN
を使用してConsoleAppender
を追加します。file-appender.xml
- 適切な設定でFILE_LOG_PATTERN
およびROLLING_FILE_NAME_PATTERN
を使用してRollingFileAppender
を追加します。
さらに、以前のバージョンの Spring Boot との互換性のために、レガシー base.xml
ファイルが提供されています。
典型的なカスタム logback.xml
ファイルは次のようになります。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
<logger name="org.springframework.web" level="DEBUG"/>
</configuration>
logback 構成ファイルは、LoggingSystem
が作成するシステムプロパティを利用することもできます。
${PID}
: 現在のプロセス ID。${LOG_FILE}
:logging.file.name
がブートの外部構成で設定されたかどうか。${LOG_PATH}
:logging.file.path
(ログファイルが存在するディレクトリを表す)がブートの外部設定で設定されたかどうか。${LOG_EXCEPTION_CONVERSION_WORD}
:logging.exception-conversion-word
がブートの外部構成で設定されたかどうか。${ROLLING_FILE_NAME_PATTERN}
:logging.pattern.rolling-file-name
がブートの外部構成で設定されたかどうか。
また、Spring Boot は、カスタム Logback コンバーターを使用して、コンソール上に(ログファイルではなく)素敵な ANSI カラーターミナル出力を提供します。例については、defaults.xml
構成の CONSOLE_LOG_PATTERN
を参照してください。
Groovy がクラスパス上にある場合、logback.groovy
で Logback も構成できるはずです。存在する場合、この設定が優先されます。
Spring 拡張は、Groovy 構成ではサポートされていません。logback-spring.groovy ファイルは検出されません。 |
8.1.1. ファイルのみの出力用に Logback を構成する
コンソールロギングを無効にし、出力のみをファイルに書き込む場合は、次の例に示すように、console-appender.xml
ではなく file-appender.xml
をインポートするカスタム logback-spring.xml
が必要です。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
次の例に示すように、logging.file.name
を application.properties
または application.yaml
に追加する必要もあります。
logging.file.name=myapplication.log
logging:
file:
name: "myapplication.log"
8.2. ロギング用に Log4j を構成する
Spring Boot は、クラスパス上にある場合、ロギング構成の Log4j 2: Apache (英語) をサポートします。依存関係のアセンブルにスターターを使用する場合は、Logback を除外してから、代わりに log4j 2 を含める必要があります。スターターを使用しない場合は、Log4j 2 に加えて(少なくとも) spring-jcl
を提供する必要があります。
推奨されるパスは、多少の揺れが必要ですが、スターターを通るパスです。次の例は、Maven でスターターをセットアップする方法を示しています。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
また、次の例は、Gradle でスターターをセットアップする 1 つの方法を示しています。
dependencies {
compile 'org.springframework.boot:spring-boot-starter-web'
}
configurations.all {
resolutionStrategy.dependencySubstitution.all { dependency ->
if (dependency.requested instanceof ModuleComponentSelector && dependency.requested.module == 'spring-boot-starter-logging') {
dependency.useTarget("org.springframework.boot:spring-boot-starter-log4j2:$dependency.requested.version", 'Use Log4j2 instead of Logback')
}
}
}
}
Log4j スターターは、共通のロギング要件(Tomcat で java.util.logging を使用するが Log4j 2 を使用して出力を構成するなど)の依存関係を収集します。 |
java.util.logging を使用して実行されるデバッグロギングが Log4j 2 にルーティングされるようにするには、java.util.logging.manager システムプロパティを org.apache.logging.log4j.jul.LogManager に設定して、JDK ロギングアダプター: Apache (英語) を構成します。 |
8.2.1. YAML または JSON を使用して Log4j 2 を構成する
デフォルトの XML 構成形式に加えて、Log4j 2 は YAML および JSON 構成ファイルもサポートしています。別の構成ファイル形式を使用するように Log4j 2 を構成するには、次の例に示すように、適切な依存関係をクラスパスに追加し、選択したファイル形式に合わせて構成ファイルに名前を付けます。
フォーマット | 依存関係 | ファイル名 |
---|---|---|
YAML |
|
|
JSON |
|
|
9. データアクセス
Spring Boot には、データソースを操作するためのスタータが多数含まれています。このセクションでは、その方法に関する質問に回答します。
9.1. カスタム DataSource を構成する
独自の DataSource
を構成するには、構成でそのタイプの @Bean
を定義します。Spring Boot は、データベースの初期化を含め、DataSource
が必要な場所で再利用します。一部の設定を外部化する必要がある場合は、DataSource
を環境にバインドできます(「spring-boot-features.html」を参照)。
次の例は、Bean でデータソースを定義する方法を示しています。
@Bean
@ConfigurationProperties(prefix="app.datasource")
public DataSource dataSource() {
return new FancyDataSource();
}
次の例は、プロパティを設定してデータソースを定義する方法を示しています。
app.datasource.url=jdbc:h2:mem:mydb
app.datasource.username=sa
app.datasource.pool-size=30
app:
datasource:
url: "jdbc:h2:mem:mydb"
username: "sa"
pool-size: 30
FancyDataSource
に URL、ユーザー名、プールサイズの通常の JavaBean プロパティがあると仮定すると、これらの設定は、DataSource
が他のコンポーネントで使用可能になる前に自動的にバインドされます。定期的なデータベースの初期化も行われます(したがって、spring.datasource.*
の関連サブセットをカスタム構成で引き続き使用できます)。
Spring Boot は、DataSourceBuilder
と呼ばれるユーティリティビルダークラスも提供します。これは、標準データソースの 1 つを作成するために使用できます(クラスパス上にある場合)。ビルダーは、クラスパスで利用可能なものに基づいて、使用するものを検出できます。また、JDBC URL に基づいてドライバーを自動検出します。
次の例は、DataSourceBuilder
を使用してデータソースを作成する方法を示しています。
@Bean
@ConfigurationProperties("app.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
その DataSource
でアプリを実行するために必要なのは、接続情報だけです。プール固有の設定も提供できます。詳細については、実行時に使用される実装を確認してください。
次の例は、プロパティを設定して JDBC データソースを定義する方法を示しています。
app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.pool-size=30
app:
datasource:
url: "jdbc:mysql://localhost/test"
username: "dbuser"
password: "dbpass"
pool-size: 30
しかし、落とし穴があります。接続プールの実際の種類が公開されていないため、カスタム DataSource
のメタデータにキーが生成されず、( DataSource
インターフェースはプロパティを公開しないため) IDE で補完機能を使用できません。また、クラスパスに Hikari がある場合、Hikari には url
プロパティがない (ただし、jdbcUrl
プロパティはある) ため、この基本セットアップは機能しません。その場合は、設定を次のように書き直す必要があります。
app.datasource.jdbc-url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.pool-size=30
app:
datasource:
jdbc-url: "jdbc:mysql://localhost/test"
username: "dbuser"
password: "dbpass"
pool-size: 30
接続プールが DataSource
ではなく専用の実装を使用して返すように強制することで、これを修正できます。実行時に実装を変更することはできませんが、オプションのリストは明示的になります。
次の例は、DataSourceBuilder
で HikariDataSource
を作成する方法を示しています。
@Bean
@ConfigurationProperties("app.datasource")
public HikariDataSource dataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
DataSourceProperties
の機能を活用することで、つまり URL が提供されていない場合に適切なユーザー名とパスワードをデフォルトの組み込みデータベースに提供することで、さらに先に進むこともできます。DataSourceProperties
オブジェクトの状態から DataSourceBuilder
を簡単に初期化できるため、Spring Boot が自動的に作成する DataSource を挿入することもできます。ただし、その場合、構成は 2 つのネームスペースに分割されます: url
、username
、password
、type
、および spring.datasource
上の driver
と残りはカスタムネームスペース(app.datasource
)にあります。これを回避するには、次の例に示すように、カスタム名前空間でカスタム DataSourceProperties
を再定義できます。
@Bean
@Primary
@ConfigurationProperties("app.datasource")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@ConfigurationProperties("app.datasource.configuration")
public HikariDataSource dataSource(DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
この設定により、デフォルトで Spring Boot が行うことと同期されますが、専用の接続プールが(コードで)選択され、その設定が app.datasource.configuration
サブ名前空間で公開される点が異なります。DataSourceProperties
が url
/jdbcUrl
変換を処理するため、次のように構成できます。
app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.configuration.maximum-pool-size=30
app:
datasource:
url: "jdbc:mysql://localhost/test"
username: "dbuser"
password: "dbpass"
configuration:
maximum-pool-size: 30
Spring Boot は、Hikari 固有の設定を spring.datasource.hikari に公開します。この例では複数のデータソース実装をサポートしていないため、この例ではより一般的な configuration サブ名前空間を使用します。 |
カスタム構成では Hikari を選択するため、app.datasource.type は効果がありません。実際には、ビルダーはそこに設定する可能性のある値で初期化され、.type() の呼び出しによってオーバーライドされます。 |
詳細については、「Spring Boot 機能」セクションの「spring-boot-features.html」および DataSourceAutoConfiguration
: GitHub (英語) クラスを参照してください。
9.2. 2 つの DataSources を構成する
複数のデータソースを構成する必要がある場合は、前のセクションで説明したものと同じトリックを適用できます。ただし、DataSource
インスタンスの 1 つを @Primary
としてマークする必要があります。今後のさまざまな自動構成では、タイプごとに 1 つを取得できると予想されるためです。
独自の DataSource
を作成すると、自動構成はバックオフします。次の例では、自動構成がプライマリデータソースで提供するものとまったく同じ機能セットを提供します。
@Bean
@Primary
@ConfigurationProperties("app.datasource.first")
public DataSourceProperties firstDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
@ConfigurationProperties("app.datasource.first.configuration")
public HikariDataSource firstDataSource() {
return firstDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
@Bean
@ConfigurationProperties("app.datasource.second")
public BasicDataSource secondDataSource() {
return DataSourceBuilder.create().type(BasicDataSource.class).build();
}
データベース初期化機能がコピーを使用するように、firstDataSourceProperties に @Primary のフラグを立てる必要があります(初期化を使用する場合)。 |
両方のデータソースは、高度なカスタマイズにも対応しています。たとえば、次のように構成できます。
app.datasource.first.url=jdbc:mysql://localhost/first
app.datasource.first.username=dbuser
app.datasource.first.password=dbpass
app.datasource.first.configuration.maximum-pool-size=30
app.datasource.second.url=jdbc:mysql://localhost/second
app.datasource.second.username=dbuser
app.datasource.second.password=dbpass
app.datasource.second.max-total=30
app:
datasource:
first:
url: "jdbc:mysql://localhost/first"
username: "dbuser"
password: "dbpass"
configuration:
maximum-pool-size: 30
second:
url: "jdbc:mysql://localhost/second"
username: "dbuser"
password: "dbpass"
max-total: 30
次の例に示すように、セカンダリ DataSource
にも同じ概念を適用できます。
@Bean
@Primary
@ConfigurationProperties("app.datasource.first")
public DataSourceProperties firstDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
@ConfigurationProperties("app.datasource.first.configuration")
public HikariDataSource firstDataSource() {
return firstDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
@Bean
@ConfigurationProperties("app.datasource.second")
public DataSourceProperties secondDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@ConfigurationProperties("app.datasource.second.configuration")
public BasicDataSource secondDataSource() {
return secondDataSourceProperties().initializeDataSourceBuilder().type(BasicDataSource.class).build();
}
前の例では、Spring Boot が自動構成で使用するのと同じロジックを使用して、カスタム名前空間に 2 つのデータソースを構成します。各 configuration
サブ名前空間は、選択した実装に基づいて高度な設定を提供することに注意してください。
9.3. Spring Data リポジトリを使用する
Spring Data は、さまざまなフレーバーの @Repository
インターフェースの実装を作成できます。@Repositories
が @EnableAutoConfiguration
クラスの同じパッケージ(またはサブパッケージ)に含まれている限り、Spring Boot はそれらすべてを処理します。
多くのアプリケーションで必要なのは、クラスパスに正しい Spring Data 依存関係を置くことだけです。JPA には spring-boot-starter-data-jpa
、Mongodb には spring-boot-starter-data-mongodb
などがあります。開始するには、@Entity
オブジェクトを処理するリポジトリインターフェースをいくつか作成します。
Spring Boot は、検出した @EnableAutoConfiguration
に基づいて、@Repository
定義の場所を推測しようとします。さらに制御するには、@EnableJpaRepositories
アノテーション(Spring Data JPA から)を使用します。
Spring Data の詳細については、Spring Data プロジェクトページを参照してください。
9.4. Spring 構成から @Entity 定義を分離する
Spring Boot は、検出した @EnableAutoConfiguration
に基づいて、@Entity
定義の場所を推測しようとします。さらに制御するには、次の例に示すように、@EntityScan
アノテーションを使用できます。
@Configuration(proxyBeanMethods = false)
@EnableAutoConfiguration
@EntityScan(basePackageClasses=City.class)
public class Application {
//...
}
9.5. JPA プロパティの構成
Spring Data JPA は、ベンダーに依存しないいくつかの構成オプション(SQL ロギングのオプションなど)をすでに提供しており、Spring Boot はそれらのオプションと Hibernate のいくつかを外部構成プロパティとして公開しています。それらの一部はコンテキストに従って自動的に検出されるため、設定する必要はありません。
spring.jpa.hibernate.ddl-auto
は、ランタイム条件に応じて異なるデフォルト値を持っているため、特別なケースです。組み込みデータベースが使用され、スキーママネージャー(Liquibase や Flyway など)が DataSource
を処理していない場合、デフォルトは create-drop
になります。他のすべての場合、デフォルトは none
です。
使用するダイアレクトは JPA プロバイダーによって検出されます。ダイアレクトを自分で設定する場合は、spring.jpa.database-platform
プロパティを設定します。
設定する最も一般的なオプションを次の例に示します。
spring.jpa.hibernate.naming.physical-strategy=com.example.MyPhysicalNamingStrategy
spring.jpa.show-sql=true
spring:
jpa:
hibernate:
naming:
physical-strategy: "com.example.MyPhysicalNamingStrategy"
show-sql: true
また、spring.jpa.properties.*
のすべてのプロパティは、ローカル EntityManagerFactory
が作成されるときに、通常の JPA プロパティとして(プレフィックスが削除された状態で)渡されます。
例:Hibernate のバッチサイズを設定する場合は、 |
Hibernate プロパティに高度なカスタマイズを適用する必要がある場合は、EntityManagerFactory を作成する前に呼び出される HibernatePropertiesCustomizer Bean を登録することを検討してください。これは、自動構成によって適用されるものよりも優先されます。 |
9.6. Hibernate 命名戦略の構成
Hibernate は、2 つの異なる命名戦略 (英語) を使用して、オブジェクトモデルから対応するデータベース名に名前をマッピングします。spring.jpa.hibernate.naming.physical-strategy
プロパティと spring.jpa.hibernate.naming.implicit-strategy
プロパティをそれぞれ設定することにより、物理的および暗黙的な戦略実装の完全修飾クラス名を構成できます。または、ImplicitNamingStrategy
または PhysicalNamingStrategy
Bean がアプリケーションコンテキストで使用可能な場合、Hibernate はそれらを使用するように自動的に構成されます。
デフォルトでは、Spring Boot は SpringPhysicalNamingStrategy
を使用して物理的な命名戦略を構成します。この実装は、Hibernate 4: と同じテーブル構造を提供し、すべてのドットがアンダースコアに置き換えられ、キャメルケースもアンダースコアに置き換えられます。さらに、デフォルトでは、すべてのテーブル名は小文字で生成されます。例: TelephoneNumber
エンティティは telephone_number
テーブルにマップされます。スキーマで大文字と小文字が混在する識別子が必要な場合は、次の例に示すように、カスタム SpringPhysicalNamingStrategy
Bean を定義します。
@Bean
SpringPhysicalNamingStrategy caseSensitivePhysicalNamingStrategy() {
return new SpringPhysicalNamingStrategy() {
@Override
protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment) {
return false;
}
};
}
代わりに Hibernate 5 のデフォルトを使用する場合は、次のプロパティを設定します。
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
または、次の Bean を構成できます。
@Bean
public PhysicalNamingStrategy physicalNamingStrategy() {
return new PhysicalNamingStrategyStandardImpl();
}
詳細については、HibernateJpaAutoConfiguration
: GitHub (英語) および JpaBaseConfiguration
: GitHub (英語) を参照してください。
9.7. Hibernate 2 次キャッシュを構成する
Hibernate 2 次キャッシュ (英語) は、さまざまなキャッシュプロバイダーに対して構成できます。キャッシュプロバイダーを再度検索するように Hibernate を構成するのではなく、可能な場合はコンテキストで利用可能なものを提供することをお勧めします。
JCache でこれを行うには、まず org.hibernate:hibernate-jcache
がクラスパスで使用可能であることを確認します。次に、次の例に示すように、HibernatePropertiesCustomizer
Bean を追加します。
@Configuration(proxyBeanMethods = false)
public class HibernateSecondLevelCacheExample {
@Bean
public HibernatePropertiesCustomizer hibernateSecondLevelCacheCustomizer(JCacheCacheManager cacheManager) {
return (properties) -> properties.put(ConfigSettings.CACHE_MANAGER, cacheManager.getCacheManager());
}
}
このカスタマイザーは、アプリケーションが使用するものと同じ CacheManager
を使用するように Hibernate を構成します。別の CacheManager
インスタンスを使用することもできます。詳細については、Hibernate ユーザーガイドを参照してください (英語) 。
9.8. Hibernate コンポーネントでの依存性注入の使用
デフォルトでは、Spring Boot は BeanFactory
を使用する BeanContainer
実装を登録して、コンバーターとエンティティリスナーが通常の依存性注入を使用できるようにします。
hibernate.resource.beans.container
プロパティを削除または変更する HibernatePropertiesCustomizer
を登録することにより、この動作を無効化または調整できます。
9.9. カスタム EntityManagerFactory を使用する
EntityManagerFactory
の構成を完全に制御するには、「entityManagerFactory」という名前の @Bean
を追加する必要があります。Spring Boot 自動構成は、そのタイプの Bean が存在する場合、エンティティマネージャーをオフにします。
9.10. EntityManagers を 2 つ使用する
デフォルトの EntityManagerFactory
が正常に機能する場合でも、新しい EntityManagerFactory
を定義する必要があります。そうでない場合、そのタイプの 2 番目の Bean が存在すると、デフォルトがオフになります。Spring Boot が提供する EntityManagerBuilder
を使用して、Spring Boot を作成できます。または、次の例に示すように、Spring ORM から直接 LocalContainerEntityManagerFactoryBean
を使用できます。
// add two data sources configured as above
@Bean
public LocalContainerEntityManagerFactoryBean customerEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(customerDataSource())
.packages(Customer.class)
.persistenceUnit("customers")
.build();
}
@Bean
public LocalContainerEntityManagerFactoryBean orderEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(orderDataSource())
.packages(Order.class)
.persistenceUnit("orders")
.build();
}
LocalContainerEntityManagerFactoryBean 用の Bean を自分で作成すると、自動構成された LocalContainerEntityManagerFactoryBean の作成中に適用されたカスタマイズは失われます。例:Hibernate の場合、spring.jpa.hibernate プレフィックスのプロパティは LocalContainerEntityManagerFactoryBean に自動的に適用されません。命名戦略や DDL モードなどを設定するためにこれらのプロパティに依存していた場合、LocalContainerEntityManagerFactoryBean Bean を作成するときに明示的に設定する必要があります。一方、spring.jpa.properties を介して指定された自動構成 EntityManagerFactoryBuilder に適用されるプロパティは、自動構成 EntityManagerFactoryBuilder を使用して LocalContainerEntityManagerFactoryBean Bean を構築する場合に自動的に適用されます。 |
上記の構成は、ほとんど単独で機能します。図を完成させるには、2 つの EntityManagers
の TransactionManagers
も構成する必要があります。それらのいずれかを @Primary
としてマークすると、Spring Boot のデフォルトの JpaTransactionManager
によってピックアップされる可能性があります。もう 1 つは、新しいインスタンスに明示的に挿入する必要があります。または、両方にまたがる JTA トランザクションマネージャーを使用できる場合があります。
Spring Data を使用する場合、次の例に示すように、それに応じて @EnableJpaRepositories
を構成する必要があります。
@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = Customer.class,
entityManagerFactoryRef = "customerEntityManagerFactory")
public class CustomerConfiguration {
...
}
@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = Order.class,
entityManagerFactoryRef = "orderEntityManagerFactory")
public class OrderConfiguration {
...
}
9.11. 従来の persistence.xml ファイルを使用する
Spring Boot は、デフォルトでは META-INF/persistence.xml
を検索または使用しません。従来の persistence.xml
を使用する場合は、タイプ LocalEntityManagerFactoryBean
の独自の @Bean
(「entityManagerFactory」の ID を使用)を定義し、そこに永続性ユニット名を設定する必要があります。
デフォルト設定については、JpaBaseConfiguration
: GitHub (英語) を参照してください。
9.12. Spring Data JPA および Mongo リポジトリを使用する
Spring Data JPA と Spring Data Mongo はどちらも Repository
実装を自動的に作成できます。両方がクラスパスに存在する場合は、Spring Boot に作成するリポジトリを指示するために、追加の構成が必要になる場合があります。最も明示的な方法は、標準の Spring Data @EnableJpaRepositories
および @EnableMongoRepositories
アノテーションを使用して、Repository
インターフェースの場所を提供することです。
外部構成で自動構成リポジトリのオンとオフを切り替えるために使用できるフラグ(spring.data.*.repositories.enabled
および spring.data.*.repositories.type
)もあります。これは、たとえば、Mongo リポジトリをオフにし、自動構成された MongoTemplate
を使用したい場合に役立ちます。
他の自動構成された Spring Data リポジトリタイプ(Elasticsearch、Solr など)にも同じ障害と同じ機能が存在します。使用するには、アノテーションの名前とフラグを適宜変更します。
9.13. Spring Data の Web サポートのカスタマイズ
Spring Data は、Web アプリケーションで Spring Data リポジトリの使用を簡素化する Web サポートを提供します。Spring Boot は、構成をカスタマイズするために spring.data.web
名前空間にプロパティを提供します。Spring Data REST を使用している場合、代わりに spring.data.rest
名前空間のプロパティを使用する必要があることに注意してください。
9.14. Spring Data リポジトリを REST エンドポイントとして公開する
Spring MVC がアプリケーションで有効になっている場合、Spring Data REST は Repository
実装を REST エンドポイントとして公開できます。
Spring Boot は、RepositoryRestConfiguration
(英語) をカスタマイズする一連の有用なプロパティ(spring.data.rest
名前空間から)を公開します。追加のカスタマイズを提供する必要がある場合は、RepositoryRestConfigurer
(英語) Bean を使用する必要があります。
カスタム RepositoryRestConfigurer で順序を指定しない場合、Spring Boot が内部的に使用した後に実行されます。順序を指定する必要がある場合は、0 より大きいことを確認してください。 |
9.15. JPA によって使用されるコンポーネントを構成する
JPA が使用するコンポーネントを構成する場合は、JPA の前にコンポーネントが初期化されていることを確認する必要があります。コンポーネントが自動構成されると、Spring Boot がこれを処理します。例:Flyway が自動構成されている場合、Hibernate は Flyway に依存するように構成されているため、Flyway は Hibernate がデータベースを使用しようとする前にデータベースを初期化できます。
コンポーネントを自分で構成する場合は、EntityManagerFactoryDependsOnPostProcessor
サブクラスを使用して、必要な依存関係をセットアップする便利な方法として使用できます。例:インデックスマネージャーとして Elasticsearch で Hibernate Search を使用する場合、次の例に示すように、EntityManagerFactory
Bean は elasticsearchClient
Bean に依存するように構成する必要があります。
/**
* {@link EntityManagerFactoryDependsOnPostProcessor} that ensures that
* {@link EntityManagerFactory} beans depend on the {@code elasticsearchClient} bean.
*/
@Component
static class ElasticsearchEntityManagerFactoryDependsOnPostProcessor
extends EntityManagerFactoryDependsOnPostProcessor {
ElasticsearchEntityManagerFactoryDependsOnPostProcessor() {
super("elasticsearchClient");
}
}
9.16. 2 つの DataSources で jOOQ を構成する
jOOQ を複数のデータソースで使用する必要がある場合は、それぞれに対して独自の DSLContext
を作成する必要があります。詳細については、JooqAutoConfiguration: GitHub (英語) を参照してください。
特に、JooqExceptionTranslator および SpringTransactionProvider を再利用して、単一の DataSource で自動構成が行うことと同様の機能を提供できます。 |
10. データベースの初期化
SQL データベースは、スタックの種類に応じてさまざまな方法で初期化できます。もちろん、データベースが別のプロセスであれば、手動で行うこともできます。スキーマ生成には単一のメカニズムを使用することをお勧めします。
10.1. JPA を使用してデータベースを初期化する
JPA には DDL 生成のための機能があり、これらはデータベースに対して起動時に実行されるように設定できます。これは、2 つの外部プロパティによって制御されます。
spring.jpa.generate-ddl
(ブール型)は、機能のオンとオフを切り替え、ベンダーに依存しません。spring.jpa.hibernate.ddl-auto
(enum)は、よりきめ細かい方法で動作を制御する Hibernate 機能です。この機能については、このガイドの後半で詳しく説明します。
10.2. Hibernate を使用したデータベースの初期化
spring.jpa.hibernate.ddl-auto
を明示的に設定でき、標準の Hibernate プロパティ値は none
、validate
、update
、create
および create-drop
です。Spring Boot は、データベースが埋め込まれていると見なすかどうかに基づいて、デフォルト値を選択します。スキーママネージャーが検出されなかった場合はデフォルトで create-drop
になり、それ以外の場合は none
になります。埋め込みデータベースは、Connection
タイプと JDBCURL を調べることによって検出されます。hsqldb
、h2
、および derby
は候補であり、その他は候補ではありません。インメモリから「実際の」データベースに切り替えるときは、新しいプラットフォームにテーブルとデータが存在することを前提としないように注意してください。ddl-auto
を明示的に設定するか、他のメカニズムの 1 つを使用してデータベースを初期化する必要があります。
org.hibernate.SQL ロガーを有効にすることにより、スキーマ作成を出力できます。これは、デバッグモードを有効にすると自動的に行われます。 |
さらに、Hibernate が最初からスキーマを作成する場合(つまり、ddl-auto
プロパティが create
または create-drop
に設定される場合)、クラスパスのルートにある import.sql
という名前のファイルが起動時に実行されます。これは、デモや、慎重にテストする場合に役立ちますが、おそらく本番環境のクラスパスに配置したいものではありません。これは Hibernate 機能です(Spring とは関係ありません)。
10.3. 基本的な SQL スクリプトを使用してデータベースを初期化する
Spring Boot は、DataSource
のスキーマ(DDL スクリプト)を自動的に作成し、それを初期化できます(DML スクリプト)。標準のルートクラスパスの場所、それぞれ schema.sql
および data.sql
から SQL をロードします。さらに、Spring Boot は schema-${platform}.sql
および data-${platform}.sql
ファイル(存在する場合)を処理します。platform
は spring.datasource.platform
の値です。これにより、必要に応じてデータベース固有のスクリプトに切り替えることができます。例:データベースのベンダー名に設定することもできます(hsqldb
、h2
、oracle
、mysql
、postgresql
など)。
基本的な SQL スクリプトのみが使用される場合、Spring Boot は埋め込まれた spring.datasource.initialization-mode=always JPA ベースのアプリでは、Hibernate にスキーマを作成させるか、 spring.jpa.hibernate.ddl-auto=none Flyway や Liquibase などの高レベルのデータベース移行ツールを使用している場合は、単独で使用してスキーマを作成および初期化する必要があります。基本的な |
デフォルトでは、Spring Boot は Spring JDBC イニシャライザーのフェイルファースト機能を有効にします。これは、スクリプトが例外を引き起こす場合、アプリケーションの起動に失敗することを意味します。spring.datasource.continue-on-error
を設定することにより、その動作を調整できます。
10.4. R2DBC を使用してデータベースを初期化する
R2DBC を使用している場合、通常の DataSource
自動構成がバックオフされるため、上記のオプションはいずれも使用できません。
次の例に示すように、SQL スクリプトを使用して、起動時にデータベースを初期化できます。
@Configuration(proxyBeanMethods = false)
static class DatabaseInitializationConfiguration {
@Autowired
void initializeDatabase(ConnectionFactory connectionFactory) {
ResourceLoader resourceLoader = new DefaultResourceLoader();
Resource[] scripts = new Resource[] { resourceLoader.getResource("classpath:schema.sql"),
resourceLoader.getResource("classpath:data.sql") };
new ResourceDatabasePopulator(scripts).populate(connectionFactory).block();
}
}
または、Flyway または Liquibase のいずれかを構成して、移行中の DataSource
を構成することができます。これらのライブラリはどちらも、移行するデータベースの url
、username
および password
を設定するプロパティを提供します。
このオプションを選択する場合、org.springframework:spring-jdbc は依然として必須の依存関係です。 |
10.5. Spring Batch データベースを初期化する
Spring Batch を使用する場合、ほとんどの一般的なデータベースプラットフォーム用の SQL 初期化スクリプトがあらかじめパッケージ化されています。Spring Boot は、データベースタイプを検出し、起動時にこれらのスクリプトを実行できます。組み込みデータベースを使用する場合、これはデフォルトで行われます。次の例に示すように、任意のデータベースタイプに対して有効にすることもできます。
spring.batch.initialize-schema=always
spring:
batch:
initialize-schema: "always"
spring.batch.initialize-schema
を never
に設定することにより、初期化を明示的にオフにすることもできます。
10.6. 高レベルのデータベース移行ツールを使用する
Spring Boot は、Flyway (英語) と Liquibase (英語) の 2 つの高レベルの移行ツールをサポートしています。
10.6.1. 起動時に Flyway データベース移行を実行する
起動時に Flyway データベースの移行を自動的に実行するには、org.flywaydb:flyway-core
をクラスパスに追加します。
通常、移行は V<VERSION>__<NAME>.sql
という形式のスクリプトです(<VERSION>
は、「1」や「2_1」などのアンダースコアで区切られたバージョンです)。デフォルトでは、これらは classpath:db/migration
と呼ばれるディレクトリにありますが、spring.flyway.locations
を設定することでその場所を変更できます。これは、1 つ以上の classpath:
または filesystem:
ロケーションのコンマ区切りリストです。例:次の構成では、デフォルトのクラスパスの場所と /opt/migration
ディレクトリの両方でスクリプトを検索します。
spring.flyway.locations=classpath:db/migration,filesystem:/opt/migration
spring:
flyway:
locations: "classpath:db/migration,filesystem:/opt/migration"
特別な {vendor}
プレースホルダーを追加して、ベンダー固有のスクリプトを使用することもできます。以下を想定します。
spring.flyway.locations=classpath:db/migration/{vendor}
spring:
flyway:
locations: "classpath:db/migration/{vendor}"
db/migration
を使用するのではなく、前述の構成では、データベースのタイプ(MySQL の db/migration/mysql
など)に従って使用するディレクトリを設定します。サポートされているデータベースのリストは、DatabaseDriver
: GitHub (英語) で入手できます。
移行は Java で作成することもできます。Flyway は、JavaMigration
を実装する Bean で自動構成されます。
FlywayProperties
: GitHub (英語) は、Flyway のほとんどの設定と、移行を無効にするか、場所の確認をオフにするために使用できる追加プロパティの小さなセットを提供します。構成をさらに制御する必要がある場合は、FlywayConfigurationCustomizer
Bean の登録を検討してください。
Spring Boot は Flyway.migrate()
を呼び出して、データベースの移行を実行します。さらに制御したい場合は、FlywayMigrationStrategy
: GitHub (英語) を実装する @Bean
を提供してください。
Flyway は SQL および Java コールバック (英語) をサポートします。SQL ベースのコールバックを使用するには、コールバックスクリプトを classpath:db/migration
ディレクトリに配置します。Java ベースのコールバックを使用するには、Callback
を実装する 1 つ以上の Bean を作成します。このような Bean は Flyway
に自動的に登録されます。@Order
を使用するか、Ordered
を実装することでオーダーできます。非推奨の FlywayCallback
インターフェースを実装する Bean も検出できますが、Callback
Bean と一緒に使用することはできません。
デフォルトでは、Flyway はコンテキストで(@Primary
) DataSource
をオートワイヤーし、それを移行に使用します。別の DataSource
を使用する場合は、作成して、その @Bean
を @FlywayDataSource
としてマークできます。そのようにして 2 つのデータソースが必要な場合は、別のデータソースを作成して @Primary
としてマークしてください。または、外部プロパティで spring.flyway.[url,user,password]
を設定することにより、Flyway のネイティブ DataSource
を使用できます。spring.flyway.url
または spring.flyway.user
のいずれかを設定するだけで、Flyway が独自の DataSource
を使用できます。3 つのプロパティのいずれかが設定されていない場合、同等の spring.datasource
プロパティの値が使用されます。
Flyway を使用して、特定のシナリオのデータを提供することもできます。例:テスト固有の移行を src/test/resources
に配置できます。これらの移行は、テストのためにアプリケーションが開始されたときにのみ実行されます。また、特定のプロファイルがアクティブな場合にのみ特定の移行が実行されるように、プロファイル固有の構成を使用して spring.flyway.locations
をカスタマイズできます。例: application-dev.properties
では、次の設定を指定できます。
spring.flyway.locations=classpath:/db/migration,classpath:/dev/db/migration
spring:
flyway:
locations: "classpath:/db/migration,classpath:/dev/db/migration"
その設定では、dev/db/migration
の移行は、dev
プロファイルがアクティブな場合にのみ実行されます。
10.6.2. 起動時に Liquibase データベースの移行を実行する
起動時に Liquibase データベースの移行を自動的に実行するには、クラスパスに org.liquibase:liquibase-core
を追加します。
|
デフォルトでは、マスター変更ログは db/changelog/db.changelog-master.yaml
から読み取られますが、spring.liquibase.change-log
を設定して場所を変更できます。YAML に加えて、Liquibase は JSON、XML、SQL 変更ログ形式もサポートしています。
デフォルトでは、Liquibase は(@Primary
) DataSource
をコンテキストでオートワイヤーし、それを移行に使用します。別の DataSource
を使用する必要がある場合は、それを作成して、その @Bean
を @LiquibaseDataSource
としてマークできます。その場合、2 つのデータソースが必要な場合は、別のデータソースを作成して、@Primary
としてマークすることを忘れないでください。または、外部プロパティで spring.liquibase.[driver-class-name,url,user,password]
を設定することにより、Liquibase のネイティブ DataSource
を使用できます。Liquibase が独自の DataSource
を使用するには、spring.liquibase.url
または spring.liquibase.user
を設定するだけで十分です。3 つのプロパティのいずれかが設定されていない場合、対応する spring.datasource
プロパティの値が使用されます。
コンテキスト、デフォルトスキーマなどの利用可能な設定の詳細については、LiquibaseProperties
: GitHub (英語) を参照してください。
11. メッセージング
Spring Boot は、メッセージングを含む多くのスターターを提供します。このセクションでは、Spring Boot でメッセージングを使用することから生じる質問に回答します。
11.1. トランザクション JMS セッションを無効にする
JMS ブローカーがトランザクションセッションをサポートしていない場合、トランザクションのサポートを完全に無効にする必要があります。独自の JmsListenerContainerFactory
を作成する場合、デフォルトではトランザクションを処理できないため、実行することはありません。DefaultJmsListenerContainerFactoryConfigurer
を使用して Spring Boot のデフォルトを再利用する場合、次のようにトランザクションセッションを無効にできます。
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(
ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory listenerFactory =
new DefaultJmsListenerContainerFactory();
configurer.configure(listenerFactory, connectionFactory);
listenerFactory.setTransactionManager(null);
listenerFactory.setSessionTransacted(false);
return listenerFactory;
}
前述の例はデフォルトのファクトリをオーバーライドします。アプリケーションが定義する他のファクトリがある場合は、それを適用する必要があります。
12. バッチアプリケーション
Spring Boot アプリケーション内から Spring Batch を使用する場合、多くの質問がしばしば発生します。このセクションでは、これらの質問に対処します。
12.1. バッチデータソースの指定
デフォルトでは、バッチアプリケーションには、ジョブの詳細を保存するために DataSource
が必要です。Spring Batch は、デフォルトで単一の DataSource
を想定しています。アプリケーションのメイン DataSource
以外の DataSource
を使用するには、DataSource
Bean を宣言し、@BatchDataSource
で @Bean
メソッドにアノテーションを付けます。その場合、2 つのデータソースが必要な場合は、もう 1 つのデータソースを @Primary
としてマークすることを忘れないでください。制御を強化するには、BatchConfigurer
を実装します。詳細については、@EnableBatchProcessing
の Javadoc を参照してください。
Spring Batch の詳細については、Spring Batch プロジェクトページを参照してください。
12.2. 起動時に Spring Batch ジョブを実行する
@EnableBatchProcessing
を @Configuration
クラスの 1 つに追加すると、Spring Batch の自動構成が有効になります。
デフォルトでは、起動時にアプリケーションコンテキストですべての Jobs
を実行します(詳細については JobLauncherApplicationRunner
: GitHub (英語) を参照)。spring.batch.job.names
(ジョブ名パターンのコンマ区切りリストを使用)を指定することにより、特定のジョブに絞り込むことができます。
詳細については、BatchAutoConfiguration: GitHub (英語) および @EnableBatchProcessing (Javadoc) を参照してください。
12.3. コマンドラインから実行する
Spring Boot は、--
で始まるコマンドライン引数をプロパティに変換して、Environment
に追加します。コマンドラインプロパティへのアクセスを参照してください。これは、バッチジョブに引数を渡すために使用しないでください。コマンドラインでバッチ引数を指定するには、次の例に示すように、通常の形式(つまり --
なし)を使用します。
$ java -jar myapp.jar someParameter=someValue anotherParameter=anotherValue
コマンドラインで Environment
のプロパティを指定すると、ジョブによって無視されます。次のコマンドを検討してください。
$ java -jar myapp.jar --server.port=7070 someParameter=someValue
これは、バッチジョブに 1 つの引数 someParameter=someValue
のみを提供します。
12.4. ジョブリポジトリの保存
Spring Batch では、Job
リポジトリ用のデータストアが必要です。Spring Boot を使用する場合、実際のデータベースを使用する必要があります。インメモリデータベースでもかまいません。ジョブリポジトリの構成を参照してください。
13. アクチュエーター
Spring Boot には Spring Boot Actuator が含まれます。このセクションでは、その使用からしばしば生じる質問に回答します。
13.1. アクチュエーターエンドポイントの HTTP ポートまたはアドレスを変更する
スタンドアロンアプリケーションでは、アクチュエーターの HTTP ポートはデフォルトでメイン HTTP ポートと同じになります。アプリケーションが別のポートでリッスンするようにするには、外部プロパティ management.server.port
を設定します。管理用の内部ネットワークとユーザーアプリケーション用の外部ネットワークがある場合など、完全に異なるネットワークアドレスでリッスンするために、management.server.address
をサーバーがバインドできる有効な IP アドレスに設定することもできます。
詳細については、ManagementServerProperties
: GitHub (英語) ソースコードおよび「Production-ready features」セクションの「production-ready-features.html」を参照してください。
13.2. 「ホワイトラベル」エラーページをカスタマイズする
Spring Boot は、サーバーエラーが発生した場合にブラウザークライアントに表示される「ホワイトラベル」エラーページをインストールします(JSON およびその他のメディアタイプを使用するマシンクライアントは、適切なエラーコードで適切なレスポンスを確認する必要があります)。
server.error.whitelabel.enabled=false を設定して、デフォルトのエラーページをオフにします。これにより、使用しているサーブレットコンテナーのデフォルトが復元されます。Spring Boot は引き続きエラービューの解決を試みるため、完全に無効にするのではなく、おそらく独自のエラーページを追加する必要があります。 |
独自のエラーページを上書きするかどうかは、使用するテンプレート技術によって異なります。例:Thymeleaf を使用する場合、error.html
テンプレートを追加できます。FreeMarker を使用する場合は、error.ftlh
テンプレートを追加できます。一般に、error
という名前で解決される View
または /error
パスを処理する @Controller
が必要です。デフォルト構成の一部を置き換えない限り、ApplicationContext
に BeanNameViewResolver
が見つかるはずです。そのため、error
という名前の @Bean
がその 1 つの方法です。その他のオプションについては、ErrorMvcAutoConfiguration
: GitHub (英語) を参照してください。
サーブレットコンテナーにハンドラーを登録する方法の詳細については、「エラー処理」のセクションも参照してください。
13.3. 機密値を無害化する
env
エンドポイントと configprops
エンドポイントによって返される情報はやや機密性が高いため、特定のパターンに一致するキーはデフォルトでサニタイズされます(つまり、それらの値は ******
に置き換えられます)。
使用するパターンは、それぞれ management.endpoint.env.keys-to-sanitize
と management.endpoint.configprops.keys-to-sanitize
を使用してカスタマイズできます。
Spring Boot はこのようなキーに適切なデフォルトを使用します。「password」、「secret」、「key」、「token」、「vcap_services」、「sun.java.command」という語で終わるキーはすべて完全にサニタイズされます。さらに、キーの一部として credentials
という単語を保持するすべてのキーがサニタイズされます(正規表現として構成されます。つまり、*credentials.*
)。
さらに、Spring Boot は、「uri」、「uris」、「address」、または「addresses」で終わるキーの URI の機密部分のみをサニタイズします。URI の機密部分は、<scheme>://<username>:<password>@<host>:<port>/
形式で識別されます。例:プロパティ myclient.uri=http://user1:[email protected] (英語) :8081
の場合、結果のサニタイズされた値は http://user1:******@localhost:8081
です。
13.4. ヘルスインジケーターを Micrometer メトリクスにマップする
Spring Boot ヘルスインジケーターは、システム全体のヘルスを示す Status
タイプを返します。特定のアプリケーションのヘルスレベルを監視またはアラートする場合は、Micrometer を介してこれらのステータスをメトリクスとしてエクスポートできます。デフォルトでは、ステータスコード「UP」、「DOWN」、「OUT_OF_SERVICE」、「UNKNOWN」が Spring Boot によって使用されます。これらをエクスポートするには、これらの状態をいくつかの数値セットに変換して、Micrometer Gauge
で使用できるようにする必要があります。
次の例は、そのようなエクスポーターを作成する 1 つの方法を示しています。
@Configuration
public class HealthMetricsConfiguration {
public HealthMetricsConfiguration(MeterRegistry registry, HealthEndpoint healthEndpoint) {
// This example presumes common tags (such as the app) are applied elsewhere
Gauge.builder("health", healthEndpoint, this::getStatusCode).strongReference(true).register(registry);
}
private int getStatusCode(HealthEndpoint health) {
Status status = health.health().getStatus();
if (Status.UP.equals(status)) {
return 3;
}
if (Status.OUT_OF_SERVICE.equals(status)) {
return 2;
}
if (Status.DOWN.equals(status)) {
return 1;
}
return 0;
}
}
14. セキュリティ
このセクションでは、Spring Boot で Spring Security を使用することから生じる質問を含む、Spring Boot を使用する際のセキュリティに関する質問について説明します。
Spring Security の詳細については、Spring Security プロジェクトページを参照してください。
14.1. Spring Boot セキュリティ構成をオフにする
アプリケーションで WebSecurityConfigurerAdapter
または SecurityFilterChain
Bean を使用して @Configuration
を定義すると、Spring Boot のデフォルトの Web アプリセキュリティ設定がオフになります。
14.2. UserDetailsService の変更とユーザーアカウントの追加
タイプ AuthenticationManager
、AuthenticationProvider
または UserDetailsService
の @Bean
を提供する場合、InMemoryUserDetailsManager
のデフォルト @Bean
は作成されません。これは、Spring Security の完全な機能セット(さまざまな認証オプションなど)を使用できることを意味します。
ユーザーアカウントを追加する最も簡単な方法は、独自の UserDetailsService
Bean を提供することです。
14.3. プロキシサーバーの背後で実行するときに HTTPS を有効にする
すべてのメインエンドポイントが HTTPS 経由でのみ使用できるようにすることは、アプリケーションにとって重要な作業です。Tomcat をサーブレットコンテナーとして使用している場合、Spring Boot は、一部の環境設定を検出すると Tomcat 自身の RemoteIpValve
を自動的に追加し、HttpServletRequest
に依存して、安全かどうか(処理するプロキシサーバーの下流であっても)を報告できるはずです実際の SSL 終了)。標準の動作は、名前が従来のものである特定のリクエストヘッダー(x-forwarded-for
および x-forwarded-proto
)の有無によって決定されるため、ほとんどのフロントエンドプロキシで動作するはずです。次の例に示すように、application.properties
にいくつかのエントリを追加することにより、バルブをオンに切り替えることができます。
server.tomcat.remoteip.remote-ip-header=x-forwarded-for
server.tomcat.remoteip.protocol-header=x-forwarded-proto
server:
tomcat:
remoteip:
remote-ip-header: "x-forwarded-for"
protocol-header: "x-forwarded-proto"
(これらのプロパティのいずれかが存在すると、バルブが切り替わります。または、WebServerFactoryCustomizer
Bean を使用して TomcatServletWebServerFactory
をカスタマイズすることにより、RemoteIpValve
を追加できます)
すべて(または一部)のリクエストにセキュリティで保護されたチャネルをリクエストするように Spring Security を構成するには、次の HttpSecurity
構成を追加する独自の SecurityFilterChain
Bean を追加することを検討してください。
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// Customize the application security
http.requiresChannel().anyRequest().requiresSecure();
return http.build();
}
15. ホットスワップ
Spring Boot はホットスワップをサポートしています。このセクションでは、その仕組みに関する質問に回答します。
15.1. 静的コンテンツをリロードする
ホットリロードにはいくつかのオプションがあります。推奨されるアプローチは spring-boot-devtools
を使用することです。これは、アプリケーションの高速再起動や LiveReload のサポートなどの追加の開発時機能、および実用的な開発時設定(テンプレートキャッシングなど)を提供するためです。Devtools は、クラスパスの変更を監視することで機能します。つまり、変更を有効にするには、静的リソースの変更を「構築」する必要があります。デフォルトでは、変更を保存すると、Eclipse でこれが自動的に行われます。IntelliJ IDEA では、プロジェクトの作成コマンドが必要なビルドをトリガーします。デフォルトの再起動の除外により、静的リソースを変更してもアプリケーションの再起動はトリガーされません。ただし、ライブリロードはトリガーされます。
あるいは、IDE で実行する(特にデバッグをオンにした)ことは、開発を行うための良い方法です(すべての最新の IDE は静的リソースの再読み込みを許可し、通常 Java クラス変更のホットスワップも許可します)。
最後に、Maven および Gradle プラグインを構成して(addResources
プロパティを参照)、ソースから直接静的ファイルをリロードするコマンドラインからの実行をサポートできます。より高いレベルのツールを使用してコードを記述している場合は、外部の css/js コンパイラープロセスで使用できます。
15.2. コンテナーを再起動せずにテンプレートをリロードする
Spring Boot でサポートされるほとんどのテンプレートテクノロジには、キャッシュを無効にする構成オプションが含まれています(このドキュメントで後述)。spring-boot-devtools
モジュールを使用する場合、これらのプロパティは開発時に自動的に構成されます。
15.2.1. Thymeleaf テンプレート
Thymeleaf を使用する場合は、spring.thymeleaf.cache
を false
に設定します。他の Thymeleaf カスタマイズオプションについては、ThymeleafAutoConfiguration
: GitHub (英語) を参照してください。
15.2.2. FreeMarker テンプレート
FreeMarker を使用する場合は、spring.freemarker.cache
を false
に設定します。他の FreeMarker カスタマイズオプションについては、FreeMarkerAutoConfiguration
: GitHub (英語) を参照してください。
15.2.3. Groovy テンプレート
Groovy テンプレートを使用する場合、spring.groovy.template.cache
を false
に設定します。他の Groovy カスタマイズオプションについては、GroovyTemplateAutoConfiguration
: GitHub (英語) を参照してください。
15.3. 高速アプリケーション再起動
spring-boot-devtools
モジュールには、自動アプリケーション再起動のサポートが含まれています。JRebel (英語) などのテクノロジーほど高速ではありませんが、通常は「コールドスタート」よりも大幅に高速です。このドキュメントで後述する、より複雑なリロードオプションのいくつかを調査する前に、おそらく試してみるべきです。
詳細については、using-spring-boot.html セクションを参照してください。
16. ビルド
Spring Boot には、Maven および Gradle のビルドプラグインが含まれています。このセクションでは、これらのプラグインに関する一般的な質問に回答します。
16.1. ビルド情報を生成する
Maven プラグインと Gradle プラグインの両方で、プロジェクトの座標、名前、バージョンを含むビルド情報を生成できます。プラグインは、構成によって追加のプロパティを追加するように構成することもできます。そのようなファイルが存在する場合、Spring Boot は BuildProperties
Bean を自動構成します。
Maven でビルド情報を生成するには、次の例に示すように、build-info
ゴールの実行を追加します。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.4.2</version>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
詳細については、Spring Boot Maven プラグインのドキュメントを参照してください。 |
次の例は、Gradle でも同じことを行います。
springBoot {
buildInfo()
}
詳細については、Spring Boot Gradle プラグインのドキュメントを参照してください。 |
16.2. Git 情報を生成する
Maven と Gradle の両方により、プロジェクトのビルド時の git
ソースコードリポジトリの状態に関する情報を含む git.properties
ファイルを生成できます。
Maven ユーザーの場合、spring-boot-starter-parent
POM には、git.properties
ファイルを生成するための事前構成プラグインが含まれています。それを使用するには、次の宣言を POM に追加します。
<build>
<plugins>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
</plugin>
</plugins>
</build>
Gradle ユーザーは、次の例に示すように、gradle-git-properties
(英語) プラグインを使用して同じ結果を得ることができます。
plugins {
id "com.gorylenko.gradle-git-properties" version "2.2.4"
}
Maven プラグインと Gradle プラグインはどちらも、git.properties
に含まれているプロパティを構成できます。
git.properties のコミット時間は、次の形式と一致することが予想されます: yyyy-MM-dd’T’HH:mm:ssZ 。これは、上記の両方のプラグインのデフォルト形式です。この形式を使用すると、時間を解析して Date に変換し、その形式を JSON に直列化するときに、Jackson の日付の直列化構成設定で制御できます。 |
16.3. 依存関係バージョンのカスタマイズ
spring-boot-dependencies
POM は、一般的な依存関係のバージョンを管理します。Maven および Gradle の Spring Boot プラグインを使用すると、これらのマネージ依存バージョンをビルドプロパティを使用してカスタマイズできます。
各 Spring Boot リリースは、この特定のサードパーティ依存関係セットに対して設計およびテストされています。バージョンを上書きすると、互換性の問題が発生する場合があります。 |
依存関係バージョンを Maven でオーバーライドするには、Maven プラグインのドキュメントのこのセクションを参照してください。
Gradle の依存バージョンをオーバーライドするには、Gradle プラグインのドキュメントのこのセクションを参照してください。
16.4. Maven を使用して実行可能 JAR を作成する
spring-boot-maven-plugin
を使用して、実行可能な「fat 」JAR を作成できます。spring-boot-starter-parent
POM を使用する場合、プラグインを宣言でき、jar は次のように再パッケージ化されます。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
親 POM を使用しない場合でも、プラグインを使用できます。ただし、次のように <executions>
セクションを追加する必要があります。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.4.2</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
使用方法の詳細については、プラグインのドキュメントを参照してください。
16.5. Spring Boot アプリケーションを依存関係として使用する
war ファイルのように、Spring Boot アプリケーションは依存関係として使用されることを意図していません。アプリケーションに他のプロジェクトと共有するクラスが含まれている場合、推奨されるアプローチは、そのコードを別のモジュールに移動することです。個別のモジュールは、アプリケーションや他のプロジェクトに依存できます。
上記の推奨に従ってコードを再配置できない場合、Spring Boot の Maven および Gradle プラグインは、依存関係としての使用に適した個別のアーティファクトを生成するように構成する必要があります。実行可能 jar 形式は BOOT-INF/classes
のアプリケーションクラスをパッケージ化するため、実行可能アーカイブは依存関係として使用できません。つまり、実行可能ファイル jar が依存関係として使用されている場合、それらは見つかりません。
依存関係として使用できるアーティファクトと実行可能なアーティファクトを生成するには、分類子を指定する必要があります。この分類子は、実行可能アーカイブの名前に適用され、デフォルトのアーカイブは依存関係として使用されます。
Maven で exec
の分類子を構成するには、次の構成を使用できます。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
</plugins>
</build>
16.6. 実行可能 Jar の実行時に特定のライブラリを抽出する
実行可能 jar のネストされたライブラリのほとんどは、実行するために解凍する必要はありません。ただし、特定のライブラリには問題がある場合があります。例:JRuby には、独自のネストされた jar サポートが含まれています。これは、jruby-complete.jar
が常に独自のファイルとして直接利用可能であることを前提としています。
問題のあるライブラリを処理するために、実行可能ファイル jar が最初に実行されるときに、特定のネストされた jar が自動的に解凍されるようにフラグを立てることができます。このようなネストされた jar は、java.io.tmpdir
システムプロパティによって識別される一時ディレクトリに書き込まれます。
アプリケーションの実行中に一時ディレクトリに解凍された jar ファイルが削除されないように、オペレーティングシステムが設定されていることを確認する必要があります。 |
例:Maven プラグインを使用して、JRuby に解凍用のフラグを設定する必要があることを示すには、次の構成を追加します。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<requiresUnpack>
<dependency>
<groupId>org.jruby</groupId>
<artifactId>jruby-complete</artifactId>
</dependency>
</requiresUnpack>
</configuration>
</plugin>
</plugins>
</build>
16.7. 除外付きの非実行可能 JAR を作成する
多くの場合、2 つの別個のビルド製品として実行可能ファイルと実行不可能な jar がある場合、実行可能バージョンにはライブラリ jar で必要のない追加の構成ファイルがあります。例: application.yml
構成ファイルは、実行不可能な JAR から除外される場合があります。
Maven では、実行可能な jar がメインアーティファクトである必要があり、次のように、ライブラリに分類された jar を追加できます。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>lib</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>lib</classifier>
<excludes>
<exclude>application.yml</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
16.8. リモート Maven で開始した Spring Boot アプリケーションのデバッグ
Maven で開始された Spring Boot アプリケーションにリモートデバッガーを接続するには、maven プラグインの jvmArguments
プロパティを使用できます。
詳細については、この例を参照してください。
16.9. spring-boot-antlib を使用せずに Ant から実行可能アーカイブを構築する
Ant でビルドするには、依存関係を取得してコンパイルし、jar または war アーカイブを作成する必要があります。実行可能にするには、spring-boot-antlib
モジュールを使用するか、次の手順に従います。
jar を構築している場合、ネストされた
BOOT-INF/classes
ディレクトリにアプリケーションのクラスとリソースをパッケージ化します。war を構築する場合は、通常どおり、ネストされたWEB-INF/classes
ディレクトリにアプリケーションのクラスをパッケージ化します。jar のネストされた
BOOT-INF/lib
ディレクトリまたは war のWEB-INF/lib
にランタイム依存関係を追加します。アーカイブ内のエントリを圧縮しないでください。jar の場合はネストされた
BOOT-INF/lib
ディレクトリに、war の場合はWEB-INF/lib-provided
に、provided
(組み込みコンテナー)依存関係を追加します。アーカイブ内のエントリを圧縮しないでください。spring-boot-loader
クラスをアーカイブのルートに追加します(Main-Class
が利用できるように)。適切なランチャー(jar ファイルの
JarLauncher
など)をマニフェストのMain-Class
属性として使用し、必要な他のプロパティをマニフェストエントリとして指定します。主に、Start-Class
プロパティを設定します。
次の例は、Ant を使用して実行可能アーカイブを構築する方法を示しています。
<target name="build" depends="compile">
<jar destfile="target/${ant.project.name}-${spring-boot.version}.jar" compress="false">
<mappedresources>
<fileset dir="target/classes" />
<globmapper from="*" to="BOOT-INF/classes/*"/>
</mappedresources>
<mappedresources>
<fileset dir="src/main/resources" erroronmissingdir="false"/>
<globmapper from="*" to="BOOT-INF/classes/*"/>
</mappedresources>
<mappedresources>
<fileset dir="${lib.dir}/runtime" />
<globmapper from="*" to="BOOT-INF/lib/*"/>
</mappedresources>
<zipfileset src="${lib.dir}/loader/spring-boot-loader-jar-${spring-boot.version}.jar" />
<manifest>
<attribute name="Main-Class" value="org.springframework.boot.loader.JarLauncher" />
<attribute name="Start-Class" value="${start-class}" />
</manifest>
</jar>
</target>
17. 従来のデプロイ
Spring Boot は、従来のデプロイだけでなく、より新しい形式のデプロイもサポートします。このセクションでは、従来のデプロイに関する一般的な質問に回答します。
17.1. デプロイ可能な War ファイルを作成する
Spring WebFlux はサーブレット API に厳密に依存せず、アプリケーションはデフォルトで組み込み Reactor Netty サーバーにデプロイされるため、War デプロイは WebFlux アプリケーションではサポートされていません。 |
デプロイ可能な war ファイルを作成する最初のステップは、SpringBootServletInitializer
サブクラスを提供し、その configure
メソッドをオーバーライドすることです。これにより、Spring Framework の Servlet 3.0 サポートが利用され、サーブレットコンテナーによって起動されたときにアプリケーションを設定できます。通常、次の例に示すように、SpringBootServletInitializer
を継承するには、アプリケーションのメインクラスを更新する必要があります。
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
次のステップは、プロジェクトが jar ファイルではなく war ファイルを生成するようにビルド構成を更新することです。Maven および spring-boot-starter-parent
(Maven の war プラグインを構成する)を使用している場合は、次のように、pom.xml
を変更してパッケージを war に変更するだけです。
<packaging>war</packaging>
Gradle を使用する場合は、build.gradle
を変更して、war プラグインをプロジェクトに次のように適用する必要があります。
apply plugin: 'war'
プロセスの最後のステップは、組み込みサーブレットコンテナーが war ファイルのデプロイ先のサーブレットコンテナーと干渉しないようにすることです。そのためには、埋め込まれたサーブレットコンテナーの依存関係を提供済みとしてマークする必要があります。
Maven を使用する場合、次の例では、サーブレットコンテナー(この場合は Tomcat)が提供されているとマークします。
<dependencies>
<!-- … -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- … -->
</dependencies>
Gradle を使用する場合、次の例では、サーブレットコンテナー(この場合は Tomcat)が提供されているとマークします。
dependencies {
// …
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
// …
}
providedRuntime は、Gradle の compileOnly 構成よりも優先されます。他の制限の中でも、compileOnly 依存関係はテストクラスパスにないため、Web ベースの統合テストはすべて失敗します。 |
Spring Boot ビルドツールを使用する場合、組み込みサーブレットコンテナーの依存関係を提供済みとしてマークすると、提供された依存関係が lib-provided
ディレクトリにパッケージ化された実行可能な war ファイルが生成されます。つまり、サーブレットコンテナーにデプロイできることに加えて、コマンドラインで java -jar
を使用してアプリケーションを実行することもできます。
17.2. 既存のアプリケーションを Spring Boot に変換する
既存の非 Web Spring アプリケーションを Spring Boot アプリケーションに変換するには、ApplicationContext
を作成するコードを置き換え、それを SpringApplication
または SpringApplicationBuilder
への呼び出しに置き換えます。Spring MVC Web アプリケーションは通常、最初にデプロイ可能な war アプリケーションを作成してから、後で実行可能な war または jar に移行するのに適しています。jar から war への変換に関する入門ガイドを参照してください。
SpringBootServletInitializer
を継承して(たとえば Application
というクラスに)、Spring Boot @SpringBootApplication
アノテーションを追加してデプロイ可能な war を作成するには、次の例に示すようなコードを使用します。
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
// Customize the application or call application.sources(...) to add sources
// Since our example is itself a @Configuration class (via @SpringBootApplication)
// we actually don't need to override this method.
return application;
}
}
sources
に入れるものはすべて Spring ApplicationContext
に過ぎないことを忘れないでください。通常、すでに動作しているものはすべてここで動作するはずです。後で削除できる Bean があり、Spring Boot に独自のデフォルトを提供させることもありますが、それを行う前に何かを機能させることができるはずです。
静的リソースは、クラスパスルートの /public
(または /static
または /resources
または /META-INF/resources
)に移動できます。同じことが messages.properties
(Spring Boot がクラスパスのルートで自動的に検出します)にも当てはまります。
Spring DispatcherServlet
および Spring Security のバニラ使用には、それ以上の変更は必要ありません。アプリケーションに他の機能がある場合(たとえば、他のサーブレットやフィルターを使用する場合)、web.xml
の要素を次のように置き換えることにより、Application
コンテキストに設定を追加する必要がある場合があります。
タイプ
Servlet
またはServletRegistrationBean
の@Bean
は、あたかもweb.xml
の<servlet/>
および<servlet-mapping/>
であるかのように、その Bean をコンテナーにインストールします。タイプ
Filter
またはFilterRegistrationBean
の@Bean
は、同様に動作します(<filter/>
および<filter-mapping/>
として)。XML ファイルの
ApplicationContext
は、Application
の@ImportResource
を介して追加できます。あるいは、アノテーション構成がすでに頻繁に使用されている場合は、@Bean
定義として数行で再作成できます。
war ファイルが機能したら、次の例に示すように、main
メソッドを Application
に追加して実行可能にすることができます。
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
アプリケーションを war または実行可能アプリケーションとして開始する場合は、
|
アプリケーションは複数のカテゴリに分類できます。
web.xml
のない Servlet 3.0+ アプリケーション。web.xml
を使用したアプリケーション。コンテキスト階層を持つアプリケーション。
コンテキスト階層のないアプリケーション。
これらはすべて翻訳に適しているはずですが、それぞれがわずかに異なる技術を必要とする場合があります。
Servlet 3.0+ アプリケーションは、すでに Spring Servlet 3.0+ 初期化子サポートクラスを使用している場合、非常に簡単に変換できます。通常、既存の WebApplicationInitializer
からのすべてのコードは SpringBootServletInitializer
に移動できます。既存のアプリケーションに複数の ApplicationContext
がある場合(たとえば、AbstractDispatcherServletInitializer
を使用する場合)、すべてのコンテキストソースを単一の SpringApplication
に結合できる場合があります。発生する可能性のある主な問題は、結合が機能せず、コンテキスト階層を維持する必要がある場合です。例については、階層の構築に関するエントリを参照してください。通常、Web 固有の機能を含む既存の親コンテキストは、すべての ServletContextAware
コンポーネントが子コンテキストに含まれるように分割する必要があります。
まだ Spring アプリケーションではないアプリケーションは、Spring Boot アプリケーションに変換できる場合があり、前述のガイダンスが役立つ場合があります。ただし、まだ問題が発生する場合があります。その場合は、spring-boot
のタグを使用して Stack Overflow で質問する (英語) ことをお勧めします。
17.3. WebLogic への WAR のデプロイ
Spring Boot アプリケーションを WebLogic にデプロイするには、サーブレット初期化子が WebApplicationInitializer
を直接実装していることを確認する必要があります(すでに実装している基本クラスから拡張する場合でも)。
WebLogic の一般的な初期化子は、次の例のようになります。
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.web.WebApplicationInitializer;
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer implements WebApplicationInitializer {
}
Logback を使用する場合は、WebLogic に、サーバーにプリインストールされているバージョンではなく、パッケージ化されたバージョンを優先するように指示する必要もあります。これを行うには、次の内容の WEB-INF/weblogic.xml
ファイルを追加します。
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app
xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
https://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd
http://xmlns.oracle.com/weblogic/weblogic-web-app
https://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
<wls:container-descriptor>
<wls:prefer-application-packages>
<wls:package-name>org.slf4j</wls:package-name>
</wls:prefer-application-packages>
</wls:container-descriptor>
</wls:weblogic-web-app>
17.4. Lettuce の代わりに Jedis を使用する
デフォルトでは、Spring Boot スターター(spring-boot-starter-data-redis
)は Lettuce: GitHub (英語) を使用します。その依存関係を除外し、代わりに Jedis: GitHub (英語) を含める必要があります。Spring Boot はこれらの依存関係の両方を管理するため、バージョンを指定せずに Jedis に切り替えることができます。
次の例は、Maven でこれを行う方法を示しています。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
次の例は、Gradle でこれを行う方法を示しています。
dependencies {
implementation('org.springframework.boot:spring-boot-starter-data-redis') {
exclude group: 'io.lettuce', module: 'lettuce-core'
}
implementation 'redis.clients:jedis'
// ...
}
17.5. 統合テストに Testcontainers を使用する
テストコンテナー (英語) ライブラリは、Docker コンテナー内で実行されているサービスを管理する方法を提供します。JUnit と統合されているため、テストを実行する前にコンテナーを起動できるテストクラスを作成できます。Testcontainers は、MySQL、MongoDB、Cassandra などの実際のバックエンドサービスと通信する統合テストを作成する場合に特に便利です。テストコンテナーは、次のように Spring Boot テストで使用できます。
@SpringBootTest
@Testcontainers
class ExampleIntegrationTests {
@Container
static Neo4jContainer<?> neo4j = new Neo4jContainer<>();
}
これにより、テストが実行される前に、Neo4j を実行している docker コンテナーが起動します(Docker がローカルで実行されている場合)。ほとんどの場合、コンテナー IP やポートなど、実行中のコンテナーの詳細を使用してアプリケーションを構成する必要があります。
これは、動的なプロパティ値を Spring 環境に追加できる静的な @DynamicPropertySource
メソッドで実行できます。
@SpringBootTest
@Testcontainers
class ExampleIntegrationTests {
@Container
static Neo4jContainer<?> neo4j = new Neo4jContainer<>();
@DynamicPropertySource
static void neo4jProperties(DynamicPropertyRegistry registry) {
registry.add("spring.neo4j.uri", neo4j::getBoltUrl);
}
}
上記の構成により、アプリケーション内の Neo4j 関連の Bean が、Testcontainers が管理する Docker コンテナー内で実行されている Neo4j と通信できるようになります。