組み込み Web サーバー

各 Spring Boot Web アプリケーションには、組み込み Web サーバーが含まれています。この機能は、組み込みサーバーの変更方法や組み込みサーバーの構成方法など、多くの使い方の質問につながります。このセクションでは、これらの質問に回答します。

別の 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-tomcatspring-boot-starter-jettyspring-boot-starter-undertow を使用できます。

別の HTTP サーバーに切り替えるときは、代わりにデフォルトの依存関係を必要なものと交換する必要があります。このプロセスを支援するために、Spring Boot はサポートされる HTTP サーバーごとに個別のスターターを提供します。

次の Maven の例は、Tomcat を除外し、Spring MVC の Jetty を含める方法を示しています。

<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>

次の Gradle の例では、Spring WebFlux の Reactor Netty の代わりに Undertow を使用するために、必要な依存関係とモジュールの交換を構成 (英語) しています。

dependencies {
	implementation "org.springframework.boot:spring-boot-starter-undertow"
	implementation "org.springframework.boot:spring-boot-starter-webflux"
	modules {
		module("org.springframework.boot:spring-boot-starter-reactor-netty") {
			replacedBy("org.springframework.boot:spring-boot-starter-undertow", "Use Undertow instead of Reactor Netty")
		}
	}
}
 WebClient クラスを使用するには spring-boot-starter-reactor-netty が必要なので、別の HTTP サーバーを含める必要がある場合でも、Netty への依存関係を維持する必要があります。

Web サーバーの無効化

クラスパスに Web サーバーの起動に必要な設定が含まれている場合、Spring Boot は自動的に起動します。この動作を無効にするには、次の例に示すように、application.properties で WebApplicationType を構成します。

  • プロパティ

  • YAML

spring.main.web-application-type=none
spring:
  main:
    web-application-type: "none"

HTTP ポートを変更する

スタンドアロンアプリケーションでは、メイン HTTP ポートはデフォルトで 8080 になりますが、server.port で設定できます(たとえば、application.properties またはシステムプロパティとして)。Environment 値の緩いバインディングのおかげで、SERVER_PORT を使用することもできます(たとえば、OS 環境変数として)。

HTTP エンドポイントを完全にオフにしながら WebApplicationContext を作成するには、server.port=-1 を使用します(そうすることはテストに役立つことがあります)。

詳細については、「Spring Boot 機能」セクションの "埋め込みサーブレットコンテナーのカスタマイズ"、または ServerProperties (Javadoc) クラスを参照してください。

ランダムな未割り当ての HTTP ポートを使用する

(衝突を防ぐために OS ネイティブを使用して)空きポートをスキャンするには、server.port=0 を使用します。

実行時に HTTP ポートを発見する

サーバーが実行されているポートには、ログ出力から、または WebServerApplicationContext から WebServer を介してアクセスできます。これを取得して初期化されていることを確認する最良の方法は、型 ApplicationListener<WebServerInitializedEvent> の @Bean を追加し、発行時にコンテナーをイベントからプルすることです。

次の例に示すように、@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) を使用するテストでは、@LocalServerPort アノテーションを使用して、実際のポートをフィールドに挿入することもできます。

  • Java

  • Kotlin

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.server.LocalServerPort;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyWebIntegrationTests {

	@LocalServerPort
	int port;

	// ...

}
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment
import org.springframework.boot.test.web.server.LocalServerPort

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyWebIntegrationTests {

	@LocalServerPort
	var port = 0

	// ...

}

@LocalServerPort は @Value("${local.server.port}") のメタアノテーションです。通常のアプリケーションでポートを挿入しようとしないでください。先ほど見たように、値はコンテナーが初期化された後にのみ設定されます。テストとは異なり、アプリケーションコードのコールバックは早期に(値が実際に利用可能になる前に)処理されます。

HTTP レスポンス圧縮を有効にする

HTTP レスポンス圧縮は、Jetty、Tomcat、Reactor Netty、および Undertow でサポートされています。次のように、application.properties で有効にできます。

  • プロパティ

  • YAML

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 プロパティを設定することにより、この動作を構成できます。

