Nullability fine-tuning around bean properties
Issue: SPR-15720 Issue: SPR-15792
This commit is contained in:
@@ -232,11 +232,15 @@ public abstract class AbstractMethodMessageHandler<T>
|
||||
this.returnValueHandlers.addHandlers(initReturnValueHandlers());
|
||||
}
|
||||
|
||||
for (String beanName : this.applicationContext.getBeanNamesForType(Object.class)) {
|
||||
ApplicationContext context = getApplicationContext();
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
for (String beanName : context.getBeanNamesForType(Object.class)) {
|
||||
if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
|
||||
Class<?> beanType = null;
|
||||
try {
|
||||
beanType = this.applicationContext.getType(beanName);
|
||||
beanType = context.getType(beanName);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
// An unresolvable bean type, probably from a lazy bean - let's ignore it.
|
||||
@@ -279,8 +283,15 @@ public abstract class AbstractMethodMessageHandler<T>
|
||||
* @param handler the handler to check, either an instance of a Spring bean name
|
||||
*/
|
||||
protected final void detectHandlerMethods(final Object handler) {
|
||||
Class<?> handlerType = (handler instanceof String ?
|
||||
this.applicationContext.getType((String) handler) : handler.getClass());
|
||||
Class<?> handlerType;
|
||||
if (handler instanceof String) {
|
||||
ApplicationContext context = getApplicationContext();
|
||||
Assert.state(context != null, "ApplicationContext is required for resolving handler bean names");
|
||||
handlerType = context.getType((String) handler);
|
||||
}
|
||||
else {
|
||||
handlerType = handler.getClass();
|
||||
}
|
||||
|
||||
if (handlerType != null) {
|
||||
final Class<?> userType = ClassUtils.getUserClass(handlerType);
|
||||
@@ -338,9 +349,10 @@ public abstract class AbstractMethodMessageHandler<T>
|
||||
protected HandlerMethod createHandlerMethod(Object handler, Method method) {
|
||||
HandlerMethod handlerMethod;
|
||||
if (handler instanceof String) {
|
||||
ApplicationContext context = getApplicationContext();
|
||||
Assert.state(context != null, "ApplicationContext is required for resolving handler bean names");
|
||||
String beanName = (String) handler;
|
||||
handlerMethod = new HandlerMethod(beanName,
|
||||
this.applicationContext.getAutowireCapableBeanFactory(), method);
|
||||
handlerMethod = new HandlerMethod(beanName, context.getAutowireCapableBeanFactory(), method);
|
||||
}
|
||||
else {
|
||||
handlerMethod = new HandlerMethod(handler, method);
|
||||
@@ -645,7 +657,7 @@ public abstract class AbstractMethodMessageHandler<T>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(Object result) {
|
||||
public void onSuccess(@Nullable Object result) {
|
||||
try {
|
||||
MethodParameter returnType = this.handlerMethod.getAsyncReturnValueType(result);
|
||||
returnValueHandlers.handleReturnValue(result, returnType, this.message);
|
||||
|
||||
@@ -252,7 +252,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||
}
|
||||
|
||||
|
||||
MethodParameter getAsyncReturnValueType(Object returnValue) {
|
||||
MethodParameter getAsyncReturnValueType(@Nullable Object returnValue) {
|
||||
return new AsyncResultMethodParameter(returnValue);
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||
|
||||
private final ResolvableType returnType;
|
||||
|
||||
public AsyncResultMethodParameter(Object returnValue) {
|
||||
public AsyncResultMethodParameter(@Nullable Object returnValue) {
|
||||
super(-1);
|
||||
this.returnValue = returnValue;
|
||||
this.returnType = ResolvableType.forType(super.getGenericParameterType()).getGeneric();
|
||||
|
||||
@@ -54,6 +54,7 @@ public class SimpMessagingTemplate extends AbstractMessageSendingTemplate<String
|
||||
|
||||
private volatile long sendTimeout = -1;
|
||||
|
||||
@Nullable
|
||||
private MessageHeaderInitializer headerInitializer;
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.EmbeddedValueResolverAware;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
@@ -305,8 +306,9 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan
|
||||
|
||||
|
||||
protected List<HandlerMethodArgumentResolver> initArgumentResolvers() {
|
||||
ConfigurableBeanFactory beanFactory = (getApplicationContext() instanceof ConfigurableApplicationContext ?
|
||||
((ConfigurableApplicationContext) getApplicationContext()).getBeanFactory() : null);
|
||||
ApplicationContext context = getApplicationContext();
|
||||
ConfigurableBeanFactory beanFactory = (context instanceof ConfigurableApplicationContext ?
|
||||
((ConfigurableApplicationContext) context).getBeanFactory() : null);
|
||||
|
||||
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.messaging.support;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.util.IdGenerator;
|
||||
@@ -31,6 +29,10 @@ import org.springframework.util.IdGenerator;
|
||||
*/
|
||||
public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitializer {
|
||||
|
||||
private static final IdGenerator ID_VALUE_NONE_GENERATOR = () -> MessageHeaders.ID_VALUE_NONE;
|
||||
|
||||
|
||||
@Nullable
|
||||
private IdGenerator idGenerator;
|
||||
|
||||
private boolean enableTimestamp;
|
||||
@@ -41,20 +43,12 @@ public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitial
|
||||
* instances with.
|
||||
* <p>By default this property is set to {@code null} in which case the default
|
||||
* IdGenerator of {@link org.springframework.messaging.MessageHeaders} is used.
|
||||
* <p>To have no id's generated at all, see {@link #setDisableIdGeneration()}.
|
||||
* <p>To have no ids generated at all, see {@link #setDisableIdGeneration()}.
|
||||
*/
|
||||
public void setIdGenerator(@Nullable IdGenerator idGenerator) {
|
||||
this.idGenerator = idGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* A shortcut for calling {@link #setIdGenerator(org.springframework.util.IdGenerator)}
|
||||
* with an id generation strategy to disable id generation completely.
|
||||
*/
|
||||
public void setDisableIdGeneration() {
|
||||
this.idGenerator = ID_VALUE_NONE_GENERATOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configured {@code IdGenerator}, if any.
|
||||
*/
|
||||
@@ -63,6 +57,14 @@ public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitial
|
||||
return this.idGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* A shortcut for calling {@link #setIdGenerator} with an id generation strategy
|
||||
* to disable id generation completely.
|
||||
*/
|
||||
public void setDisableIdGeneration() {
|
||||
this.idGenerator = ID_VALUE_NONE_GENERATOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to enable the automatic addition of the
|
||||
* {@link org.springframework.messaging.MessageHeaders#TIMESTAMP} header on
|
||||
@@ -90,12 +92,4 @@ public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitial
|
||||
headerAccessor.setEnableTimestamp(isEnableTimestamp());
|
||||
}
|
||||
|
||||
|
||||
private static final IdGenerator ID_VALUE_NONE_GENERATOR = new IdGenerator() {
|
||||
@Override
|
||||
public UUID generateId() {
|
||||
return MessageHeaders.ID_VALUE_NONE;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.concurrent.TimeoutException;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.publisher.MonoProcessor;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.concurrent.FailureCallback;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
@@ -67,12 +68,14 @@ abstract class AbstractMonoToListenableFutureAdapter<S, T> implements Listenable
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public T get() throws InterruptedException {
|
||||
S result = this.monoProcessor.block();
|
||||
return adapt(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
Assert.notNull(unit, "TimeUnit must not be null");
|
||||
Duration duration = Duration.ofMillis(TimeUnit.MILLISECONDS.convert(timeout, unit));
|
||||
@@ -111,6 +114,7 @@ abstract class AbstractMonoToListenableFutureAdapter<S, T> implements Listenable
|
||||
}
|
||||
|
||||
|
||||
protected abstract T adapt(S result);
|
||||
@Nullable
|
||||
protected abstract T adapt(@Nullable S result);
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.springframework.messaging.tcp.reactor;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* A Mono-to-ListenableFuture adapter where the source and the target from
|
||||
* the Promise and the ListenableFuture respectively are of the same type.
|
||||
@@ -33,7 +35,7 @@ class MonoToListenableFutureAdapter<T> extends AbstractMonoToListenableFutureAda
|
||||
}
|
||||
|
||||
@Override
|
||||
protected T adapt(T result) {
|
||||
protected T adapt(@Nullable T result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user