リアクティブ Web アプリケーション

Spring Boot は、Spring Webflux の自動構成を提供することにより、リアクティブ Web アプリケーションの開発を簡素化します。

「Spring WebFlux フレームワーク」

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

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

  • Java

  • Kotlin

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

	private final UserRepository userRepository;

	private final CustomerRepository customerRepository;

	public MyRestController(UserRepository userRepository, CustomerRepository customerRepository) {
		this.userRepository = userRepository;
		this.customerRepository = customerRepository;
	}

	@GetMapping("/{userId}")
	public Mono<User> getUser(@PathVariable Long userId) {
		return this.userRepository.findById(userId);
	}

	@GetMapping("/{userId}/customers")
	public Flux<Customer> getUserCustomers(@PathVariable Long userId) {
		return this.userRepository.findById(userId).flatMapMany(this.customerRepository::findByUser);
	}

	@DeleteMapping("/{userId}")
	public Mono<Void> deleteUser(@PathVariable Long userId) {
		return this.userRepository.deleteById(userId);
	}

}
import org.springframework.web.bind.annotation.DeleteMapping
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono

@RestController
@RequestMapping("/users")
class MyRestController(private val userRepository: UserRepository, private val customerRepository: CustomerRepository) {

	@GetMapping("/{userId}")
	fun getUser(@PathVariable userId: Long): Mono<User?> {
		return userRepository.findById(userId)
	}

	@GetMapping("/{userId}/customers")
	fun getUserCustomers(@PathVariable userId: Long): Flux<Customer> {
		return userRepository.findById(userId).flatMapMany { user: User? ->
			customerRepository.findByUser(user)
		}
	}

	@DeleteMapping("/{userId}")
	fun deleteUser(@PathVariable userId: Long): Mono<Void> {
		return userRepository.deleteById(userId)
	}

}

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

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

  • Java

  • Kotlin

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicate;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;

import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;

@Configuration(proxyBeanMethods = false)
public class MyRoutingConfiguration {

	private static final RequestPredicate ACCEPT_JSON = accept(MediaType.APPLICATION_JSON);

	@Bean
	public RouterFunction<ServerResponse> monoRouterFunction(MyUserHandler userHandler) {
		return route()
				.GET("/{user}", ACCEPT_JSON, userHandler::getUser)
				.GET("/{user}/customers", ACCEPT_JSON, userHandler::getUserCustomers)
				.DELETE("/{user}", ACCEPT_JSON, userHandler::deleteUser)
				.build();
	}

}
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.MediaType
import org.springframework.web.reactive.function.server.RequestPredicates.DELETE
import org.springframework.web.reactive.function.server.RequestPredicates.GET
import org.springframework.web.reactive.function.server.RequestPredicates.accept
import org.springframework.web.reactive.function.server.RouterFunction
import org.springframework.web.reactive.function.server.RouterFunctions
import org.springframework.web.reactive.function.server.ServerResponse

@Configuration(proxyBeanMethods = false)
class MyRoutingConfiguration {

	@Bean
	fun monoRouterFunction(userHandler: MyUserHandler): RouterFunction<ServerResponse> {
		return RouterFunctions.route(
			GET("/{user}").and(ACCEPT_JSON), userHandler::getUser).andRoute(
			GET("/{user}/customers").and(ACCEPT_JSON), userHandler::getUserCustomers).andRoute(
			DELETE("/{user}").and(ACCEPT_JSON), userHandler::deleteUser)
	}

	companion object {
		private val ACCEPT_JSON = accept(MediaType.APPLICATION_JSON)
	}

}
  • Java

  • Kotlin

import reactor.core.publisher.Mono;

import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;

@Component
public class MyUserHandler {

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

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

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

}
import org.springframework.stereotype.Component
import org.springframework.web.reactive.function.server.ServerRequest
import org.springframework.web.reactive.function.server.ServerResponse
import reactor.core.publisher.Mono

@Component
class MyUserHandler {

	fun getUser(request: ServerRequest?): Mono<ServerResponse> {
		...
	}

	fun getUserCustomers(request: ServerRequest?): Mono<ServerResponse> {
		...
	}

	fun deleteUser(request: ServerRequest?): Mono<ServerResponse> {
		...
	}

}