SSL を構成する

SSL は、通常は application.properties または application.yaml のさまざまな server.ssl.* プロパティを設定することによって宣言的に構成できます。サポートされているすべてのプロパティの詳細については、Ssl (Javadoc) を参照してください。

次の例は、Java KeyStore ファイルを使用して SSL プロパティを設定する方法を示しています。

  • プロパティ

  • YAML

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"

上記の例のような構成を使用すると、アプリケーションはポート 8080 でプレーン HTTP コネクターをサポートしなくなります。Spring Boot は、application.properties を介した HTTP コネクターと HTTPS コネクターの両方の構成をサポートしません。両方が必要な場合は、どちらかをプログラムで設定する必要があります。HTTP コネクターはプログラムで簡単に構成できるため、application.properties を使用して HTTPS を構成することをお勧めします。

PEM エンコードされたファイルの使用

Java KeyStore ファイルの代わりに、PEM エンコードされたファイルを使用できます。可能な限り PKCS#8 キーファイルを使用する必要があります。PEM エンコードされた PKCS#8 キーファイルは、-----BEGIN PRIVATE KEY----- または -----BEGIN ENCRYPTED PRIVATE KEY----- ヘッダーで始まります。

PKCS#1 (-----BEGIN RSA PRIVATE KEY-----) や SEC 1 (-----BEGIN EC PRIVATE KEY-----) など、他の形式のファイルがある場合は、OpenSSL を使用して PKCS#8 に変換できます。

openssl pkcs8 -topk8 -nocrypt -in <input file> -out <output file>

次の例は、PEM でエンコードされた証明書と秘密鍵ファイルを使用して SSL プロパティを設定する方法を示しています。

  • プロパティ

  • YAML

server.port=8443
server.ssl.certificate=classpath:my-cert.crt
server.ssl.certificate-private-key=classpath:my-cert.key
server.ssl.trust-certificate=classpath:ca-cert.crt
server:
  port: 8443
  ssl:
    certificate: "classpath:my-cert.crt"
    certificate-private-key: "classpath:my-cert.key"
    trust-certificate: "classpath:ca-cert.crt"

SSL バンドルの使用

あるいは、次の例に示すように、SSL 信頼マテリアルを SSL バンドルで構成し、Web サーバーに適用することもできます。

  • プロパティ

  • YAML

server.port=8443
server.ssl.bundle=example
server:
  port: 8443
  ssl:
    bundle: "example"
server.ssl.bundle プロパティは、server.ssl の個別の Java KeyStore または PEM プロパティオプションと組み合わせることはできません。

サーバー名表示の構成

Tomcat、Netty、Undertow は、Server Name Indication (SNI) をサポートするために、個々のホスト名に固有の SSL トラストマテリアルを使用するように構成できます。SNI 構成は Jetty ではサポートされていませんが、複数の証明書が提供されている場合、Jetty は SNI を自動的にセットアップ (英語) できます。

webweb-alt1web-alt2 という名前の SSL バンドルが設定されていると仮定すると、次の設定を使用して、各バンドルを組み込み Web サーバーが提供するホスト名に割り当てることができます。

  • プロパティ

  • YAML

server.port=8443
server.ssl.bundle=web
server.ssl.server-name-bundles[0].server-name=alt1.example.com
server.ssl.server-name-bundles[0].bundle=web-alt1
server.ssl.server-name-bundles[1].server-name=alt2.example.com
server.ssl.server-name-bundles[1].bundle=web-alt2
server:
  port: 8443
  ssl:
    bundle: "web"
    server-name-bundles:
      - server-name: "alt1.example.com"
        bundle: "web-alt1"
      - server-name: "alt2.example.com"
        bundle: "web-alt2"

server.ssl.bundle で指定されたバンドルは、デフォルトのホストと、SNI をサポートするすべてのクライアントに使用されます。server.ssl.server-name-bundles が構成されている場合は、このデフォルトのバンドルを構成する必要があります。

HTTP/2 を構成する

