Skip to content

Spring Framework 7.0 Release Notes

Rossen Stoyanchev edited this page Jul 7, 2025 · 38 revisions

This is a preview of the Spring Framework 7.0 release, scheduled for November 2025.

Upgrading From Spring Framework 6.2

Baseline upgrades

Spring Framework 7.0 does not change the JDK baseline, expecting a JDK 17-27 compatibility range.

This new generation raises its minimum requirements with the following libraries:

Removed APIs

Spring JCL has been retired

The spring-jcl module has been removed in favor of Apache Commons Logging 1.3.0. This change should be transparent for most applications, as spring-jcl was a transitive dependency and the logging API calls should not change. See #32459 for more details.

Removed support for javax.annotation and javax.inject annotations

Annotations in the javax.annotation and javax.inject packages are no longer supported. This includes annotations such as @javax.annotation.Resource,@javax.annotation.PostConstruct, @javax.inject.Inject, etc. If your application still uses annotations from those packages, you will need to migrate to their equivalents in the jakarta.annotation and jakarta.inject packages.

Path mapping options

Several path mapping options have been marked for removal since 6.0. They are now removed completely. This includes:

  • suffixPatternMatch/registeredSuffixPatternMatch for annotated controller methods
  • trailingSlashMatch for extensions of AbstractHandlerMapping
  • favorPathExtension/ignoreUnknownPathExtensions and underlying PathExtensionContentNegotiationStrategy and ServletPathExtensionContentNegotiationStrategy for content negotiation, configurable through ContentNegotiationManagerFactoryBean and in the MVC Java config
  • matchOptionalTrailingSeparator in PathPatternParser

Other removals

Many other APIs and features were removed as part of #33809, including:

  • ListenableFuture in favor of CompletableFuture
  • OkHttp3 support
  • WebJars support with org.webjars:webjars-locator-core in favor of org.webjars:webjars-locator-lite

