Spring Boot 3.4: Alle nieuwe functies uitgelegd
Spring Boot 3.4 brengt native gestructureerde logging, uitgebreide virtual threads, standaard graceful shutdown en MockMvcTester. Complete gids van de nieuwe functies.

Spring Boot 3.4, uitgebracht in november 2024, levert significante verbeteringen voor ontwikkelaarsproductiviteit en applicatieprestaties. Deze versie introduceert native gestructureerde logging, schakelt graceful shutdown standaard in en breidt virtual thread-ondersteuning uit over het gehele framework.
Spring Boot 3.4 vereist minimaal Java 17 en ondersteunt Java 21 voor virtual threads. Deze versie gebruikt Spring Framework 6.2.
Native gestructureerde logging
Gestructureerde logging vormt een belangrijke vooruitgang voor applicatie-observabiliteit. In plaats van tekstgebaseerde logs die moeilijk te analyseren zijn, genereert Spring Boot 3.4 JSON-logs die door tools als Elasticsearch, Grafana Loki of Datadog verwerkt kunnen worden.
Drie formaten worden native ondersteund: Elastic Common Schema (ECS), Logstash en Graylog Extended Log Format (GELF).
# application.properties
# Enable structured logging in console
logging.structured.format.console=ecs
# Or for log files
logging.structured.format.file=logstashDeze eenvoudige configuratie produceert automatisch geformatteerde gestructureerde JSON-logs.
@RestController
@RequestMapping("/api/demo")
public class LoggingController {
// Logger injection via SLF4J
private static final Logger logger = LoggerFactory.getLogger(LoggingController.class);
@GetMapping("/action")
public ResponseEntity<String> performAction(@RequestParam String userId) {
// Log will be automatically formatted as structured JSON
logger.info("Action performed by user: {}", userId);
return ResponseEntity.ok("Action completed");
}
}Met het ECS-formaat ingeschakeld wordt deze log een JSON-object met timestamp, level, bericht, klassenaam, thread en applicatiemetadata. Deze structuur vereenvoudigt het zoeken en aggregeren in monitoringplatforms.
Graceful Shutdown standaard ingeschakeld
Belangrijke wijziging: graceful shutdown is nu standaard ingeschakeld. Lopende HTTP-verzoeken worden afgerond voordat de server afsluit, waardoor 502-fouten tijdens deployments worden voorkomen.
# 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=45sDit gedrag geldt voor alle embedded servers: Tomcat, Jetty, Undertow en Reactor Netty.
@Configuration
public class LifecycleConfig {
private static final Logger logger = LoggerFactory.getLogger(LifecycleConfig.class);
@Bean
public ApplicationListener<ContextClosedEvent> 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.
};
}
}Deze verbetering maakt zero-downtime deployments eenvoudiger te implementeren zonder extra configuratie in de meeste gevallen.
Uitgebreide Virtual Thread-ondersteuning
Spring Boot 3.4 breidt de virtual thread-ondersteuning (Java 21+) uit naar meer componenten. OtlpMeterRegistry en de Undertow-server gebruiken nu virtual threads wanneer deze zijn ingeschakeld.
# application.properties
# Enable virtual threads globally
spring.threads.virtual.enabled=trueDeze enkele property transformeert het threading-model van de applicatie. Elk HTTP-verzoek krijgt zijn eigen virtual thread, waardoor duizenden gelijktijdige verbindingen mogelijk zijn zonder de thread pool uit te putten.
@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);
}
}Virtual threads blinken uit bij I/O-intensieve applicaties: HTTP-aanroepen, database-queries, bestandsoperaties. De OS-thread wordt vrijgegeven tijdens wachttijd en opnieuw toegewezen bij hervatting.
Virtual threads vereisen minimaal Java 21. Op Java 17 wordt deze property genegeerd en geldt het klassieke gedrag.
Verbeterde RestClient en RestTemplate
Spring Boot 3.4 normaliseert de HTTP-clientconfiguratie. De selectie van HttpRequestFactory volgt nu een duidelijke rangorde op basis van het classpath.
@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();
}
}Ook de configuratie van redirect-gedrag is vereenvoudigd.
# application.properties
# Force specific implementation
spring.http.client.factory=jdk
# Configure redirect behavior
spring.http.client.redirects=dont-followVoor meer gedetailleerde controle maakt de nieuwe ClientHttpRequestFactoryBuilder volledige programmatische configuratie mogelijk.
@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();
}
}Deze aanpak biedt maximale flexibiliteit met een consistente API ongeacht de onderliggende HTTP-implementatie.
Klaar om je Spring Boot gesprekken te halen?
Oefen met onze interactieve simulatoren, flashcards en technische tests.
MockMvcTester voor vloeiend testen
Spring Boot 3.4 introduceert MockMvcTester, een op AssertJ gebaseerd alternatief voor MockMvc. Deze nieuwe aanpak maakt tests leesbaarder en expressiever.
@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");
}
}Vergeleken met de oude aanpak met MockMvc zijn de assertions beknopter en voelt het ketenen natuurlijker aan.
@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 wordt automatisch geconfigureerd wanneer AssertJ aanwezig is op het classpath (standaard meegeleverd met spring-boot-starter-test).
Verbeterde Docker Compose en Testcontainers
Docker Compose-ondersteuning krijgt meer flexibiliteit met meerdere configuratiebestanden en aangepaste argumenten.
# 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 60Nieuwe services worden automatisch gedetecteerd en geconfigureerd.
# 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 gRPCSpring Boot 3.4 detecteert deze services automatisch en configureert de bijbehorende verbindingseigenschappen.
Voor testen met Testcontainers worden nieuwe containers ondersteund.
@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");
}
}De @ServiceConnection-annotatie configureert verbindingseigenschappen automatisch, waardoor @DynamicPropertySource in de meeste gevallen overbodig wordt.
Actuator SSL en observabiliteit
Het nieuwe /actuator/info-endpoint toont nu informatie over geconfigureerde SSL-certificaten: geldigheidsdatums, uitgever en onderwerp.
# 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=30dDeze functionaliteit maakt het mogelijk om certificaatvervaldatums direct via actuator te monitoren, wat de automatisering van vernieuwingen vergemakkelijkt.
@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();
};
}
}Voor observabiliteit ondersteunt OTLP-transport nu gRPC naast HTTP.
# 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-servicesDe applicatiegroep (spring.application.group) maakt logische groepering van meerdere services mogelijk in observability-dashboards.
Lichtere OCI-images
De standaard OCI-image builder verandert van paketobuildpacks/builder-jammy-base naar paketobuildpacks/builder-jammy-java-tiny, wat aanzienlijk kleinere images oplevert.
tasks.named("bootBuildImage") {
// Native ARM support (new)
imagePlatform = "linux/arm64"
// New security flag
trustBuilder = false
// Image configuration
imageName = "myregistry.com/myapp:${version}"
}De nieuwe imagePlatform-parameter vereenvoudigt cross-platform builds voor ARM en x64.
<!-- pom.xml -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<!-- Native ARM support -->
<platform>linux/arm64</platform>
<!-- Builder optimized for minimal images -->
<builder>paketobuildpacks/builder-jammy-java-tiny</builder>
</image>
</configuration>
</plugin>Deze geoptimaliseerde images starten sneller en verbruiken minder resources, bijzonder voordelig voor Kubernetes-deployments.
De builder-wijziging kan applicaties beïnvloeden die afhankelijk zijn van bepaalde systeemtools. Test nieuwe images voordat ze naar productie worden uitgerold.
Wijzigingen in Bean Validation
Spring Boot 3.4 brengt het validatiegedrag in lijn met de Bean Validation-specificatie. Validatie cascadeert niet langer automatisch naar geneste properties.
@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
}Deze wijziging kan bestaande applicaties beïnvloeden. Controleer @ConfigurationProperties-klassen en voeg @Valid toe waar validatie moet cascaderen.
Deprecatie van @MockBean en @SpyBean
De Spring Boot-annotaties @MockBean en @SpyBean zijn deprecated ten gunste van nieuwe Mockito-annotaties.
@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");
}
}De oude annotaties werken nog maar tonen deprecatiewaarschuwingen. Plan de migratie naar @MockitoBean en @MockitoSpyBean.
Begin met oefenen!
Test je kennis met onze gespreksimulatoren en technische tests.
Conclusie
Spring Boot 3.4 levert substantiële verbeteringen voor productiviteit en observabiliteit:
Migratiechecklist:
- Gestructureerde logging inschakelen voor betere observabiliteit
- Graceful shutdown-gedrag verifiëren (nu standaard ingeschakeld)
- Virtual threads overwegen voor I/O-intensieve applicaties (Java 21+)
- Migreren naar MockMvcTester voor leesbaarder tests
@Validtoevoegen op geneste@ConfigurationProperties-properties@MockBean/@SpyBeanvervangen door@MockitoBean/@MockitoSpyBean- Nieuwe OCI-images testen voor productie-deployment
Spring Boot 3.4 verstevigt zijn positie als referentieframework voor moderne Java-ontwikkeling, met bijzondere aandacht voor observability-standaarden en performance.
Bronnen:
Tags
Delen
Gerelateerde artikelen

Node.js Backend Sollicitatievragen: Volledige Gids 2026
De 25 meest gestelde Node.js backend sollicitatievragen. Event loop, async/await, streams, clustering en performance uitgelegd met gedetailleerde antwoorden.

Go: Basiskennis voor Java/Python-ontwikkelaars in 2026
Leer Go snel door je Java- of Python-ervaring te benutten. Goroutines, channels, interfaces en essentiële patronen voor een vlotte overstap.

NestJS: Een complete REST API vanaf nul bouwen
Stap-voor-stap handleiding voor het bouwen van een productieklare REST API met NestJS, TypeScript, Prisma en class-validator. CRUD, validatie, foutafhandeling en interceptors.