server.http2.enabled 構成プロパティを使用して、Spring Boot アプリケーションで HTTP/2 サポートを有効にすることができます。h2 (HTTP/2 over TLS) と h2c (HTTP/2 over TCP) の両方がサポートされています。h2 を使用するには、SSL も有効にする必要があります。SSL が有効でない場合、h2c が使用されます。たとえば、アプリケーションが TLS ターミネーションを実行しているプロキシサーバーの背後で実行されている場合、h2c を使用することができます。

HTTP/2 と Tomcat

Spring Boot は、デフォルトで h2c および h2 をすぐにサポートする Tomcat 10.1.x と共に提供されます。または、ホストオペレーティングシステムにライブラリとその依存関係がインストールされている場合は、h2 サポートに libtcnative を使用できます。

ライブラリディレクトリは、JVM ライブラリパスで使用できるようにする必要があります(まだ使用していない場合)。-Djava.library.path=/usr/local/opt/tomcat-native/lib などの JVM 引数を使用してこれを行うことができます。詳細については、Tomcat の公式ドキュメントを参照してください [Apache] (英語)

Jetty を使用した HTTP/2

HTTP/2 をサポートするには、Jetty に追加の org.eclipse.jetty.http2:jetty-http2-server 依存関係が必要です。h2c を使用するために、他の依存関係は必要ありません。h2 を使用するには、デプロイに応じて、次の依存関係のいずれかを選択する必要もあります。

  • JDK 組み込みサポートを使用するための org.eclipse.jetty:jetty-alpn-java-server 

  • org.eclipse.jetty:jetty-alpn-conscrypt-server と暗号化ライブラリ (英語)

HTTP/2 と Reactor Netty

spring-boot-webflux-starter は、デフォルトで Reactor Netty をサーバーとして使用しています。Reactor Netty は、すぐに h2c と h2 をサポートします。実行時のパフォーマンスを最適化するために、このサーバーはネイティブライブラリで h2 もサポートしています。これを有効にするには、アプリケーションに追加の依存関係が必要です。

Spring Boot は、すべてのプラットフォームのネイティブライブラリを含む io.netty:netty-tcnative-boringssl-static "uber jar" のバージョンを管理します。開発者は、分類子を使用して必要な依存関係のみをインポートすることを選択できます(Netty 公式ドキュメント (英語) を参照)。

Undertow を使用した HTTP/2

Undertow は、すぐに h2c と h2 をサポートします。

Web サーバーを構成する

一般的には、まず利用可能な多くの構成キーの 1 つを使用することを検討し、application.properties または application.yaml ファイルに新しいエントリを追加して Web サーバーをカスタマイズする必要があります ( "外部プロパティの組み込みオプションを理解する" を参照)。ここでは server.* 名前空間が非常に役立ち、サーバー固有の機能のために server.tomcat.*server.jetty.* などの名前空間が含まれています。アプリケーションプロパティ設定一覧のリストを参照してください。

前のセクションでは、圧縮、SSL、HTTP/2 などの多くの一般的なユースケースについて説明しました。ただし、ユースケースの構成キーが存在しない場合は、WebServerFactoryCustomizer (Javadoc) を確認する必要があります。このようなコンポーネントを宣言して、選択に関連するサーバーファクトリにアクセスできます。選択したサーバー(Tomcat、Jetty、Reactor Netty、Undertow)および選択した Web スタック(サーブレットまたはリアクティブ)のバリアントを選択する必要があります。

以下の例は、spring-boot-starter-web (サーブレットスタック)を備えた Tomcat の場合です。

  • Java

  • Kotlin

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class MyTomcatWebServerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

	@Override
	public void customize(TomcatServletWebServerFactory factory) {
		// customize the factory here
	}

}
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.stereotype.Component

@Component
class MyTomcatWebServerCustomizer : WebServerFactoryCustomizer<TomcatServletWebServerFactory?> {

	override fun customize(factory: TomcatServletWebServerFactory?) {
		// customize the factory here
	}

}
Spring Boot は、そのインフラストラクチャを内部的に使用してサーバーを自動構成します。自動構成された WebServerFactoryCustomizer Bean の順序は 0 であり、特に明記されていない限り、ユーザー定義のカスタマイザーの前に処理されます。