Deprecations

  • The <mvc:* XML configuration namespace for Spring MVC is now deprecated in favor of the Java configuration variant. There are no plans yet for removing it completely, but XML configuration will not be updated to follow the Java configuration model. Other namespaces (like <bean>) are NOT deprecated.
  • The Kotlin team has shared their intention to remove JSR 223 support in a future Kotlin 2.x release. As a result, the templating support for Kotlin scripts in Spring has been deprecated.
  • JUnit 4 support in the Spring TestContext Framework is now deprecated in favor of the SpringExtension for JUnit Jupiter. Deprecated classes include the SpringRunner, SpringClassRule, SpringMethodRule, AbstractJUnit4SpringContextTests, AbstractTransactionalJUnit4SpringContextTests, and related support classes.
  • Jackson 2.x support has been deprecated in favor of Jackson 3.x, see #33798
  • The use of PathMatcher is Spring MVC is now deprecated, see #34018.
  • The HandlerMappingIntrospector SPI (for alignment of Spring Security Spring MVC path matching( is deprecated, see #34019 and spring-security/16886.

Null Safety

Spring nullness annotations with JSR 305 semantics are deprecated in favor of JSpecify annotations. The Spring Framework codebase has been migrated to Specify and now specifies the nullness of array/vararg elements and generic types. You can find more details on how to migrate in this dedicated section of the reference documentation.

HttpHeaders changes

The HttpHeaders API has been revisited in 7.0; this class does not extend the MultiValueMap contract anymore. Underlying servers treat headers more like a collection of pairs, and many map-like operations do not behave or perform well, because headers are case-insensitive in the first place. We removed several methods as a result and introduced fallbacks as immediately @Deprecated, like HttpHeaders#asMultiValueMap. Please consider other methods as much as possible. See gh-33913 for more details.

Servlet 6.1 and WebSocket 2.2 baselines

Spring Framework 7.0 adopted Jakarta Servlet 6.1 and WebSocket 2.2 as new baselines for web applications. In practice, this means that applications should be deployed on recent Servlet containers like Tomcat 11+ and Jetty 12.1+.

We also took this opportunity to update our HTTP mock support with MockHttpServletRequest/MockHttpServletResponse, better aligning with the behavior described in the Servlet API. This is especially relevant when using null names and values in HTTP headers.

Jackson 3.x support

As of #33798, we default to supporting Jackson 3.x in our entire stack, falling back to Jackson 2.x. Support for the Jackson 2.x generation has been deprecated in Spring Framework, and our current plan is to disable its auto-detection in 7.1, and remove its support entirely in 7.2.

Jackson 3.x uses a new tools.jackson package, which differs from the usual com.fasterxml.jackson. Classes from the "jackson-annotation" artifact (like @JsonView, @JsonTypeInfo) remain in the com.fasterxml.jackson package for easier upgrade.

There is no Jackson 3.x equivalent for Jackson2ObjectMapperBuilder, we now recommend using Jackson's JsonMapper.builder(), CBORMapper.builder() and others as replacements.

More details on the changes between Jackson 2 and 3:

kotlinx.serialization JSON support

The org.jetbrains.kotlinx:kotlinx-serialization-json dependency is quite popular in the Kotlin ecosystem and is often transitive dependency. This caused issues where applications were using this library for reading/writing JSON instead of Jackson; there is no easy workaround. As of this Spring Framework 7.0, the Kotlinx Serialization JSON codecs and converters will only be auto-detected and configured if the library is on the classpath and Jackson is not present.

GraalVM Native applications

Spring Framework 7.0 switches to the unified reachability metadata format, being adopted by the GraalVM community. Applications contributing RuntimeHints should apply the following changes:

The resource hints syntax has changed from a java.util.regex.Pattern format to a "glob pattern" format. In practice, applications might need to change their resource hints registrations if they were using wildcards. Previously, "/files/*.ext" matched both "/files/a.ext" and "/files/folder/b.txt". The new behavior matches only the former. To match both, you will need to use "/files/**/*.ext" instead. Registration of "excludes" has been removed completely.

Registering a reflection hint for a type now implies methods, constructors and fields introspection. As a result, ExecutableMode.INTROSPECT, and all MemberCategory values except MemberCategory.INVOKE_* have been deprecated. They have no replacement, as registering a type hint is enough.

In practice, it is enough to replace this:

hints.reflection().registerType(MyType.class, MemberCategory.DECLARED_FIELDS);

With this:

hints.reflection().registerType(MyType.class);

As for MemberCategory.PUBLIC_FIELDS and MemberCategory.DECLARED_FIELDS, those constants were replaced by INVOKE_PUBLIC_FIELDS and INVOKE_DECLARED_FIELDS to make their original intent clearer and to align with the rest of the API. Note, if you were using those values for reflection only, you can safely remove those hints in favor of a simple type hint.

More details on the related changes in #33847.

CORS Pre-flight requests behavior change

As of #31839, CORS Pre-Flight requests are not rejected anymore when the CORS configuration is empty.

WebClient behavior changes for Reactor client

As of #34850, the Reactor client (when used with WebClient) will automatically opt-in for the system properties for proxy configuration, https.proxyHost and https.proxyPort.

New and Noteworthy

Null Safety

The Spring Framework codebase is annotated with JSpecify annotations to declare the nullness of APIs, fields, and related type usage. JSpecify provides significant enhancements compared to the previous JSR 305 based arrangement, such as properly defined specifications, a canonical dependency with no split-package issue, better tooling, better Kotlin integration, and the capability to specify nullness for generic types, arrays, and vararg elements. Using JSpecify annotations is also recommended for Spring-based applications. For more on this, check out the revisited "Null Safety" section of our reference documentation.

Class-File API usage for Java 24+ apps

Spring Framework reads class bytecode to collect metadata about the application code. Historically we have used a reduced ASM fork for this purpose, through the MetadataReaderFactory and MetadataReader types in the org.springframework.core.type.classreading package. Although Spring applications typically have no direct exposure to this API, this is especially useful when parsing @Configuration classes or looking for annotations on application code.

Java 24 introduced a new Class-File API with JEP 484 for reading and writing classes as Java bytecode. Spring Framework 7.0 adopts this feature for Java 24+ applications with a new ClassFileMetadataReader implementation in spring-core. This should be completely transparent for applications.

Retry support in the spring-core module

The Spring team has been working on the Spring Retry project for a very long time. We have decided that it was time to trim unnecessary features, revisit some of its API and merge the resulting work into the "spring-core" module of Spring Framework. This new Retry support is located in the org.springframework.core.retry package, we will update the reference documentation soon.

API versioning

Spring MVC and WebFlux now provide first class support for API versioning. On the server side, you can map requests to controller methods and route requests to functional endpoints by taking into account the API version of the request. You can configure how the API version is resolved, parsed, and validated, mark versions as deprecated in order to notify clients, and more. On the client side, there is support for setting the API version on requests in RestClient, WebClient, and also with HTTP interface clients. On the testing side, there is support in WebTestClient as well as in MockMvc.

For more details see the reference docs for Spring MVC and WebFlux.

HTTP Interface Client Config

There is now dedicated support for HTTP interface client configuration that can significantly simplify the required configuration especially when you work with many HTTP interfaces and target hosts. This is done through @ImportHttpServices declarations that let applications focus on identifying HTTP Services by group, and customizing the client for each group, while the framework transparently creates a registry of client proxies, and declares each proxy as a bean. For example:

@Configuration(proxyBeanMethods = false)
@ImportHttpServices(group = "weather", types = {FreeWeather.class, CommercialWeather.class})
@ImportHttpServices(group = "user", types = {UserServiceInternal.class, UserServiceOfficial.class})
static class HttpServicesConfiguration extends AbstractHttpServiceRegistrar {

	@Bean
	public RestClientHttpServiceGroupConfigurer groupConfigurer() {
		return groups -> groups.filterByName("weather", "user")
				.configureClient((group, builder) -> builder.defaultHeader("User-Agent", "My-Application"));
	}

}

For more details, see the reference documentation.

HTTP Interface Client support for InputStream and OutputStream

It is now possible to provide an OutputStream for the request body through an StreamingHttpOutputMessage.Body method parameter, and also to consume the response through an InputStream or ResponseEntity<InputStream> return value.

Programmatic Bean Registration

Applications should never attempt to register several beans within a single @Bean method in a @Configuration class. Similarly, @Bean methods should declare the most concrete type as their return type. Those requirements often get in the way of more flexible bean registrations when more logic is required, or when multiple registration is needed.

This major version introduces a new programmatic bean registration mechanism with the BeanRegistrar contract that will help with such use cases. See the new "Programmatic Bean Registration" section in the reference documentation.

Optional support with null-safe and Elvis operators in SpEL expressions

The java.util.Optional type is now better supported in SpEL expressions. Not only can you now call null-safe operations on Optional types with transparent unwrapping, but you can also use the Elvis operator to automatically unwrap an Optional.

Clone this wiki locally