Spring Boot Tutorial
What Is New in Spring Boot 4
Spring Boot 4.0 (November 2025) is the first new major version since Spring Boot 3 moved the ecosystem to Jakarta EE in 2022. It is built on Spring Framework 7 and brings a modular code base, Jackson 3, null-safety annotations across the portfolio, built-in API versioning, declarative HTTP clients, new test tooling and first-class OpenTelemetry. Spring Boot 4.1 followed with gRPC support and many refinements.
Whether you are starting a new project or maintaining a Boot 3 application, you will meet these changes in documentation, starters and error messages. This lesson summarises what changed, why, and what it means for your code — and gives a practical upgrade checklist.
Platform Baseline
The versions underneath Spring Boot 4 moved forward together:
- Java 17 minimum (Java 21 or 25 recommended for virtual threads and the latest language features).
- Spring Framework 7, Spring Security 7, Spring Data 2025.1, Spring Batch 6, Spring Cloud 2025.1 "Oakwood", Spring AI 2.0.
- Jakarta EE 11 with Servlet 6.1 — Tomcat 11 and Jetty 12.1. Undertow is no longer supported because it does not yet implement Servlet 6.1.
- Hibernate 7, Jackson 3, Micrometer 1.16, Kotlin 2.2, JUnit Jupiter 6 and Testcontainers 2.
Modular Spring Boot and Renamed Starters
The big spring-boot-autoconfigure jar was split into focused modules, one per technology. Starters now map to those modules, which means smaller applications and clearer dependencies. Some starters were renamed: spring-boot-starter-web → spring-boot-starter-webmvc, spring-boot-starter-aop → spring-boot-starter-aspectj, and the OAuth2 starters gained a security- prefix. Flyway and Liquibase now need their own starters, and every technology has a matching test starter such as spring-boot-starter-webmvc-test. The old names still work but are deprecated; spring-boot-starter-classic restores the Boot 3 layout as a temporary migration bridge.
Developer-Facing Features
Several features you will use daily arrived in this generation:
- Jackson 3 — new
tools.jacksonpackages, immutableJsonMapper, unchecked exceptions (see the Jackson lesson). - API versioning —
@GetMapping(version = "2")andspring.mvc.apiversion.*. - HTTP service clients —
@ImportHttpServicesplusspring.http.serviceclient.*for declarative interface clients. - Resilience in core Spring —
@Retryableand@ConcurrencyLimitwith@EnableResilientMethods, no extra library. - JSpecify null-safety —
@Nullable/@NonNullsemantics across Spring APIs, understood by IDEs and Kotlin. - Testing —
RestTestClient,MockMvcTester,@MockitoBean(the old@MockBeanis removed). - Observability —
spring-boot-starter-opentelemetryfor OTLP metrics and traces. - Spring Boot 4.1 — gRPC server and client support,
InetAddressFilteragainst SSRF, lazy JDBC connection fetching, Redis listener support and more.
Upgrade Checklist from Spring Boot 3
Upgrade to the latest Spring Boot 3.5.x first and fix all deprecation warnings — Boot 4 removes APIs deprecated in 3.x. Then move to 4.0 and work through: starter renames (or temporarily add the classic starters); Jackson 3 imports and customizers; @MockBean → @MockitoBean; explicit @AutoConfigureMockMvc/@AutoConfigureRestTestClient; Spring Security 7 changes (lambda DSL only, PathPatternRequestMatcher); Hibernate 7 and Undertow removal. The OpenRewrite recipe UpgradeSpringBoot_4_0 automates much of this.
Examples
A Spring Boot 4 pom.xml with the new starter names
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.1.1</version>
</parent>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc</artifactId> <!-- was spring-boot-starter-web -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-flyway</artifactId> <!-- new: needed for Flyway -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security-oauth2-resource-server</artifactId>
</dependency>
<!-- per-technology test starters -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
mvn dependency:tree | findstr autoconfigure
[INFO] +- org.springframework.boot:spring-boot-webmvc:jar:4.1.1
[INFO] +- org.springframework.boot:spring-boot-data-jpa:jar:4.1.1
[INFO] +- org.springframework.boot:spring-boot-flyway:jar:4.1.1
(focused modules instead of one large spring-boot-autoconfigure jar)
Typical code changes when upgrading from Boot 3
// 1. Tests: @MockBean is gone
- @MockBean ProductService service;
+ @MockitoBean ProductService service;
// 2. Jackson: new package for core classes (annotations unchanged)
- import com.fasterxml.jackson.databind.ObjectMapper;
+ import tools.jackson.databind.json.JsonMapper;
- @Bean Jackson2ObjectMapperBuilderCustomizer custom() { ... }
+ @Bean JsonMapperBuilderCustomizer custom() { ... }
// 3. Full-context tests must opt in to MockMvc
@SpringBootTest
+ @AutoConfigureMockMvc
class CheckoutIT { ... }
// 4. Retry without the spring-retry library
+ @EnableResilientMethods
@SpringBootApplication
public class ShopApplication { ... }
@Retryable(maxRetries = 3, delay = 200)
public Rates fetchRates() { ... }
(Run the OpenRewrite recipe to apply most of these automatically: mvn -U org.openrewrite.maven:rewrite-maven-plugin:run -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-spring:RELEASE -Drewrite.activeRecipes=org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0)
Using the classic starters as a temporary migration bridge
<!-- Restores a Boot 3-like classpath so you can upgrade in small steps.
Remove it once you have switched to the new focused starters. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-classic</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test-classic</artifactId>
<scope>test</scope>
</dependency>
Started ShopApplication in 2.4 seconds (Spring Boot 4.1.1, classic layout)
Common Mistakes
- Jumping straight from an old 2.x or early 3.x version to 4.0 instead of passing through the latest 3.5.x and fixing deprecations.
- Following Spring Boot 3 tutorials that use spring-boot-starter-web, @MockBean or WebSecurityConfigurerAdapter without adapting them.
- Keeping spring-boot-starter-classic forever instead of migrating to focused starters.
- Mixing Jackson 2 ObjectMapper and Jackson 3 JsonMapper configuration and getting inconsistent JSON.
- Assuming Undertow still works — it is not supported on Servlet 6.1 in Spring Boot 4.
Key Points to Remember
- Spring Boot 4 runs on Spring Framework 7, Jakarta EE 11 and Java 17+.
- The code base is modular; starters were renamed (webmvc, aspectj, security-oauth2-*) and test starters exist per technology.
- Key new features: Jackson 3, API versioning, HTTP service clients, core @Retryable, JSpecify, RestTestClient, OpenTelemetry starter.
- Spring Boot 4.1 adds gRPC, SSRF protection with InetAddressFilter and more.
- Upgrade via the latest 3.5.x, fix deprecations, then use OpenRewrite and the migration guide.
Practice the examples
Change an input, predict the result, then compare it with the output. Explain why the result changes.
Use your local JDK or project IDE for these examples. Codelab currently runs Python and HTML/CSS/JavaScript; framework examples may need project dependencies.