カスタマイザーを使用して WebServerFactory にアクセスできるようになると、それを使用して、コネクター、サーバーリソース、サーバー自体などの特定の部分を構成できます。これらはすべてサーバー固有の API を使用します。

さらに、Spring Boot は以下を提供します。

サーバー サーブレットスタック リアクティブスタック

Tomcat

TomcatServletWebServerFactory

TomcatReactiveWebServerFactory

Jetty

JettyServletWebServerFactory

JettyReactiveWebServerFactory

Undertow

UndertowServletWebServerFactory

UndertowReactiveWebServerFactory

Reactor

なし

NettyReactiveWebServerFactory

最後の手段として、独自の WebServerFactory Bean を宣言することもできます。これは、Spring Boot によって提供されるものをオーバーライドします。その場合でも、自動構成されたカスタマイザーはカスタムファクトリに適用されるため、そのオプションは慎重に使用してください。

サーブレット、フィルター、リスナーをアプリケーションに追加する

サーブレットスタックアプリケーション、つまり spring-boot-starter-web では、ServletFilterServletContextListener と、サーブレット API でサポートされている他のリスナーをアプリケーションに追加する方法が 2 つあります。

Spring Bean を使用して、サーブレット、フィルター、リスナーを追加する

Spring Bean を使用して ServletFilter、サーブレット *Listener を追加するには、@Bean 定義を指定する必要があります。そうすることは、構成または依存関係を注入する場合に非常に役立ちます。ただし、アプリケーションのライフサイクルの非常に早い段階でコンテナーにインストールする必要があるため、他の多くの Bean の初期化を先行して行わないように十分に注意する必要があります。(例: DataSource または JPA の構成に依存させることはお勧めできません)初期化ではなく、最初に使用するときに Bean を遅延初期化することで、このような制限を回避できます。

フィルターとサーブレットの場合、基礎となるコンポーネントの代わりに、またはそれに加えて FilterRegistrationBean または ServletRegistrationBean を追加することにより、マッピングと初期化パラメーターを追加することもできます。

フィルター登録で dispatcherType が指定されていない場合は、REQUEST が使用されます。これは、サーブレット仕様のデフォルトのディスパッチャー型と一致します。

他の Spring Bean と同様に、サーブレットフィルター Bean の順序を定義できます。"サーブレット、フィルター、リスナーを Spring Bean として登録する" のセクションを必ず確認してください。

サーブレットまたはフィルターの登録を無効にする

前に説明したように、Servlet または Filter Bean はサーブレットコンテナーに自動的に登録されます。特定の Filter または Servlet Bean の登録を無効にするには、次の例に示すように、その登録 Bean を作成し、無効としてマークします。

  • Java

  • Kotlin

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyFilterConfiguration {

	@Bean
	public FilterRegistrationBean<MyFilter> registration(MyFilter filter) {
		FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>(filter);
		registration.setEnabled(false);
		return registration;
	}

}
import org.springframework.boot.web.servlet.FilterRegistrationBean
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyFilterConfiguration {

	@Bean
	fun registration(filter: MyFilter): FilterRegistrationBean<MyFilter> {
		val registration = FilterRegistrationBean(filter)
		registration.isEnabled = false
		return registration
	}

}

クラスパススキャンを使用してサーブレット、フィルター、リスナーを追加する

 @Configuration クラスに @ServletComponentScan アノテーションを付け、登録するコンポーネントを含むパッケージを指定することにより、@WebServlet@WebFilter@WebListener アノテーション付きクラスを組み込みサーブレットコンテナーに自動的に登録できます。デフォルトでは、@ServletComponentScan はアノテーション付きクラスのパッケージからスキャンします。

アクセスログを構成する

アクセスログは、Tomcat、Undertow、Jetty のそれぞれの名前空間を介して構成できます。

たとえば、次の設定は、カスタムパターン [Apache] (英語) で Tomcat へのアクセスを記録します。

  • プロパティ

  • YAML