"WebFlux.fn" は Spring Framework の一部であり、詳細情報はそのリファレンスドキュメントに記載されています。

ルーターの定義をモジュール化するために、必要な数の RouterFunction (Javadoc) Bean を定義できます。優先順位を適用する必要がある場合は、Bean を順序付けできます。

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

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

Spring WebFlux 自動構成

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

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

Spring Boot および WebFlux の機能を維持し、さらに WebFlux の構成を追加する場合は、@EnableWebFlux (Javadoc) なしで、型 WebFluxConfigurer (Javadoc) の独自の @Configuration (Javadoc) クラスを追加できます。

自動構成された HttpHandler (Javadoc) にさらにカスタマイズを追加する場合は、WebHttpHandlerBuilderCustomizer (Javadoc) 型の Bean を定義し、それを使用して WebHttpHandlerBuilder (Javadoc) を変更できます。

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

Spring WebFlux 変換サービス

Spring WebFlux で使用される ConversionService (Javadoc) をカスタマイズする場合は、addFormatters メソッドを使用して WebFluxConfigurer (Javadoc) Bean を提供できます。

変換は、spring.webflux.format.* 構成プロパティを使用してカスタマイズすることもできます。構成されていない場合は、次のデフォルトが使用されます。

プロパティ DateTimeFormatter フォーマット

spring.webflux.format.date

ofLocalizedDate(FormatStyle.SHORT)

java.util.Date and LocalDate (標準 Javadoc) (英語)

spring.webflux.format.time

ofLocalizedTime(FormatStyle.SHORT)

java.time の LocalTime (標準 Javadoc) OffsetTime (標準 Javadoc)

spring.webflux.format.date-time

ofLocalizedDateTime(FormatStyle.SHORT)

java.time の LocalDateTime (標準 Javadoc) OffsetDateTime (標準 Javadoc) ZonedDateTime (標準 Javadoc)

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

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

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

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

  • Java

  • Kotlin

import org.springframework.boot.web.codec.CodecCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.codec.ServerSentEventHttpMessageReader;

@Configuration(proxyBeanMethods = false)
public class MyCodecsConfiguration {

	@Bean
	public CodecCustomizer myCodecCustomizer() {
		return (configurer) -> {
			configurer.registerDefaults(false);
			configurer.customCodecs().register(new ServerSentEventHttpMessageReader());
			// ...
		};
	}

}
import org.springframework.boot.web.codec.CodecCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.http.codec.CodecConfigurer
import org.springframework.http.codec.ServerSentEventHttpMessageReader

class MyCodecsConfiguration {

	@Bean
	fun myCodecCustomizer(): CodecCustomizer {
		return CodecCustomizer { configurer: CodecConfigurer ->
			configurer.registerDefaults(false)
			configurer.customCodecs().register(ServerSentEventHttpMessageReader())
		}
	}

}

静的コンテンツ

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

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

  • プロパティ

  • YAML

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

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

