# Spring Boot 3.4:新機能を徹底解説 > Spring Boot 3.4はネイティブ構造化ロギング、拡張されたバーチャルスレッド、デフォルトのグレースフルシャットダウン、MockMvcTesterを導入。新機能の完全ガイド。 - Published: 2026-01-16 - Updated: 2026-04-10 - Author: SharpSkill - Tags: spring boot, java, spring boot 3.4, spring framework, backend - Reading time: 12 min --- Spring Boot 3.4は2024年11月にリリースされ、開発者の生産性とアプリケーションパフォーマンスにおいて大幅な改善を提供します。このバージョンではネイティブ構造化ロギングが導入され、グレースフルシャットダウンがデフォルトで有効になり、バーチャルスレッドのサポートがフレームワーク全体に拡張されています。 > **前提条件** > > Spring Boot 3.4はJava 17以上が必要で、バーチャルスレッドにはJava 21をサポートしています。このバージョンはSpring Framework 6.2を使用しています。 ## ネイティブ構造化ロギング 構造化ロギングは、アプリケーションの可観測性における重要な進歩です。解析が困難なテキストベースのログの代わりに、Spring Boot 3.4はElasticsearch、Grafana Loki、Datadogなどのツールで処理可能なJSON形式のログを生成します。 3つのフォーマットがネイティブでサポートされています:Elastic Common Schema(ECS)、Logstash、Graylog Extended Log Format(GELF)。 ```properties # application.properties # Enable structured logging in console logging.structured.format.console=ecs # Or for log files logging.structured.format.file=logstash ``` このシンプルな設定で、自動的にフォーマットされた構造化JSONログが生成されます。 ```java // LoggingController.java @RestController @RequestMapping("/api/demo") public class LoggingController { // Logger injection via SLF4J private static final Logger logger = LoggerFactory.getLogger(LoggingController.class); @GetMapping("/action") public ResponseEntity performAction(@RequestParam String userId) { // Log will be automatically formatted as structured JSON logger.info("Action performed by user: {}", userId); return ResponseEntity.ok("Action completed"); } } ``` ECSフォーマットが有効な場合、このログはタイムスタンプ、レベル、メッセージ、クラス名、スレッド、アプリケーションメタデータを含むJSONオブジェクトになります。この構造により、モニタリングプラットフォームでの検索と集計が簡素化されます。 ## グレースフルシャットダウンがデフォルトで有効に 重要な変更:グレースフルシャットダウンがデフォルトで有効になりました。処理中のHTTPリクエストはサーバーのシャットダウン前に完了するため、デプロイ時の502エラーを防止できます。 ```properties # application.properties # Graceful shutdown is now ON by default # To restore previous behavior (immediate shutdown): server.shutdown=immediate # Configure maximum wait timeout (30s default) spring.lifecycle.timeout-per-shutdown-phase=45s ``` この動作はすべての組み込みサーバーに適用されます:Tomcat、Jetty、Undertow、Reactor Netty。 ```java // LifecycleConfig.java @Configuration public class LifecycleConfig { private static final Logger logger = LoggerFactory.getLogger(LifecycleConfig.class); @Bean public ApplicationListener gracefulShutdownListener() { // This listener executes at shutdown start return event -> { logger.info("Graceful shutdown initiated - completing in-flight requests"); // Custom logic: close connections, save state, etc. }; } } ``` この改善により、ほとんどの場合、追加設定なしでゼロダウンタイムデプロイの実装が簡素化されます。 ## バーチャルスレッドサポートの拡張 Spring Boot 3.4は、バーチャルスレッドサポート(Java 21以上)をより多くのコンポーネントに拡張しています。`OtlpMeterRegistry`とUndertowサーバーが、有効化時にバーチャルスレッドを使用するようになりました。 ```properties # application.properties # Enable virtual threads globally spring.threads.virtual.enabled=true ``` この単一のプロパティにより、アプリケーションのスレッディングモデルが変換されます。各HTTPリクエストが独自のバーチャルスレッドを取得し、スレッドプールを枯渇させることなく数千の同時接続を可能にします。 ```java // AsyncService.java @Service public class AsyncService { private static final Logger logger = LoggerFactory.getLogger(AsyncService.class); // With virtual threads enabled, each blocking call // no longer consumes an OS thread public String fetchExternalData() { logger.info("Executing on thread: {}", Thread.currentThread()); // Blocking HTTP call - with virtual threads, // the OS thread is released during I/O wait return restClient.get() .uri("https://api.external.com/data") .retrieve() .body(String.class); } } ``` バーチャルスレッドは、I/O負荷の高いアプリケーションで真価を発揮します:HTTP呼び出し、データベースクエリ、ファイル操作。OSスレッドは待機時間中に解放され、再開時に再割り当てされます。 > **互換性** > > バーチャルスレッドにはJava 21以上が必要です。Java 17では、このプロパティは無視され、従来の動作が適用されます。 ## 改良されたRestClientとRestTemplate Spring Boot 3.4は、HTTPクライアントの設定を標準化しています。`HttpRequestFactory`の選択は、クラスパスに基づく明確な優先順位に従うようになりました。 ```java // HttpClientConfig.java @Configuration public class HttpClientConfig { @Bean public RestClient restClient(RestClient.Builder builder) { // Spring Boot automatically chooses implementation: // 1. Apache HTTP Components (if present) // 2. Jetty Client // 3. Reactor Netty // 4. JDK HttpClient (Java 11+) // 5. SimpleClientHttpRequestFactory (fallback) return builder .baseUrl("https://api.example.com") .defaultHeader("Accept", "application/json") .build(); } } ``` リダイレクト動作の設定も簡素化されています。 ```properties # application.properties # Force specific implementation spring.http.client.factory=jdk # Configure redirect behavior spring.http.client.redirects=dont-follow ``` より詳細な制御には、新しい`ClientHttpRequestFactoryBuilder`による完全なプログラマティック設定が可能です。 ```java // CustomHttpClientConfig.java @Configuration public class CustomHttpClientConfig { @Bean public RestClient customRestClient(ClientHttpRequestFactoryBuilder factoryBuilder) { // Advanced factory configuration ClientHttpRequestFactory factory = factoryBuilder .httpComponents() .connectTimeout(Duration.ofSeconds(5)) .readTimeout(Duration.ofSeconds(30)) .build(); return RestClient.builder() .requestFactory(factory) .baseUrl("https://api.example.com") .build(); } } ``` このアプローチは、基盤となるHTTP実装に関係なく、一貫したAPIで最大限の柔軟性を提供します。 ## 流暢なテストのためのMockMvcTester Spring Boot 3.4は、`MockMvc`のAssertJベースの代替である`MockMvcTester`を導入しています。この新しいアプローチにより、テストがより読みやすく表現力豊かになります。 ```java // UserControllerTest.java @WebMvcTest(UserController.class) class UserControllerTest { @Autowired private MockMvcTester mockMvc; // New class! @Test void shouldReturnUserById() { // Fluent API with AssertJ mockMvc.get().uri("/api/users/{id}", 1) .assertThat() .hasStatusOk() .hasContentType(MediaType.APPLICATION_JSON) .bodyJson() .extractingPath("$.name") .isEqualTo("John Doe"); } @Test void shouldReturn404ForUnknownUser() { mockMvc.get().uri("/api/users/{id}", 999) .assertThat() .hasStatus(HttpStatus.NOT_FOUND) .bodyJson() .extractingPath("$.error") .isEqualTo("User not found"); } } ``` 従来の`MockMvc`を使用したアプローチと比較して、アサーションがより簡潔になり、チェーンがより自然に感じられます。 ```java // ComparisonTest.java @WebMvcTest(UserController.class) class ComparisonTest { @Autowired private MockMvcTester mockMvcTester; @Autowired private MockMvc mockMvc; @Test void withMockMvcTester() { // New approach: fluent and concise mockMvcTester.post().uri("/api/users") .contentType(MediaType.APPLICATION_JSON) .content("{\"name\": \"Jane\"}") .assertThat() .hasStatus(HttpStatus.CREATED) .hasHeader("Location", "/api/users/2"); } @Test void withClassicMockMvc() throws Exception { // Old approach: more verbose mockMvc.perform(post("/api/users") .contentType(MediaType.APPLICATION_JSON) .content("{\"name\": \"Jane\"}")) .andExpect(status().isCreated()) .andExpect(header().string("Location", "/api/users/2")); } } ``` `MockMvcTester`は、クラスパスにAssertJが存在する場合に自動設定されます(`spring-boot-starter-test`にデフォルトで含まれています)。 ## Docker ComposeとTestcontainersの改良 Docker Composeサポートは、複数の設定ファイルとカスタム引数による柔軟性を獲得しています。 ```properties # application.properties # Use multiple Docker Compose files spring.docker.compose.file=compose.yaml,compose-dev.yaml # Pass arguments at startup spring.docker.compose.start.arguments=--scale redis=2 # Arguments at shutdown spring.docker.compose.stop.arguments=--timeout 60 ``` 新しいサービスは自動的に検出および設定されます。 ```yaml # compose.yaml services: postgres: image: postgres:16 environment: POSTGRES_DB: myapp POSTGRES_USER: user POSTGRES_PASSWORD: password ports: - "5432:5432" redis-stack: image: redis/redis-stack:latest ports: - "6379:6379" - "8001:8001" # RedisInsight UI grafana-lgtm: image: grafana/otel-lgtm:latest ports: - "3000:3000" # Grafana - "4317:4317" # OTLP gRPC ``` Spring Boot 3.4はこれらのサービスを自動検出し、対応する接続プロパティを設定します。 Testcontainersでのテストでは、新しいコンテナがサポートされています。 ```java // IntegrationTestConfig.java @TestConfiguration(proxyBeanMethods = false) public class IntegrationTestConfig { @Bean @ServiceConnection public PostgreSQLContainer postgresContainer() { return new PostgreSQLContainer<>("postgres:16"); } @Bean @ServiceConnection public RedisStackContainer redisStackContainer() { // New Redis Stack support return new RedisStackContainer("redis/redis-stack:latest"); } @Bean @ServiceConnection public LgtmStackContainer observabilityContainer() { // New Grafana LGTM support (Loki, Grafana, Tempo, Mimir) return new LgtmStackContainer("grafana/otel-lgtm:latest"); } } ``` `@ServiceConnection`アノテーションは接続プロパティを自動的に設定し、ほとんどの場合で`@DynamicPropertySource`の必要性を排除します。 ## Actuator SSLと可観測性 新しい`/actuator/info`エンドポイントは、設定済みのSSL証明書に関する情報を公開するようになりました:有効期限、発行者、サブジェクト。 ```properties # application.properties # Enable SSL information in actuator management.info.ssl.enabled=true # Configure warning threshold for expiring certificates management.health.ssl.certificate-validity-warning-threshold=30d ``` この機能により、actuatorを通じて直接証明書の有効期限を監視でき、更新の自動化が容易になります。 ```java // SslMonitoringConfig.java @Configuration public class SslMonitoringConfig { @Bean public HealthIndicator sslCertificateHealth(SslInfo sslInfo) { return () -> { // Custom certificate validity check boolean allValid = sslInfo.getBundles().values().stream() .flatMap(bundle -> bundle.getCertificates().stream()) .allMatch(cert -> cert.getValidityEnds().isAfter(Instant.now())); return allValid ? Health.up().build() : Health.down().withDetail("reason", "Certificate expiring soon").build(); }; } } ``` 可観測性については、OTLPトランスポートがHTTPに加えてgRPCをサポートするようになりました。 ```properties # application.properties # Use gRPC for OTLP (traces and metrics) management.otlp.tracing.transport=grpc management.otlp.tracing.endpoint=http://localhost:4317 # New: group applications together spring.application.group=payment-services ``` アプリケーショングループ(`spring.application.group`)により、可観測性ダッシュボードで複数のサービスを論理的にグループ化できます。 ## より軽量なOCIイメージ デフォルトのOCIイメージビルダーが`paketobuildpacks/builder-jammy-base`から`paketobuildpacks/builder-jammy-java-tiny`に変更され、大幅に小さなイメージが生成されます。 ```groovy // build.gradle tasks.named("bootBuildImage") { // Native ARM support (new) imagePlatform = "linux/arm64" // New security flag trustBuilder = false // Image configuration imageName = "myregistry.com/myapp:${version}" } ``` 新しい`imagePlatform`パラメータにより、ARMおよびx64のクロスプラットフォームビルドが簡素化されます。 ```xml org.springframework.boot spring-boot-maven-plugin linux/arm64 paketobuildpacks/builder-jammy-java-tiny ``` これらの最適化されたイメージは、起動が速く、リソース消費が少なく、特にKubernetesデプロイメントに有利です。 > **移行に関する注意** > > ビルダーの変更は、特定のシステムツールに依存するアプリケーションに影響を与える可能性があります。本番環境にデプロイする前に新しいイメージをテストすることを推奨します。 ## Bean Validationの変更 Spring Boot 3.4は、バリデーション動作をBean Validation仕様に合わせています。バリデーションはネストされたプロパティに自動的にカスケードされなくなりました。 ```java // ConfigProperties.java @ConfigurationProperties(prefix = "app") @Validated public class AppConfig { @NotBlank private String name; // IMPORTANT: @Valid required to cascade validation @Valid private DatabaseConfig database; // Without @Valid, ServerConfig constraints will NOT be checked private ServerConfig server; // Getters and setters } public class DatabaseConfig { @NotBlank private String url; @Min(1) private int poolSize; // Getters and setters } public class ServerConfig { @NotNull // This constraint will NOT be checked without @Valid on parent private Integer port; // Getters and setters } ``` この変更は既存のアプリケーションに影響を与える可能性があります。`@ConfigurationProperties`クラスを確認し、バリデーションがカスケードされるべき箇所に`@Valid`を追加する必要があります。 ## @MockBeanと@SpyBeanの非推奨化 Spring Bootの`@MockBean`と`@SpyBean`アノテーションは、新しいMockitoアノテーションに置き換えられ、非推奨となりました。 ```java // UserServiceTest.java (new approach) @SpringBootTest class UserServiceTest { // New: native Mockito annotations @MockitoBean private UserRepository userRepository; @MockitoSpyBean private EmailService emailService; @Autowired private UserService userService; @Test void shouldCreateUser() { // Mock configuration when(userRepository.save(any())).thenReturn(new User(1L, "test@example.com")); userService.createUser("test@example.com"); // Spy verification verify(emailService).sendWelcomeEmail("test@example.com"); } } ``` 旧アノテーションは引き続き動作しますが、非推奨の警告が表示されます。`@MockitoBean`と`@MockitoSpyBean`への移行を計画することを推奨します。 ## まとめ Spring Boot 3.4は、生産性と可観測性において大幅な改善を提供しています: **移行チェックリスト:** - 構造化ロギングを有効化して可観測性を向上させる - グレースフルシャットダウンの動作を確認する(デフォルトで有効化済み) - I/O負荷の高いアプリケーションにバーチャルスレッドを検討する(Java 21以上) - より読みやすいテストのためにMockMvcTesterに移行する - ネストされた`@ConfigurationProperties`プロパティに`@Valid`を追加する - `@MockBean`/`@SpyBean`を`@MockitoBean`/`@MockitoSpyBean`に置き換える - 本番デプロイ前に新しいOCIイメージをテストする Spring Boot 3.4は、可観測性基準とパフォーマンスに特に注力し、モダンJava開発のリファレンスフレームワークとしての地位を強化しています。 **参考資料:** - [Spring Boot 3.4.0 Release Announcement](https://spring.io/blog/2024/11/21/spring-boot-3-4-0-available-now/) - [Spring Boot 3.4 Release Notes](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.4-Release-Notes) - [Bootiful Spring Boot 3.4](https://spring.io/blog/2024/11/24/bootiful-34-boot/) --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/ja/blog/spring-boot/spring-boot-3-4-new-features