server.tomcat.basedir=my-tomcat
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%t %a %r %s (%D microseconds)
server:
  tomcat:
    basedir: "my-tomcat"
    accesslog:
      enabled: true
      pattern: "%t %a %r %s (%D microseconds)"
ログのデフォルトの場所は、Tomcat ベースディレクトリに相対的な logs ディレクトリです。デフォルトでは、logs ディレクトリは一時ディレクトリです。そのため、Tomcat のベースディレクトリを修正するか、ログに絶対パスを使用することができます。上記の例では、ログはアプリケーションの作業ディレクトリに関連する my-tomcat/logs で利用可能です。

次の例に示すように、Undertow のアクセスログは同様の方法で構成できます。

  • プロパティ

  • YAML

server.undertow.accesslog.enabled=true
server.undertow.accesslog.pattern=%t %a %r %s (%D milliseconds)
server.undertow.options.server.record-request-start-time=true
server:
  undertow:
    accesslog:
      enabled: true
      pattern: "%t %a %r %s (%D milliseconds)"
    options:
      server:
        record-request-start-time: true

アクセスログの有効化とそのパターンの設定に加えて、リクエストの開始時間の記録も有効になっていることに注意してください。これは、アクセスログパターンにレスポンス時間 (%D) を含める場合に必要です。ログは、アプリケーションの作業ディレクトリに相対的な logs ディレクトリに保存されます。server.undertow.accesslog.dir プロパティを設定することで、この場所をカスタマイズできます。

最後に、Jetty のアクセスロギングは次のように構成することもできます。

  • プロパティ

  • YAML

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 のドキュメントを参照してください。

フロントエンドプロキシサーバーの背後で実行する

アプリケーションがプロキシ、ロードバランサー、クラウド内で実行されている場合、リクエスト情報(ホスト、ポート、スキームなど)は途中で変更される可能性があります。アプリケーションは 10.10.10.10:8080 で実行されている可能性がありますが、HTTP クライアントは example.org のみを見るはずです。

RFC7239「転送ヘッダー」 [IETF] (英語) は、Forwarded HTTP ヘッダーを定義します。プロキシはこのヘッダーを使用して、元のリクエストに関する情報を提供できます。これらのヘッダーを読み取り、リンクを作成して HTTP 302 レスポンス、JSON ドキュメント、HTML ページでクライアントに送信するときに、その情報を自動的に使用するようにアプリケーションを構成できます。X-Forwarded-HostX-Forwarded-PortX-Forwarded-ProtoX-Forwarded-SslX-Forwarded-Prefix のような非標準のヘッダーもあります。

プロキシが一般的に使用される X-Forwarded-For および X-Forwarded-Proto ヘッダーを追加する場合、server.forward-headers-strategy を NATIVE に設定するだけでサポートできます。このオプションを使用すると、Web サーバー自体がこの機能をネイティブでサポートします。特定のドキュメントを確認して、特定の動作について学ぶことができます。

これでは十分でない場合、Spring Framework はサーブレットスタック用の ForwardedHeaderFilter とリアクティブスタック用の ForwardedHeaderTransformer を提供します。server.forward-headers-strategy を FRAMEWORK に設定することで、アプリケーションでこれらを使用できます。

Tomcat を使用していて、プロキシで SSL を終了している場合は、server.tomcat.redirect-context-root を false に設定する必要があります。これにより、リダイレクトが実行される前に X-Forwarded-Proto ヘッダーを受け入れることができます。
アプリケーションがサポートされている Cloud Platform (Javadoc) で実行される場合、server.forward-headers-strategy プロパティはデフォルトで NATIVE に設定されます。それ以外の場合は、デフォルトで NONE に設定されます。

Tomcat のプロキシ設定をカスタマイズする

Tomcat を使用する場合は、次の例に示すように、「転送された」情報を伝達するために使用されるヘッダーの名前を追加で構成できます。

  • プロパティ

  • YAML

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 は、信頼される内部プロキシに一致する正規表現で構成されています。デフォルト値については、付録の server.tomcat.remoteip.internal-proxies エントリを参照してください。次の例に示すように、application.properties にエントリを追加することで、バルブの構成をカスタマイズできます。

  • プロパティ

  • YAML

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 の構成を完全に制御できます。