前述の「標準」の静的リソースの場所に加えて、Webjars コンテンツ (英語) には特別なケースが作成されます。デフォルトでは、パスが /webjars/** のリソースは、Webjars 形式でパッケージ化されている場合、jar ファイルから提供されます。パスは spring.webflux.webjars-path-pattern プロパティでカスタマイズできます。

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

ウェルカムページ

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

これは、アプリケーションによって定義された実際のインデックスルートのフォールバックとしてのみ機能します。順序は、HandlerMapping (Javadoc) Bean の順序によって定義され、デフォルトでは次のようになります。

org.springframework.web.reactive.function.server.support.RouterFunctionMapping

RouterFunction (Javadoc) Bean で宣言されたエンドポイント

org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping

@Controller (Javadoc) Bean で宣言されたエンドポイント

RouterFunctionMapping for the Welcome Page

The welcome page support

Template Engines

As well as REST web services, you can also use Spring WebFlux to serve dynamic HTML content. Spring WebFlux supports a variety of templating technologies, including Thymeleaf, FreeMarker, and Mustache.

Spring Boot includes auto-configuration support for the following templating engines:

Not all FreeMarker features are supported with WebFlux. For more details, check the description of each property.

When you use one of these templating engines with the default configuration, your templates are picked up automatically from src/main/resources/templates.

Error Handling

Spring Boot provides a WebExceptionHandler (Javadoc) that handles all errors in a sensible way. Its position in the processing order is immediately before the handlers provided by WebFlux, which are considered last. For machine clients, it produces a JSON response with details of the error, the HTTP status, and the exception message. For browser clients, there is a “whitelabel” error handler that renders the same data in HTML format. You can also provide your own HTML templates to display errors (see the next section).

Before customizing error handling in Spring Boot directly, you can leverage the RFC 9457 Problem Details support in Spring WebFlux. Spring WebFlux can produce custom error messages with the application/problem+json media type, like:

{
	"type": "https://example.org/problems/unknown-project",
	"title": "Unknown project",
	"status": 404,
	"detail": "No project found for id 'spring-unknown'",
	"instance": "/projects/spring-unknown"
}

This support can be enabled by setting spring.webflux.problemdetails.enabled to true.

The first step to customizing this feature often involves using the existing mechanism but replacing or augmenting the error contents. For that, you can add a bean of type ErrorAttributes (Javadoc) .

To change the error handling behavior, you can implement ErrorWebExceptionHandler (Javadoc) and register a bean definition of that type. Because an ErrorWebExceptionHandler (Javadoc) is quite low-level, Spring Boot also provides a convenient AbstractErrorWebExceptionHandler (Javadoc) to let you handle errors in a WebFlux functional way, as shown in the following example:

  • Java

  • Kotlin

import reactor.core.publisher.Mono;

import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.reactive.function.server.ServerResponse.BodyBuilder;

@Component
public class MyErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {

	public MyErrorWebExceptionHandler(ErrorAttributes errorAttributes, WebProperties webProperties,
			ApplicationContext applicationContext, ServerCodecConfigurer serverCodecConfigurer) {
		super(errorAttributes, webProperties.getResources(), applicationContext);
		setMessageReaders(serverCodecConfigurer.getReaders());
		setMessageWriters(serverCodecConfigurer.getWriters());
	}

	@Override
	protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
		return RouterFunctions.route(this::acceptsXml, this::handleErrorAsXml);
	}

	private boolean acceptsXml(ServerRequest request) {
		return request.headers().accept().contains(MediaType.APPLICATION_XML);
	}

	public Mono<ServerResponse> handleErrorAsXml(ServerRequest request) {
		BodyBuilder builder = ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR);
		// ... additional builder calls
		return builder.build();
	}

}
import org.springframework.boot.autoconfigure.web.WebProperties
import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler
import org.springframework.boot.web.reactive.error.ErrorAttributes
import org.springframework.context.ApplicationContext
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.http.codec.ServerCodecConfigurer
import org.springframework.stereotype.Component
import org.springframework.web.reactive.function.server.RouterFunction
import org.springframework.web.reactive.function.server.RouterFunctions
import org.springframework.web.reactive.function.server.ServerRequest
import org.springframework.web.reactive.function.server.ServerResponse
import reactor.core.publisher.Mono

@Component
class MyErrorWebExceptionHandler(
		errorAttributes: ErrorAttributes, webProperties: WebProperties,
		applicationContext: ApplicationContext, serverCodecConfigurer: ServerCodecConfigurer
) : AbstractErrorWebExceptionHandler(errorAttributes, webProperties.resources, applicationContext) {

	init {
		setMessageReaders(serverCodecConfigurer.readers)
		setMessageWriters(serverCodecConfigurer.writers)
	}

	override fun getRoutingFunction(errorAttributes: ErrorAttributes): RouterFunction<ServerResponse> {
		return RouterFunctions.route(this::acceptsXml, this::handleErrorAsXml)
	}

	private fun acceptsXml(request: ServerRequest): Boolean {
		return request.headers().accept().contains(MediaType.APPLICATION_XML)
	}

	fun handleErrorAsXml(request: ServerRequest): Mono<ServerResponse> {
		val builder = ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR)
		// ... additional builder calls
		return builder.build()
	}

}

For a more complete picture, you can also subclass DefaultErrorWebExceptionHandler (Javadoc) directly and override specific methods.

In some cases, errors handled at the controller level are not recorded by web observations or the metrics infrastructure. Applications can ensure that such exceptions are recorded with the observations by setting the handled exception on the observation context.

Custom Error Pages

If you want to display a custom HTML error page for a given status code, you can add views that resolve from error/*, for example by adding files to a /error directory. Error pages can either be static HTML (that is, added under any of the static resource directories) or built with templates. The name of the file should be the exact status code, a status code series mask, or error for a default if nothing else matches. Note that the path to the default error view is error/error, whereas with Spring MVC the default error view is error.

For example, to map 404 to a static HTML file, your directory structure would be as follows:

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

To map all 5xx errors by using a Mustache template, your directory structure would be as follows:

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

Web Filters

Spring WebFlux provides a WebFilter (Javadoc) interface that can be implemented to filter HTTP request-response exchanges. WebFilter (Javadoc) beans found in the application context will be automatically used to filter each exchange.

Where the order of the filters is important they can implement Ordered (Javadoc) or be annotated with @Order (Javadoc) . Spring Boot auto-configuration may configure web filters for you. When it does so, the orders shown in the following table will be used:

Web Filter Order

WebFilterChainProxy (Javadoc) (Spring Security)

-100

HttpExchangesWebFilter (Javadoc)

Ordered.LOWEST_PRECEDENCE - 10

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

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

リアクティブサーバーのカスタマイズ

一般的なリアクティブ Web サーバー設定は、Spring Environment (Javadoc) プロパティを使用して構成できます。通常、application.properties または application.yaml ファイルでプロパティを定義します。

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

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

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

  • SSL

  • HTTP 圧縮

Spring Boot は可能な限り共通設定を公開しようとしますが、常に可能であるとは限りません。このような場合には、server.netty.* などの専用の名前空間がサーバー固有のカスタマイズを提供します。

完全なリストについては、ServerProperties (Javadoc) クラスを参照してください。

プログラムによるカスタマイズ

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

  • Java

  • Kotlin

import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class MyWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableReactiveWebServerFactory> {

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

}
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory
import org.springframework.stereotype.Component

@Component
class MyWebServerFactoryCustomizer : WebServerFactoryCustomizer<ConfigurableReactiveWebServerFactory> {

	override fun customize(server: ConfigurableReactiveWebServerFactory) {
		server.setPort(9000)
	}

}

JettyReactiveWebServerFactory (Javadoc) NettyReactiveWebServerFactory (Javadoc) TomcatReactiveWebServerFactory (Javadoc) UndertowReactiveWebServerFactory (Javadoc) は、それぞれ Jetty、Reactor、Netty、Tomcat、Undertow 用の追加のカスタマイズ setter メソッドを持つ ConfigurableReactiveWebServerFactory (Javadoc) の専用バリアントです。次の例は、Reactor Netty 固有の構成オプションへのアクセスを提供する NettyReactiveWebServerFactory (Javadoc) をカスタマイズする方法を示しています。

  • Java

  • Kotlin

import java.time.Duration;

import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class MyNettyWebServerFactoryCustomizer implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {

	@Override
	public void customize(NettyReactiveWebServerFactory factory) {
		factory.addServerCustomizers((server) -> server.idleTimeout(Duration.ofSeconds(20)));
	}

}
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.stereotype.Component
import java.time.Duration

@Component
class MyNettyWebServerFactoryCustomizer : WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {

	override fun customize(factory: NettyReactiveWebServerFactory) {
		factory.addServerCustomizers({ server -> server.idleTimeout(Duration.ofSeconds(20)) })
	}

}

ConfigurableReactiveWebServerFactory を直接カスタマイズする

ReactiveWebServerFactory (Javadoc) からの拡張を必要とするより高度なユースケースでは、そのような型の Bean を自分で公開できます。

Setter は、多くの構成オプション用に提供されています。さらに特殊な操作が必要な場合に備えて、protected メソッド「フック」もいくつか提供されています。詳細については、ConfigurableReactiveWebServerFactory (Javadoc) API ドキュメントを参照してください。

自動構成されたカスタマイザーは引き続きカスタムファクトリに適用されるため、そのオプションは慎重に使用してください。

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

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

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

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

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

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

クライアント側のリソース構成の詳細については、WebClient ランタイムセクションを参照してください。