Nullability refinements and related polishing

See gh-32475
This commit is contained in:
Juergen Hoeller
2024-03-19 09:58:44 +01:00
parent cd7ba1835c
commit c531a8a705
58 changed files with 327 additions and 257 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import io.micrometer.common.KeyValues;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.springframework.web.reactive.function.client.ClientHttpObservationDocumentation.HighCardinalityKeyNames;
import org.springframework.web.reactive.function.client.ClientHttpObservationDocumentation.LowCardinalityKeyNames;
@@ -88,8 +89,10 @@ public class DefaultClientRequestObservationConvention implements ClientRequestO
}
@Override
@Nullable
public String getContextualName(ClientRequestObservationContext context) {
return "http " + context.getRequest().method().name().toLowerCase();
ClientRequest request = context.getRequest();
return (request != null ? "http " + request.method().name().toLowerCase() : null);
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -94,7 +94,7 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (this.applicationContext == event.getApplicationContext() && this.handlerMap.isEmpty()) {
detectResourceHandlers(this.applicationContext);
detectResourceHandlers(event.getApplicationContext());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -75,14 +75,14 @@ public final class ConsumesRequestCondition extends AbstractRequestCondition<Con
* @param consumes as described in {@link RequestMapping#consumes()}
* @param headers as described in {@link RequestMapping#headers()}
*/
public ConsumesRequestCondition(String[] consumes, String[] headers) {
public ConsumesRequestCondition(@Nullable String[] consumes, @Nullable String[] headers) {
this.expressions = parseExpressions(consumes, headers);
if (this.expressions.size() > 1) {
Collections.sort(this.expressions);
}
}
private static List<ConsumeMediaTypeExpression> parseExpressions(String[] consumes, String[] headers) {
private static List<ConsumeMediaTypeExpression> parseExpressions(@Nullable String[] consumes, @Nullable String[] headers) {
Set<ConsumeMediaTypeExpression> result = null;
if (!ObjectUtils.isEmpty(headers)) {
for (String header : headers) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -81,7 +81,7 @@ public final class ProducesRequestCondition extends AbstractRequestCondition<Pro
* @param produces expressions with syntax defined by {@link RequestMapping#produces()}
* @param headers expressions with syntax defined by {@link RequestMapping#headers()}
*/
public ProducesRequestCondition(String[] produces, String[] headers) {
public ProducesRequestCondition(@Nullable String[] produces, @Nullable String[] headers) {
this(produces, headers, null);
}
@@ -92,15 +92,17 @@ public final class ProducesRequestCondition extends AbstractRequestCondition<Pro
* @param headers expressions with syntax defined by {@link RequestMapping#headers()}
* @param resolver used to determine requested content type
*/
public ProducesRequestCondition(String[] produces, String[] headers, RequestedContentTypeResolver resolver) {
public ProducesRequestCondition(
@Nullable String[] produces, @Nullable String[] headers, @Nullable RequestedContentTypeResolver resolver) {
this.expressions = parseExpressions(produces, headers);
if (this.expressions.size() > 1) {
Collections.sort(this.expressions);
}
this.contentTypeResolver = resolver != null ? resolver : DEFAULT_CONTENT_TYPE_RESOLVER;
this.contentTypeResolver = (resolver != null ? resolver : DEFAULT_CONTENT_TYPE_RESOLVER);
}
private List<ProduceMediaTypeExpression> parseExpressions(String[] produces, String[] headers) {
private List<ProduceMediaTypeExpression> parseExpressions(@Nullable String[] produces, @Nullable String[] headers) {
Set<ProduceMediaTypeExpression> result = null;
if (!ObjectUtils.isEmpty(headers)) {
for (String header : headers) {

View File

@@ -16,6 +16,7 @@
package org.springframework.web.reactive.result.method.annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
@@ -200,7 +201,10 @@ public abstract class AbstractNamedValueArgumentResolver extends HandlerMethodAr
WebDataBinder binder = bindingContext.createDataBinder(exchange, namedValueInfo.name);
Class<?> parameterType = parameter.getParameterType();
if (KotlinDetector.isKotlinPresent() && KotlinDetector.isInlineClass(parameterType)) {
parameterType = BeanUtils.findPrimaryConstructor(parameterType).getParameterTypes()[0];
Constructor<?> ctor = BeanUtils.findPrimaryConstructor(parameterType);
if (ctor != null) {
parameterType = ctor.getParameterTypes()[0];
}
}
try {
value = binder.convertIfNecessary(value, parameterType, parameter);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,7 +32,6 @@ import org.springframework.core.ReactiveAdapter;
import org.springframework.core.ReactiveAdapterRegistry;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
@@ -74,7 +73,6 @@ class ModelInitializer {
* @param exchange the current exchange
* @return a {@code Mono} for when the model is populated.
*/
@SuppressWarnings("Convert2MethodRef")
public Mono<Void> initModel(HandlerMethod handlerMethod, InitBinderBindingContext bindingContext,
ServerWebExchange exchange) {
@@ -124,7 +122,7 @@ class ModelInitializer {
ResolvableType type = handlerResult.getReturnType();
MethodParameter typeSource = handlerResult.getReturnTypeSource();
ReactiveAdapter adapter = this.adapterRegistry.getAdapter(type.resolve(), value);
if (isAsyncVoidType(type, typeSource, adapter)) {
if (adapter != null && isAsyncVoidType(type, typeSource, adapter)) {
return Mono.from(adapter.toPublisher(value));
}
String name = getAttributeName(typeSource);
@@ -134,10 +132,10 @@ class ModelInitializer {
}
private boolean isAsyncVoidType(ResolvableType type, MethodParameter typeSource, @Nullable ReactiveAdapter adapter) {
private boolean isAsyncVoidType(ResolvableType type, MethodParameter typeSource, ReactiveAdapter adapter) {
Method method = typeSource.getMethod();
return (adapter != null && (adapter.isNoValue() || type.resolveGeneric() == Void.class)) ||
(method != null && KotlinDetector.isSuspendingFunction(method) && typeSource.getParameterType() == void.class);
return (adapter.isNoValue() || type.resolveGeneric() == Void.class || (method != null &&
KotlinDetector.isSuspendingFunction(method) && typeSource.getParameterType() == void.class));
}
private String getAttributeName(MethodParameter param) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -94,7 +94,6 @@ public class ResponseEntityResultHandler extends AbstractMessageWriterResultHand
isSupportedType(result.getReturnType().getGeneric().toClass());
}
@Nullable
private static Class<?> resolveReturnValueType(HandlerResult result) {
Class<?> valueType = result.getReturnType().toClass();
Object value = result.getReturnValue();