-
Notifications
You must be signed in to change notification settings - Fork 40.8k
Spring Boot 3.4 Release Notes
Support for auto-configuring RestClient
and RestTemplate
to use Reactor Netty’s HttpClient
or the JDK’s HttpClient
has been added.
In order of precedence, the supported clients are now:
-
Apache HTTP Components (
HttpComponentsClientHttpRequestFactory
) -
Jetty Client (
JettyClientHttpRequestFactory
) -
Reactor Netty
HttpClient
(ReactorClientHttpRequestFactory
) -
JDK
HttpClient
(JdkClientHttpRequestFactory
) -
Simple JDK
HttpURLConnection
(SimpleClientHttpRequestFactory
)
Notably, if you don’t have an HTTP client library on the classpath, this will likely result in the use of JdkClientHttpRequestFactory
where SimpleClientHttpRequestFactory
would have been used previously.
A particular client can be selected by setting spring.http.client.factory
.
Supported values are http-components
, jetty
, reactor
, jdk
, and simple
.
All five clients will follow redirects by default.
To disable this behavior, set spring.http.client.redirects
to dont-follow
.
Apache HTTP Components have changed defaults in the HttpClient
relating to HTTP/1.1 TLS upgrades.
Most proxy servers handle upgrades without issue, however, you may encounter issues with Envoy or Istio.
If you need to restore previous behaviour, you can use the new ClientHttpRequestFactoryBuilder
.
Define a HttpComponentsClientHttpRequestFactoryBuilder
and apply the following customization:
@Bean
public HttpComponentsClientHttpRequestFactoryBuilder httpComponentsClientHttpRequestFactoryBuilder() {
return ClientHttpRequestFactoryBuilder.httpComponents()
.withDefaultRequestConfigCustomizer((builder) -> builder.setProtocolUpgradeEnabled(false));
Previously, when a @ConfigurationProperties
class annotated with @Validated
was being validated using a Bean Validation implementation such as Hibernate Validator, validation of nested properties would be performed as they were bound, irrespective of the use of @Valid
.
In Spring Boot 3.4, validation now follows the behavior of the Bean Validation specification.
Validation is performed from the @ConfigurationProperties
-annoated class and only cascades down to nested properties where the corresponding field is annotated with @Valid
.
When upgrading, inspect your @ConfigurationProperties
classes with Bean Validation constraints.
Add @Valid
as necessary where you want the validation to cascade down to nested properties.
The behavior of @ConditionalOnBean
and @ConditionalOnMissingBean
has changed when used on a @Bean
method and the annotation
attribute is set.
As before, both conditions will use the return type of the @Bean
method as a default for the type to match.
Previously, this default was not used if name
, type
, or value
had been set.
As of Spring Boot 3.4, this default will also not be used if annotation
has been set.
To restore the previous behavior, specify both a value
that is the return type of the @Bean
method and annotation
.
Graceful shutdown of the embedded web server (Jetty, Rector Netty, Tomcat, or Undertow) is now enabled by default.
If you need to restore the previous behavior, set server.shutdown
to immediate
.
The default Cloud Native Buildpacks builder used when building OCI images for JVM applications using the Maven spring-boot:build-image
goal or Gradle bootBuildImage
task has changed from paketobuildpacks/builder-jammy-base
to paketobuildpacks/builder-jammy-java-tiny
.
This should result in smaller images.
The tiny
builder does not include a shell, so it might not work for applications that require a start script to run the application.
See the Maven or Gradle documentation for information on customizing the builder.
Support for defining dynamic properties by injecting a DynamicPropertyRegistry
into a @Bean
method has been deprecated and attempting to do so will now fail by default.
Instead of injecting DynamicPropertyRegistry
in a @Bean
method, implement a separate @Bean
method that returns a DynamicPropertyRegistrar
.
This separate bean method should inject the container from which the properties' values will be sourced.
This addresses some container lifecycle issues and ensures that the container from which a property’s value has been sourced will have been started before the property is used.
If you wish to continue injecting DynamicPropertyRegistry
(at the risk of encountering the lifecycle issue described above), set spring.testcontainers.dynamic-property-registry-injection
to either warn
or allow
.
The former will log a warning while allowing the use of an injected DynamicPropertyRegistry
.
The latter will silently allow the use of an injected DynamicPropertyRegistry
, fully restoring Spring Boot 3.3’s behavior.
The @AutoConfigureTestDatabase
annotation now attempts to detect if a database has been sourced from a container.
This should remove the need to add replace=Replace.NONE
if you want to use the annotation with container databases.
If you need to revert to the old behavior, set replace=Replace.AUTO_CONFIGURED
on the annotation.
Support for enabling and disabling endpoints has been reworked, replacing the on/off support that it provided with a finer-grained access model.
The new model supports only allowing read-only
access to endpoint operations, in addition to disabling an endpoint (access of none
) and fully enabling it (access of unrestricted
).
The following properties have been deprecated:
-
management.endpoints.enabled-by-default
-
management.endpoint.<id>.enabled
Their replacements are:
-
management.endpoints.access.default
-
management.endpoint.<id>.access
Similarly, the enableByDefault
attribute on @Endpoint
has been deprecated with a new defaultAccess
attribute replacing it.
As part of these changes, enabled-by-default
is now applied consistently and irrespective of the use of @ConditionalOnEnabledEndpoint
.
If you lose access to an endpoint when upgrading, set management.endpoint.<id>.access
to read-only
or unrestricted
or set management.endpoint.<id>.enabled
to true
to make the endpoint accessible again.
Additionally, a new property has been introduced that allows an operator to control the permitted level of access to Actuator endpoints:
-
management.endpoints.access.max-permitted
This property caps any access that may have been configured for an endpoint.
For example, if management.endpoints.access.max-permitted
is set to read-only
and management.endpoint.loggers.access
is set to unrestricted
, only read-only access to the loggers endpoint will be allowed.
The EndpointExposure.CLOUD_FOUNDRY
enum value used with the @ConditionalOnAvailableEndpoint
has been deprecated in favor of EndpointExposure.WEB
.
Typical Spring Boot application will probably not be affected by this change, however, if you have custom Cloud Foundry specific actuator endpoint beans you should update your conditions to use EndpointExposure.WEB
.
HtmlUnit has been upgraded to 4.3.
With this upgrade comes a change in dependency coordinates from net.sourceforge.htmlunit:htmlunit
to org.htmlunit:htmlunit
and a change in package names from com.gargoylesoftware.htmlunit.
to org.htmlunit.
.
When upgrading, update your build configuration and imports accordingly.
Selenium HtmlUnit has been updated to 4.22.
With this upgrade comes a change in dependency coordinates from org.seleniumhq.selenium:htmlunit-driver
to org.seleniumhq.selenium:htmlunit3-driver
.
When upgrading, update your build configuration accordingly.
For faster startup times and efficient WebJars asset resolution, you will need to update your pom.xml/build.gradle to depend on org.webjars:webjars-locator-lite
instead of org.webjars:webjars-locator-core
(both dependencies are managed by Spring Boot).
Note that org.webjars:webjars-locator-core
support in Spring is now deprecated and will be removed in a future version. See the reference documentation section on this feature.
Spring Boot no longer depends on OkHttp so it no longer manages its version. If your application has OkHttp dependencies, update its build to use an OkHttp version that meets its needs.
Note
|
This is not needed when upgrading directly to Spring Boot 3.4.1 or later. |
Spring Boot 3.4.0 uses a version of Netty which isn’t supported yet by the GraalVM reachability metadata included in the Native Build Tools. To get Netty working in a native image, you’ll need to upgrade the GraalVM reachability metadata version manually.
For Maven:
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<configuration>
<metadataRepository>
<version>0.3.14</version>
</metadataRepository>
</configuration>
</plugin>
For Gradle:
graalvmNative {
metadataRepository {
version = '0.3.14'
}
}
@MockBean
and @SpyBean
have been deprecated in favor of @MockitoBean
and @MockitoSpyBean
in Spring Framework.
The functionality provided by the Spring Framework annotations is not exactly the same as that offered by Spring Boot.
For example, @MockitoBean
is not supported on @Configuration
classes and you may need to migrate to annotating fields on a test class instead.
Classes, methods, and properties that were deprecated in Spring Boot 3.2 and marked for removal in 3.4 have been removed in this release. Please ensure that you aren’t calling deprecated methods before upgrading.
Tip
|
Check the configuration changelog for a complete overview of the changes in configuration. |
Support for structured logging has been introduced with built-in support for Elastic Common Schema (ecs
), Graylog Extended Log Format (gelf
) and Logstash (logstash
).
To enable structured file logging set logging.structured.format.file
to ecs
, gelf
or logstash
.
Similarly, to enable structured console logging set logging.structured.format.console
.
To learn more about Spring Boot’s support for structured logging, including how to define a custom format, see the reference documentation.
@ConditionalOnSingleCandidate
now supports @Fallback
beans.
The condition will match if there’s a single primary bean or, if there are no primary beans, if there’s a single non-fallback bean.
When type matching, bean-based conditions will now ignore any beans that are not default candidates.
By declaring that a bean is not a default candidate (using @Bean(defaultCandidate=false)
), a bean of an auto-configured type can now be defined without causing the auto-configure bean of the same type to back off.
This reduces the configuration required to, for example, use two DataSource
beans or two EntityManagerFactory
beans in the same application.
A new ClientHttpRequestFactoryBuilder
interface has been added which allows you to build ClientHttpRequestFactory
instances for specific technologies.
Builders allow for fine-grained customization of the underlying components, as well as a consistent way to apply common settings.
The following builders can be created for specific libraries using static factory methods from the interface:
-
Apache HTTP Components (
ClientHttpRequestFactoryBuilder.httpComponents()
) -
Jetty Client (
ClientHttpRequestFactoryBuilder.jetty()
) -
Reactor Netty
HttpClient
(ClientHttpRequestFactoryBuilder.reactor()
) -
JDK
HttpClient
(ClientHttpRequestFactoryBuilder.jdk()
) -
Simple JDK
HttpURLConnection
(ClientHttpRequestFactoryBuilder.simple()
)
See the updated reference docs for more details, including how to apply common settings using configuration properties.
The new spring.application.group
property can be used to group applications together, for example if they all belong to some business unit or one bigger application arrangement.
When this property is set, it’s also included in the log messages.
This behavior can be controlled with the property logging.include-application.group
.
The application group is also automatically added to the OpenTelemetry Resource
.
It’s now possible to send OTLP spans over the gRPC transport.
For this, set the new configuration property management.otlp.tracing.transport
to grpc
.
This property defaults to http
.
Service connection support for this has been added, too.
The new properties under management.otlp.logs
can be used to auto-configure OpenTelemetry’s OtlpHttpLogRecordExporter
and SdkLoggerProvider
.
The ProcessInfoContributor
now also shows memory info about heap and non-heap usage.
New management.otlp.tracing.export.enabled
, management.wavefront.tracing.export.enabled
and management.zipkin.tracing.export.enabled
properties can now be used to enable or disable trace exporting more finely grained.
Auto-configuration for MockMvcTester
is provided when AssertJ is on the classpath.
MockMvcTester
lets you define the requests and the assertions using a fluent API.
It can be injected anywhere MockMvc
is.
For more details, see the dedicated section of the Spring Framework reference documentation.
Configuration properties are now provided for configuring a default tenant and namespace.
The defaults apply when consuming or producing messages with a topic URL that is not fully qualified.
Configure them using the spring.pulsar.defaults.topic.tenant
and spring.pulsar.defaults.topic.namespace
configuration properties or define your own PulsarTopicBuilder
bean.
Set spring.pulsar.defaults.topic.enabled=false
to disable the defaults.
A new PulsarContainerFactoryCustomizer
interface has been added to support customization of the auto-configured PulsarContainerFactory
.
The spring.pulsar.consumer.subscription.name
configuration property now applies to the auto-configured Pulsar listener container.
Two new configuration properties for configuring the Pulsar client’s concurrency have been introduced:
-
spring.pulsar.client.threads.io
controls the number of threads to be used for handling connections to brokers. -
spring.pulsar.client.threads.listener
controls the number of threads to be used for message listeners.
Lastly, the new spring.pulsar.listener.concurrency
property can be used to control the concurrency of the auto-configured Pulsar message listener container.
Client certificates can now be used to authenticate with a Couchbase cluster, as an alternative to basic username and password authentication. See the reference documentation for more details.
FreeMarker variables that are used by the auto-configured FreeMarker’s Configuration
object can now be customized.
To do so, define one or more beans of type FreeMarkerVariablesCustomizer
.
These are invoked according to their defined order (if any).
Now that ActiveMQ Classic supports an embedded broker again, the auto-configuration has been updated to support it.
Note that contrary to Spring Boot 2.7.x, the ActiveMQ starter is client only. To use the embedded broker, org.apache.activemq:activemq-broker
should be added to your application.
The default value of an Enum
is now detected by the annotation processor.
If you have added manual metadata to provide the value for a custom property, make sure to remove it.
To make it easier to evolve auto-configuration, support for deprecating and replacing auto-configuration classes has been introduced.
Replacements can be declared in a new META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.replacements
file.
To learn more, please refer to the reference documentation.
Any property resolved to a Resource
can now make use of the Base64ProtocolResolver
without needing to explicitly register it.
For example, you can now use it to specify the certificate location of a SAML2 relying party signing credential:
spring:
security:
saml2:
relyingparty:
registration:
keycloak:
entity-id: "saml-test"
signing:
credentials:
- private-key-location: classpath:local.key
certificate-location: base64:LS...
You can also easily add your own protocol resolvers by adding them to a META-INF/spring.factories
file under the org.springframework.core.io.ProtocolResolver
key.
If virtual threads are enabled, the following components will now use them:
-
OtlpMeterRegistry
-
Undertow web server
Spring Boot now uses the paketobuildpacks/builder-jammy-java-tiny
by default.
This builder supports ARM and x64 platforms out of the box.
A trustBuilder
option has been added to the Maven and Gradle plugins for building OCI images.
This option controls how the CNB lifecycle is invoked, providing improved security when using builders from untrusted sources.
By default, builders from the Paketo project, Heroku, and Google are trusted.
See the Maven or Gradle documentation for information.
An imagePlatform
option has been added to the Maven and Gradle plugins for building OCI images.
This option can be used to specify the operating system and architecture of any CNB builder, run, and buildpack images that are pulled in order to run CNB buildpacks.
This can be used to build an image for an operating system and architecture that is different from the OS/architecture of the host platform, when the host platform supports emulation of the other OS/architecture (for example, when using Rosetta on a Mac with Apple silicon to emulate the AMD archicture on an ARM host).
See the Maven or Gradle documentation for more information.
Docker Compose now supports multiple Docker Compose configuration files.
The new properties spring.docker.compose.start.arguments
and spring.docker.compose.stop.arguments
can be used to specify additional command line arguments that are passed to the Docker Compose subcommands when starting and stopping services. A new spring.docker.compose.arguments
property has been added to pass arguments to Docker Compose.
-
Postgres
POSTGRES_HOST_AUTH_METHOD=trust
environment variable is now supported. -
Support for Redis Stack and Redis Stack Server has been added using the
redis/redis-stack
andredis/redis-stack-server
container images respectively. -
Support for Grafana LGTM has been added using the
grafana/otel-lgtm
container image. -
Support has been added for Hazelcast (using
HazelcastConnectionDetails
). -
Support has been added for OTLP logging.
-
Support has been added for
org.testcontainers.kafka.KafkaContainer
. -
Support for Redis Stack and Redis Stack Server has been added using the
redis/redis-stack
andredis/redis-stack-server
container images respectively. -
Support has been added for
org.testcontainers.grafana.LgtmStackContainer
. -
Support has been added for Hazelcast (using
HazelcastConnectionDetails
). -
Support has been added for OTLP logging.
-
Support for
RedisContainer
has been added
It is now possible to extend Spring Boot to expose actuator endpoints in a pluggable way.
The new EndpointExposureOutcomeContributor
interface can be implemented to influence @ConditionalOnAvailableEndpoint
conditions.
This extension should make it easier to offer additional platform integrations similar to our existing Cloud Foundry support.
If you’re using SSL bundles, there’s now a new endpoint showing SSL information (validity dates, issuer, subject, etc.) available under /actuator/info
.
This endpoint also shows soon to be expired certificates to alert you that they need to be rotated soon.
There’s a new configuration property named management.health.ssl.certificate-validity-warning-threshold
to configure the threshold.
A new health check monitoring the SSL certificates has been added, too. If a certificate is invalid, it sets the status to OUT_OF_SERVICE
.
The /scheduledtasks
Actuator endpoint now exposes additional metadata about scheduled tasks, such as "next scheduled execution time" and "last execution time, status and exception".
Spring Boot 3.4 moves to new versions of several Spring projects:
Numerous third-party dependencies have also been updated, some of the more noteworthy of which are the following:
-
Apache Http Client 5.4
-
Elasticsearch Client 8.15
-
Hibernate 6.6
-
HtmlUnit 4.5.0
-
JUnit Jupiter 5.11
-
Jackson 2.18.0
-
Jedis 5.2
-
Kafka 3.8
-
Lettuce 6.4
-
Log4j 2.24
-
MongoDB 5.2.0
-
R2DBC MySQL 1.3
-
Rabbit AMQP Client 5.22
-
Rabbit Stream Client 0.18.0
Apart from the changes listed above, there have also been lots of minor tweaks and improvements including:
-
You can now use a
Customizer<Liquibase>
bean to customize Liquibase before it is being used -
The properties used to create a JCache
CacheManager
can now be customized by defining aJCachePropertiesCustomizer
bean. -
The
RequestToViewNameTranslator
used by Spring MVC can now be customized by defining a bean namedviewNameTranslator
. -
Lettuce’s
ClientOptions
can now be customized using aLettuceClientOptionsBuilderCustomizer
bean. For broader configuration of the wholeLettuceClientConfiguration
, continue to useLettuceClientConfigurationBuilderCustomizer
. -
The new customizer
ProxyConnectionFactoryCustomizer
can be used to customize a R2DBCProxyConnectionFactory
. -
An audit event is now published if a Spring Security logout happens.
-
TLS on
JavaMailSender
can now be configured with SSL bundles using the new propertiesspring.mail.ssl.*
-
GSON’s strictness can be configured using the new
spring.gson.strictness
property. -
@Name
can now be used on the field of a JavaBean-style configuration property to customize its name. -
When derived from another
DataSource
,DataSourceBuilder
can now determine the Driver class name using the source DataSource’s URL if it does not expose the Driver class name. -
Liveness and Readiness health probes are now automatically enabled on Cloud Foundry Platforms.
-
The new property
spring.application.version
can be used to read and set the application version. The default value for the property is taken from theImplementation-Version
of the manifest. -
The auto-configured
EntityManagerFactoryBuilder
defines the native (e.g. Hibernate) properties as well. -
Spring Integration’s
TaskScheduler
is now virtual thread aware, even if@EnableScheduling
hasn’t been used. -
@ConditionalOnAvailableEndpoint
now has avalue
alais forendpoint
. -
A new configuration property,
spring.data.web.pageable.serialization-mode
, for configuring Spring Data Web’s serialization mode has been added. -
When using the
SpringApplication.from(…)
syntax, it’s now possible to specify the additional profiles to activate. -
The Spring Boot plugin no longer sets
BP_NATIVE_IMAGE: true
in the buildpack environment. -
Registered
@ConfigurationProperties
beans now respect@DependsOn
,@Description
,@Fallback
,@Lazy
,@Primary
,@Scope
and@Role
annotations. -
Log4j2’s
MultiFormatStringBuilderFormattable
is now supported in structured logging -
A new configuration property,
spring.jms.listener.max-messages-per-task
, for configuring the maximum number of messages a listener processes in one task has been added. -
The default security configuration now exposes health groups mapped to additional paths. In addition, both
EndpointRequest
classes now offertoAdditionalPaths(…)
methods. -
The partitioned attribute of session cookies can now be set through properties.
-
A new
server.jetty.max-form-keys
property has been added to customize Jetty’s max form keys. -
New properties
management.otlp.logging.connect-timeout
andmanagement.otlp.tracing.connect-timeout
have been added to configure the connect timeout to the OTLP collector. -
Support for gRPC transport when shipping logs over OTLP has been added.
-
When binding a directory in the container which is used by buildpacks in the build process, a warning is now shown.
-
When building a native image with
--enable-sbom=sbom
, this SBOM is now auto-detected. -
The
DatabaseDriver
enum now support the ClickHouse JDBC driver. -
The new properties
management.logging.export.enabled
andmanagement.otlp.logging.export.enabled
can be used to disable log exporting. -
The
TaskExecutor
used by Spring Batch can be customized by defining aTaskExecutor
bean annotated with@BatchTaskExectuor
. -
Spring Session auto-configuration now supports the
indexed
repository type in reactive web applications. -
A warning from
HikariCheckpointRestoreLifecycle
will be logged if pool suspension isn’t configured and a checkpoint is created.
-
spring.gson.lenient
in favor ofspring.gson.strictness
. -
@MockBean
and@SpyBean
in favor of Spring Framework’s@MockitoBean
andMockitoSpyBean
respectively. -
org.springframework.boot.ResourceBanner#getApplicationVersion(Class<?>)
in favor ofspring.application.version
property. -
org.springframework.boot.SpringApplication#logStartupInfo(boolean)
in favor oforg.springframework.boot.SpringApplication#logStartupInfo(ConfigurationApplicationContext)
. -
org.springframework.boot.logging.logback.ApplicationNameConverter
in favor oforg.springframework.boot.logging.logback.EnclosedInSquareBracketsConverter
. -
org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure#CLOUD_FOUNDRY
in favor oforg.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure#WEB
. -
org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails#getUrl()
in favor ofgetUrl(Transport)
-
org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryAutoConfiguration
in favor oforg.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryTracingAutoConfiguration
-
OtlpAutoConfiguration
has been in favor ofOtlpTracingAutoConfiguration
-
management.endpoints.enabled-by-default
andmanagement.endpoint.<id>.enabled
in favor ofmanagement.endpoints.access.default
andmanagement.endpoint.<id>.access
respectively -
enableByDefault
on@Endpoint
in favor ofdefaultAccess