Spring Boot 3.4: Semua fitur baru dijelaskan lengkap
Spring Boot 3.4 menghadirkan structured logging native, virtual threads yang diperluas, graceful shutdown default, dan MockMvcTester. Panduan lengkap fitur-fitur baru.

Spring Boot 3.4, dirilis pada November 2024, menghadirkan peningkatan signifikan untuk produktivitas developer dan performa aplikasi. Versi ini memperkenalkan structured logging native, mengaktifkan graceful shutdown secara default, dan memperluas dukungan virtual threads di seluruh framework.
Spring Boot 3.4 memerlukan minimal Java 17 dan mendukung Java 21 untuk virtual threads. Versi ini menggunakan Spring Framework 6.2.
Structured logging native
Structured logging merupakan kemajuan penting untuk observabilitas aplikasi. Alih-alih log berbasis teks yang sulit dianalisis, Spring Boot 3.4 menghasilkan log dalam format JSON yang dapat dikonsumsi oleh tools seperti Elasticsearch, Grafana Loki, atau Datadog.
Tiga format didukung secara native: Elastic Common Schema (ECS), Logstash, dan 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=logstashKonfigurasi sederhana ini secara otomatis menghasilkan log JSON terstruktur yang terformat.
@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");
}
}Dengan format ECS diaktifkan, log ini menjadi objek JSON yang berisi timestamp, level, pesan, nama kelas, thread, dan metadata aplikasi. Struktur ini menyederhanakan pencarian dan agregasi di platform monitoring.
Graceful Shutdown aktif secara default
Perubahan penting: graceful shutdown kini aktif secara default. Request HTTP yang sedang berjalan diproses sebelum server dimatikan, mencegah error 502 selama deployment.
# 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=45sPerilaku ini berlaku untuk semua embedded server: Tomcat, Jetty, Undertow, dan 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.
};
}
}Peningkatan ini menyederhanakan implementasi deployment tanpa downtime, tanpa perlu konfigurasi tambahan di sebagian besar kasus.
Dukungan Virtual Threads yang diperluas
Spring Boot 3.4 memperluas dukungan virtual threads (Java 21+) ke lebih banyak komponen. OtlpMeterRegistry dan server Undertow kini menggunakan virtual threads saat diaktifkan.
# application.properties
# Enable virtual threads globally
spring.threads.virtual.enabled=trueProperty tunggal ini mengubah model threading aplikasi. Setiap request HTTP mendapat virtual thread-nya sendiri, memungkinkan ribuan koneksi bersamaan tanpa menghabiskan thread pool.
@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 unggul pada aplikasi dengan beban I/O tinggi: panggilan HTTP, query database, operasi file. Thread OS dilepaskan selama waktu tunggu dan dialokasikan ulang saat dilanjutkan.
Virtual threads memerlukan minimal Java 21. Pada Java 17, property ini diabaikan dan perilaku klasik yang berlaku.
RestClient dan RestTemplate yang ditingkatkan
Spring Boot 3.4 menormalisasi konfigurasi HTTP client. Pemilihan HttpRequestFactory kini mengikuti urutan prioritas yang jelas berdasarkan 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();
}
}Konfigurasi perilaku redirect juga disederhanakan.
# application.properties
# Force specific implementation
spring.http.client.factory=jdk
# Configure redirect behavior
spring.http.client.redirects=dont-followUntuk kontrol lebih detail, ClientHttpRequestFactoryBuilder yang baru memungkinkan konfigurasi programatik penuh.
@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();
}
}Pendekatan ini menawarkan fleksibilitas maksimal dengan API yang konsisten terlepas dari implementasi HTTP yang mendasarinya.
Siap menguasai wawancara Spring Boot Anda?
Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.
MockMvcTester untuk pengujian yang lebih lancar
Spring Boot 3.4 memperkenalkan MockMvcTester, alternatif berbasis AssertJ untuk MockMvc. Pendekatan baru ini membuat test lebih mudah dibaca dan ekspresif.
@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");
}
}Dibandingkan dengan pendekatan lama menggunakan MockMvc, assertion lebih ringkas dan chaining terasa lebih natural.
@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 dikonfigurasi secara otomatis ketika AssertJ ada di classpath (sudah termasuk secara default dengan spring-boot-starter-test).
Docker Compose dan Testcontainers yang ditingkatkan
Dukungan Docker Compose mendapat fleksibilitas lebih dengan multiple file konfigurasi dan argumen kustom.
# 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 60Service baru secara otomatis terdeteksi dan terkonfigurasi.
# 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 secara otomatis mendeteksi service-service ini dan mengkonfigurasi property koneksi yang sesuai.
Untuk pengujian dengan Testcontainers, container baru didukung.
@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");
}
}Anotasi @ServiceConnection secara otomatis mengkonfigurasi property koneksi, menghilangkan kebutuhan @DynamicPropertySource di sebagian besar kasus.
Actuator SSL dan observabilitas
Endpoint /actuator/info yang baru kini mengekspos informasi tentang sertifikat SSL yang dikonfigurasi: tanggal validitas, penerbit, dan subjek.
# 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=30dFitur ini memungkinkan pemantauan masa berlaku sertifikat langsung melalui actuator, memudahkan otomatisasi pembaruan.
@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();
};
}
}Untuk observabilitas, transport OTLP kini mendukung gRPC selain 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-servicesGrup aplikasi (spring.application.group) memungkinkan pengelompokan logis beberapa service di dashboard observabilitas.
Image OCI yang lebih ringan
Builder image OCI default berubah dari paketobuildpacks/builder-jammy-base ke paketobuildpacks/builder-jammy-java-tiny, menghasilkan image yang jauh lebih kecil.
tasks.named("bootBuildImage") {
// Native ARM support (new)
imagePlatform = "linux/arm64"
// New security flag
trustBuilder = false
// Image configuration
imageName = "myregistry.com/myapp:${version}"
}Parameter imagePlatform yang baru menyederhanakan build cross-platform untuk ARM dan 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>Image yang dioptimalkan ini lebih cepat dimulai dan mengonsumsi lebih sedikit resource, terutama menguntungkan untuk deployment di Kubernetes.
Perubahan builder dapat mempengaruhi aplikasi yang bergantung pada tool sistem tertentu. Uji image baru sebelum di-deploy ke production.
Perubahan Bean Validation
Spring Boot 3.4 menyelaraskan perilaku validasi dengan spesifikasi Bean Validation. Validasi tidak lagi otomatis menyebar ke property yang bersarang.
@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
}Perubahan ini dapat mempengaruhi aplikasi yang sudah ada. Periksa kelas @ConfigurationProperties dan tambahkan @Valid di mana validasi harus menyebar.
Deprecation @MockBean dan @SpyBean
Anotasi @MockBean dan @SpyBean dari Spring Boot sudah di-deprecate demi anotasi Mockito yang baru.
@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");
}
}Anotasi lama masih berfungsi tetapi menampilkan peringatan deprecation. Rencanakan migrasi ke @MockitoBean dan @MockitoSpyBean.
Mulai berlatih!
Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.
Kesimpulan
Spring Boot 3.4 memberikan peningkatan substansial dalam produktivitas dan observabilitas:
Checklist migrasi:
- Aktifkan structured logging untuk observabilitas yang lebih baik
- Verifikasi perilaku graceful shutdown (sekarang aktif secara default)
- Pertimbangkan virtual threads untuk aplikasi dengan beban I/O tinggi (Java 21+)
- Migrasi ke MockMvcTester untuk test yang lebih mudah dibaca
- Tambahkan
@Validpada property@ConfigurationPropertiesyang bersarang - Ganti
@MockBean/@SpyBeandengan@MockitoBean/@MockitoSpyBean - Uji image OCI baru sebelum deployment ke production
Spring Boot 3.4 memperkuat posisinya sebagai framework referensi untuk pengembangan Java modern, dengan perhatian khusus pada standar observabilitas dan performa.
Sumber:
Tag
Bagikan
Artikel terkait

Pertanyaan Wawancara Backend Node.js: Panduan Lengkap 2026
25 pertanyaan wawancara backend Node.js yang paling sering ditanyakan. Event loop, async/await, streams, clustering, dan performa dijelaskan dengan jawaban terperinci.

Go: Dasar-Dasar untuk Developer Java/Python di 2026
Pelajari Go dengan cepat menggunakan pengalaman Java atau Python. Goroutine, channel, interface, dan pola-pola penting untuk transisi yang lancar.

NestJS: Membangun REST API Lengkap dari Nol
Panduan lengkap membangun REST API profesional dengan NestJS. Controller, Service, Module, validasi dengan class-validator, dan penanganan error dijelaskan secara praktis.