Add nullability annotations to module/spring-boot-webclient

See gh-46587
This commit is contained in:
Moritz Halbritter
2025-08-07 10:48:43 +02:00
parent 544e7281d6
commit 840fc57d7a
9 changed files with 42 additions and 17 deletions
@@ -20,6 +20,8 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.boot.http.client.autoconfigure.ApiversionProperties;
import org.springframework.boot.http.client.autoconfigure.reactive.AbstractClientHttpConnectorProperties;
@@ -40,7 +42,7 @@ public abstract class AbstractWebClientProperties extends AbstractClientHttpConn
* Base url to set in the underlying HTTP client group. By default, set to
* {@code null}.
*/
private String baseUrl;
private @Nullable String baseUrl;
/**
* Default request headers for interface client group. By default, set to empty
@@ -54,11 +56,11 @@ public abstract class AbstractWebClientProperties extends AbstractClientHttpConn
@NestedConfigurationProperty
private final ApiversionProperties apiversion = new ApiversionProperties();
public String getBaseUrl() {
public @Nullable String getBaseUrl() {
return this.baseUrl;
}
public void setBaseUrl(String baseUrl) {
public void setBaseUrl(@Nullable String baseUrl) {
this.baseUrl = baseUrl;
}
@@ -21,6 +21,8 @@ import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.boot.http.client.autoconfigure.ApiversionProperties;
import org.springframework.boot.http.client.autoconfigure.PropertiesApiVersionInserter;
@@ -29,6 +31,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.web.client.ApiVersionFormatter;
import org.springframework.web.client.ApiVersionInserter;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClient.Builder;
/**
* {@link WebClientCustomizer} to apply {@link AbstractWebClientProperties}.
@@ -38,18 +41,19 @@ import org.springframework.web.reactive.function.client.WebClient;
*/
public class PropertiesWebClientCustomizer implements WebClientCustomizer {
private final AbstractWebClientProperties[] orderedProperties;
private final @Nullable AbstractWebClientProperties[] orderedProperties;
private ApiVersionInserter apiVersionInserter;
private final @Nullable ApiVersionInserter apiVersionInserter;
public PropertiesWebClientCustomizer(ApiVersionInserter apiVersionInserter, ApiVersionFormatter apiVersionFormatter,
AbstractWebClientProperties... orderedProperties) {
public PropertiesWebClientCustomizer(@Nullable ApiVersionInserter apiVersionInserter,
@Nullable ApiVersionFormatter apiVersionFormatter,
@Nullable AbstractWebClientProperties... orderedProperties) {
this.orderedProperties = orderedProperties;
this.apiVersionInserter = PropertiesApiVersionInserter.get(apiVersionInserter, apiVersionFormatter,
Arrays.stream(orderedProperties).map(this::getApiVersion));
}
private ApiversionProperties getApiVersion(AbstractWebClientProperties properties) {
private @Nullable ApiversionProperties getApiVersion(@Nullable AbstractWebClientProperties properties) {
return (properties != null) ? properties.getApiversion() : null;
}
@@ -62,13 +66,16 @@ public class PropertiesWebClientCustomizer implements WebClientCustomizer {
if (properties != null) {
map.from(properties::getBaseUrl).whenHasText().to(builder::baseUrl);
map.from(properties::getDefaultHeader).as(this::putAllHeaders).to(builder::defaultHeaders);
map.from(properties.getApiversion())
.as(ApiversionProperties::getDefaultVersion)
.to(builder::defaultApiVersion);
setDefaultApiVersion(builder, map, properties);
}
}
}
@SuppressWarnings("NullAway") // Lambda isn't detected with the correct nullability
private void setDefaultApiVersion(Builder builder, PropertyMapper map, AbstractWebClientProperties properties) {
map.from(properties.getApiversion()).as(ApiversionProperties::getDefaultVersion).to(builder::defaultApiVersion);
}
private Consumer<HttpHeaders> putAllHeaders(Map<String, List<String>> defaultHeaders) {
return (httpHeaders) -> httpHeaders.putAll(defaultHeaders);
}
@@ -17,4 +17,7 @@
/**
* Auto-configuration for Spring Framework's functional web client.
*/
@NullMarked
package org.springframework.boot.webclient.autoconfigure;
import org.jspecify.annotations.NullMarked;
@@ -53,6 +53,7 @@ import org.springframework.web.service.registry.ImportHttpServices;
@EnableConfigurationProperties(ReactiveHttpClientServiceProperties.class)
public final class ReactiveHttpServiceClientAutoConfiguration implements BeanClassLoaderAware {
@SuppressWarnings("NullAway.Init")
private ClassLoader beanClassLoader;
ReactiveHttpServiceClientAutoConfiguration() {
@@ -16,6 +16,8 @@
package org.springframework.boot.webclient.autoconfigure.service;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.http.client.autoconfigure.reactive.ClientHttpConnectors;
import org.springframework.boot.http.client.autoconfigure.reactive.HttpReactiveClientProperties;
@@ -54,9 +56,9 @@ class WebClientPropertiesHttpServiceGroupConfigurer implements WebClientHttpServ
private final ObjectProvider<ClientHttpConnectorSettings> clientConnectorSettings;
private final ApiVersionInserter apiVersionInserter;
private final @Nullable ApiVersionInserter apiVersionInserter;
private final ApiVersionFormatter apiVersionFormatter;
private final @Nullable ApiVersionFormatter apiVersionFormatter;
WebClientPropertiesHttpServiceGroupConfigurer(ClassLoader classLoader, ObjectProvider<SslBundles> sslBundles,
HttpReactiveClientProperties clientProperties, ReactiveHttpClientServiceProperties serviceProperties,
@@ -91,12 +93,13 @@ class WebClientPropertiesHttpServiceGroupConfigurer implements WebClientHttpServ
}
private PropertiesWebClientCustomizer getPropertiesWebClientCustomizer(
ReactiveHttpClientServiceProperties.Group groupProperties) {
ReactiveHttpClientServiceProperties.@Nullable Group groupProperties) {
return new PropertiesWebClientCustomizer(this.apiVersionInserter, this.apiVersionFormatter, groupProperties,
this.serviceProperties);
}
private ClientHttpConnector getClientConnector(ReactiveHttpClientServiceProperties.Group groupProperties) {
private ClientHttpConnector getClientConnector(
ReactiveHttpClientServiceProperties.@Nullable Group groupProperties) {
ClientHttpConnectors connectors = new ClientHttpConnectors(this.sslBundles, groupProperties,
this.serviceProperties, this.clientProperties);
ClientHttpConnectorBuilder<?> builder = this.clientConnectorBuilder
@@ -17,4 +17,7 @@
/**
* Auto-Configuration for Spring's Reactive HTTP Service Interface Clients.
*/
@NullMarked
package org.springframework.boot.webclient.autoconfigure.service;
import org.jspecify.annotations.NullMarked;
@@ -17,4 +17,7 @@
/**
* Observation integration for WebClient.
*/
@NullMarked
package org.springframework.boot.webclient.observation;
import org.jspecify.annotations.NullMarked;
@@ -17,4 +17,7 @@
/**
* Spring WebFlux WebClient support abstractions.
*/
@NullMarked
package org.springframework.boot.webclient;
import org.jspecify.annotations.NullMarked;