Spring Framework 7 and Spring Boot 4: Key Features for Java Developers

    Spring Framework 7 and Spring Boot 4: Key Features for Java Developers

    18/11/2025

    Introduction

    Spring Framework 7 and Spring Boot 4 introduce several new features and improvements. Let us explore some of the key features which are important for Java developers. Java 17 is still the baseline, but it’s recommended to use the latest LTS JDK (for example, Java 25) for better performance and security.


    API Versioning

    API versioning is the process of assigning unique version numbers to your API. As you introduce new features or make breaking changes, you can release a new version of your API while allowing existing clients to continue using the older version. This ensures that you don't disrupt services for your users.

    In earlier versions of Spring Boot, there was no built-in, opinionated way to handle API versioning. Developers had to implement versioning manually using Spring's flexible request mapping capabilities.

    With the introduction of Spring Framework 7, API versioning has been significantly streamlined through native support. The framework now provides an ApiVersionStrategy that centralizes the configuration and management of API versions. This eliminates the need for manual version resolution logic and reduces code duplication.

    Configuration

    You can configure API versioning by implementing WebMvcConfigurer and overriding the configureApiVersioning method:

    @Configuration public class WebConfiguration implements WebMvcConfigurer { @Override public void configureApiVersioning(ApiVersionConfigurer configurer) { configurer.useRequestHeader("API-Version"); } }

    This configuration tells Spring to extract the API version from the "API-Version" request header. You can configure other strategies as well: use configurer.useQueryParam("version") for query parameter-based versioning, configurer.usePathSegment() for path segment versioning, or configurer.useMediaTypeParameter() for media type-based versioning.

    For Spring Boot applications, you can configure this using properties in application.properties:

    spring.mvc.apiversion.use.header=API-Version

    Using the Version Attribute

    Once configured, you can specify the API version directly in your controller mappings using the new version attribute:

    @RestController public class ProductController { @GetMapping(path = "/products/{id}", version = "1") public Product getProductV1(@PathVariable String id) { return productService.getProduct(id); } @GetMapping(path = "/products/{id}", version = "2") public ProductV2 getProductV2(@PathVariable String id) { return productService.getProductV2(id); } }

    Want more details?
    See A Developer's Guide to API Versioning in Spring Boot for in-depth strategies, legacy methods, and side-by-side code examples on API versioning in Spring Boot and Framework 7.


    Resilience features

    Till now for resilience features, we had to use Spring Retry and Resilience4j. With Spring Framework 7, we have got a native support for retry and concurrency limit features. For others like circuit breaker, rate limiting, etc., we still need to use Resilience4j.

    @EnableResilientMethods @Service class PaymentService { @Retryable(maxAttempts = 4, delay = 100, multiplier = 2, maxDelay = 1000) @ConcurrencyLimit(3) public String charge(String id) { return "ok"; } }

    First we need to enable the resilience features in our application by adding the @EnableResilientMethods annotation. Then we can annotate our methods with @Retryable and @ConcurrencyLimit annotations.

    Recommended Reading

    JMS Client

    Similar to JdbcClient and RestClient, we now have JmsClient to make JMS calls as an alternative to JmsTemplate.

    public class MyJmsClient { private final JmsClient jmsClient; public MyJmsClient(JmsClient jmsClient) { this.jmsClient = jmsClient; } public void sendMessage(String message) { jmsClient.destination("queue1").send(message); } public String receiveMessage() { return jmsClient.destination("queue2").receive(); } }

    HTTP Service Client Enhancements

    Spring Framework 7 introduces the HTTP Service Registry to simplify managing multiple HTTP service clients. Instead of configuring each client individually, you can organize related services into groups and configure them collectively.

    Define your HTTP service interface:

    public interface InventoryService { @GetExchange("http://product-service/products/{id}") Product getProduct(@PathVariable String id); @PostExchange("http://product-service/products") ProductResponse createProduct(@RequestBody ProductRequest request); }

    Group and configure the service:

    @ImportHttpServices(group = "inventory", types = {InventoryService.class}) @Configuration public class InventoryClientConfig { }

    This approach centralizes configuration, reduces boilerplate, and makes it easier to manage shared settings like base URLs and authentication headers across related services.

    After this, you can inject the service into your controller:

    @RestController public class InventoryController { private final InventoryService inventoryService; public InventoryController(InventoryService inventoryService) { this.inventoryService = inventoryService; } @GetMapping("/products/{id}") public Product getProduct(@PathVariable String id) { return inventoryService.getProduct(id); } }

    Null safety through JSpecify

    Spring Framework 7 adopts JSpecify annotations to enhance null-safety by explicitly declaring the nullability of APIs, fields, and type usages. This helps prevent NullPointerException through build-time checks and makes the potential absence of values explicit in your code.

    import org.jspecify.annotations.Nullable; import org.jspecify.annotations.NonNull; public class UserService { @NonNull public String getUserName(@NonNull String userId) { // userId is guaranteed to be non-null return userRepository.findById(userId).getName(); } @Nullable public String findOptionalEmail(String userId) { // Return value may be null return userRepository.findEmailById(userId); } }

    JSpecify annotations work with tools like NullAway and are supported by IDEs such as IntelliJ IDEA and Eclipse. For Kotlin developers, these annotations are automatically translated to Kotlin's native null-safety features, ensuring seamless integration.


    Programmatic bean registration

    Traditionally, registering multiple beans or handling complex registration logic in a @Configuration class was discouraged: each @Bean method should register only one bean, and its return type should be as concrete as possible. These guidelines, while ensuring clarity, have sometimes limited flexibility—especially when advanced conditional or bulk registration is needed.

    Spring Framework 7 now includes a new programmatic bean registration feature via the BeanRegistrar contract, empowering developers to implement more sophisticated and dynamic registration logic with ease.


    RestTestClient

    Spring Framework 7 introduces RestTestClient, a testing utility for client-side REST API testing. It provides a fluent API for sending HTTP requests and verifying responses, with built-in assertions and integration with AssertJ for flexible response validation.

    import org.springframework.test.web.client.RestTestClient; @SpringBootTest class UserControllerTest { @Autowired private WebApplicationContext context; @Test void shouldGetUser() { RestTestClient client = RestTestClient.bindToApplicationContext(context).build(); client.get() .uri("/users/123") .exchange() .expectStatus().isOk() .expectBody(User.class) .value(user -> assertThat(user.getName()).isEqualTo("John")); } }

    RestTestClient simplifies testing by allowing developers to focus on request and response handling without needing an actual server, making it ideal for integration testing of REST endpoints.


    Support for Jackson 3

    Spring Framework 7 introduces support for Jackson 3, the latest major release of the JSON library.

    Jackson 3 is designed to coexist with Jackson 2, allowing for a gradual migration path. Spring Boot 4 uses Jackson 3 as the default, while Spring Framework 7 maintains compatibility with both versions.


    References

    To stay updated with the latest updates in Java and Spring follow us on linked in and medium.

    Summarise

    Transform Your Learning

    Get instant AI-powered summaries of YouTube videos and websites. Save time while enhancing your learning experience.

    Instant video summaries
    Smart insights extraction
    Channel tracking