Tomcat で複数のコネクターを有効にする

次の例に示すように、org.apache.catalina.connector.Connector を TomcatServletWebServerFactory に追加して、HTTP および HTTPS コネクターを含む複数のコネクターを許可できます。

  • Java

  • Kotlin

import org.apache.catalina.connector.Connector;

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyTomcatConfiguration {

	@Bean
	public WebServerFactoryCustomizer<TomcatServletWebServerFactory> connectorCustomizer() {
		return (tomcat) -> tomcat.addAdditionalTomcatConnectors(createConnector());
	}

	private Connector createConnector() {
		Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
		connector.setPort(8081);
		return connector;
	}

}
import org.apache.catalina.connector.Connector
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyTomcatConfiguration {

	@Bean
	fun connectorCustomizer(): WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
		return WebServerFactoryCustomizer { tomcat: TomcatServletWebServerFactory ->
			tomcat.addAdditionalTomcatConnectors(
				createConnector()
			)
		}
	}

	private fun createConnector(): Connector {
		val connector = Connector("org.apache.coyote.http11.Http11NioProtocol")
		connector.port = 8081
		return connector
	}

}

Tomcat の MBean レジストリを有効にします

組み込み Tomcat の MBean レジストリはデフォルトで無効になっています。これにより、Tomcat のメモリフットプリントが最小限に抑えられます。たとえば、Tomcat の MBean を使用して、Micrometer がメトリクスを公開できるようにする場合は、次の例に示すように、server.tomcat.mbeanregistry.enabled プロパティを使用する必要があります。

  • プロパティ

  • YAML

server.tomcat.mbeanregistry.enabled=true
server:
  tomcat:
    mbeanregistry:
      enabled: true

Undertow で複数のリスナーを有効にする

次の例に示すように、UndertowBuilderCustomizer を UndertowServletWebServerFactory に追加し、リスナーを Builder に追加します。

  • Java

  • Kotlin

import io.undertow.Undertow.Builder;

import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyUndertowConfiguration {

	@Bean
	public WebServerFactoryCustomizer<UndertowServletWebServerFactory> undertowListenerCustomizer() {
		return (factory) -> factory.addBuilderCustomizers(this::addHttpListener);
	}

	private Builder addHttpListener(Builder builder) {
		return builder.addHttpListener(8080, "0.0.0.0");
	}

}
import io.undertow.Undertow
import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyUndertowConfiguration {

	@Bean
	fun undertowListenerCustomizer(): WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
		return WebServerFactoryCustomizer { factory: UndertowServletWebServerFactory ->
			factory.addBuilderCustomizers(
				UndertowBuilderCustomizer { builder: Undertow.Builder -> addHttpListener(builder) })
		}
	}

	private fun addHttpListener(builder: Undertow.Builder): Undertow.Builder {
		return builder.addHttpListener(8080, "0.0.0.0")
	}

}

@ServerEndpoint を使用して WebSocket エンドポイントを作成する

組み込みコンテナーを使用した Spring Boot アプリケーションで @ServerEndpoint を使用する場合は、次の例に示すように、単一の ServerEndpointExporter@Bean を宣言する必要があります。

  • Java

  • Kotlin

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration(proxyBeanMethods = false)
public class MyWebSocketConfiguration {

	@Bean
	public ServerEndpointExporter serverEndpointExporter() {
		return new ServerEndpointExporter();
	}

}
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.socket.server.standard.ServerEndpointExporter

@Configuration(proxyBeanMethods = false)
class MyWebSocketConfiguration {

	@Bean
	fun serverEndpointExporter(): ServerEndpointExporter {
		return ServerEndpointExporter()
	}

}

前の例に示されている Bean は、@ServerEndpoint アノテーション付き Bean を基礎となる WebSocket コンテナーに登録します。スタンドアロンサーブレットコンテナーにデプロイされる場合、このロールはサーブレットコンテナー初期化子によって実行され、ServerEndpointExporter Bean は必要ありません。