From 772087fe1878976505fbc7378be9c7dfdd4248f1 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 20 Jun 2019 12:09:51 +0100 Subject: [PATCH] Refactor RSocket handler selection 1. Consolidate config options for handler detection in the base class AbstractMethodMessageHandler with sub-classes like RSocketMessageHandler now only setting the handler predicate by default (e.g. @Controller). 2. Remove autoDetection flag in favor of just having the mutually exclusive handler Predicate vs manually registered List. Or if both are desired for some reason, then manually register first, and set the predicate second. --- .../MessageMappingMessageHandler.java | 60 +------------------ .../AbstractMethodMessageHandler.java | 59 ++++++++++++++---- .../reactive/MethodMessageHandlerTests.java | 10 ++-- 3 files changed, 52 insertions(+), 77 deletions(-) diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/MessageMappingMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/MessageMappingMessageHandler.java index bb8a236999..88d24a6b7d 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/MessageMappingMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/MessageMappingMessageHandler.java @@ -83,10 +83,6 @@ import org.springframework.validation.Validator; public class MessageMappingMessageHandler extends AbstractMethodMessageHandler implements EmbeddedValueResolverAware { - @Nullable - private Predicate> handlerPredicate = - beanType -> AnnotatedElementUtils.hasAnnotation(beanType, Controller.class); - private final List> decoders = new ArrayList<>(); @Nullable @@ -104,59 +100,10 @@ public class MessageMappingMessageHandler extends AbstractMethodMessageHandler AnnotatedElementUtils.hasAnnotation(type, Controller.class)); } - /** - * Manually configure handlers to check for {@code @MessageMapping} methods. - *

Note: the given handlers are not required to be - * annotated with {@code @Controller}. Consider also using - * {@link #setAutoDetectDisabled()} if the intent is to use these handlers - * instead of, and not in addition to {@code @Controller} classes. Or - * alternatively use {@link #setHandlerPredicate(Predicate)} to select a - * different set of beans based on a different criteria. - * @param handlers the handlers to register - * @see #setAutoDetectDisabled() - * @see #setHandlerPredicate(Predicate) - */ - public void setHandlers(List handlers) { - for (Object handler : handlers) { - detectHandlerMethods(handler); - } - // Disable auto-detection.. - this.handlerPredicate = null; - } - - /** - * Configure the predicate to use for selecting which Spring beans to check - * for {@code @MessageMapping} methods. When set to {@code null}, - * auto-detection is turned off which is what - * {@link #setAutoDetectDisabled()} does internally. - *

The predicate used by default selects {@code @Controller} classes. - * @see #setHandlers(List) - * @see #setAutoDetectDisabled() - */ - public void setHandlerPredicate(@Nullable Predicate> handlerPredicate) { - this.handlerPredicate = handlerPredicate; - } - - /** - * Return the {@link #setHandlerPredicate configured} handler predicate. - */ - @Nullable - public Predicate> getHandlerPredicate() { - return this.handlerPredicate; - } - - /** - * Disable auto-detection of {@code @MessageMapping} methods, e.g. in - * {@code @Controller}s, by setting {@link #setHandlerPredicate(Predicate) - * setHandlerPredicate(null)}. - */ - public void setAutoDetectDisabled() { - this.handlerPredicate = null; - } - /** * Configure the decoders to use for incoming payloads. */ @@ -264,11 +211,6 @@ public class MessageMappingMessageHandler extends AbstractMethodMessageHandler> initHandlerPredicate() { - return this.handlerPredicate; - } - @Override protected CompositeMessageCondition getMappingForMethod(Method method, Class handlerType) { diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/AbstractMethodMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/AbstractMethodMessageHandler.java index 43da16b095..5fb60c9074 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/AbstractMethodMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/AbstractMethodMessageHandler.java @@ -86,6 +86,12 @@ public abstract class AbstractMethodMessageHandler protected final Log logger = LogFactory.getLog(getClass()); + @Nullable + private Predicate> handlerPredicate; + + @Nullable + List handlers; + private ArgumentResolverConfigurer argumentResolverConfigurer = new ArgumentResolverConfigurer(); private ReturnValueHandlerConfigurer returnValueHandlerConfigurer = new ReturnValueHandlerConfigurer(); @@ -103,6 +109,38 @@ public abstract class AbstractMethodMessageHandler private final MultiValueMap destinationLookup = new LinkedMultiValueMap<>(64); + /** + * Configure a predicate for selecting which Spring beans to check for the + * presence of message handler methods. + *

This is not set by default. However sub-classes may initialize it to + * some default strategy (e.g. {@code @Controller} classes). + * @see #setHandlers(List) + */ + public void setHandlerPredicate(@Nullable Predicate> handlerPredicate) { + this.handlerPredicate = handlerPredicate; + } + + /** + * Return the {@link #setHandlerPredicate configured} handler predicate. + */ + @Nullable + public Predicate> getHandlerPredicate() { + return this.handlerPredicate; + } + + /** + * Manually configure the handlers to check for the presence of message + * handling methods, which also disables auto-detection via a + * {@link #setHandlerPredicate(Predicate) handlerPredicate}. If you do not + * want to disable auto-detection, then call this method first, and then set + * the handler predicate. + * @param handlers the handlers to check + */ + public void setHandlers(List handlers) { + this.handlers = handlers; + this.handlerPredicate = null; + } + /** * Configure custom resolvers for handler method arguments. */ @@ -233,9 +271,14 @@ public abstract class AbstractMethodMessageHandler logger.warn("No ApplicationContext available for detecting beans with message handling methods."); return; } - Predicate> handlerPredicate = initHandlerPredicate(); - if (handlerPredicate == null) { - logger.warn("[" + getBeanName() + "] No auto-detection of handler methods (e.g. in @Controller)."); + if (this.handlers != null) { + for (Object handler : this.handlers) { + detectHandlerMethods(handler); + } + } + Predicate> predicate = this.handlerPredicate; + if (predicate == null) { + logger.warn("[" + getBeanName() + "] Auto-detection of message handling methods is off."); return; } for (String beanName : this.applicationContext.getBeanNamesForType(Object.class)) { @@ -250,21 +293,13 @@ public abstract class AbstractMethodMessageHandler logger.debug("Could not resolve target class for bean with name '" + beanName + "'", ex); } } - if (beanType != null && handlerPredicate.test(beanType)) { + if (beanType != null && predicate.test(beanType)) { detectHandlerMethods(beanName); } } } } - /** - * Return the predicate to use to check whether a given Spring bean should - * be introspected for message handling methods. If {@code null} is - * returned, auto-detection is effectively disabled. - */ - @Nullable - protected abstract Predicate> initHandlerPredicate(); - /** * Detect if the given handler has any methods that can handle messages and if * so register it with the extracted mapping information. diff --git a/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/reactive/MethodMessageHandlerTests.java b/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/reactive/MethodMessageHandlerTests.java index 5adc945f2f..229ef2227b 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/reactive/MethodMessageHandlerTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/reactive/MethodMessageHandlerTests.java @@ -24,7 +24,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Consumer; -import java.util.function.Predicate; import org.junit.Test; import org.reactivestreams.Publisher; @@ -203,6 +202,10 @@ public class MethodMessageHandlerTests { private PathMatcher pathMatcher = new AntPathMatcher(); + public TestMethodMessageHandler() { + setHandlerPredicate(handlerType -> handlerType.getName().endsWith("Controller")); + } + @Override protected List initArgumentResolvers() { return Collections.emptyList(); @@ -213,11 +216,6 @@ public class MethodMessageHandlerTests { return Collections.singletonList(this.returnValueHandler); } - @Override - protected Predicate> initHandlerPredicate() { - return handlerType -> handlerType.getName().endsWith("Controller"); - } - @Nullable public Object getLastReturnValue() { return this.returnValueHandler.getLastReturnValue();