Class AbstractMethodMessageHandler<T>

java.lang.Object
org.springframework.messaging.handler.invocation.reactive.AbstractMethodMessageHandler<T>
Type Parameters:
T - the type of the Object that contains information mapping information
All Implemented Interfaces:
Aware, BeanNameAware, InitializingBean, ApplicationContextAware, ReactiveMessageHandler
Direct Known Subclasses:
MessageMappingMessageHandler

public abstract class AbstractMethodMessageHandler<T> extends Object implements ReactiveMessageHandler, ApplicationContextAware, InitializingBean, BeanNameAware
Abstract base class for reactive HandlerMethod-based message handling. Provides most of the logic required to discover handler methods at startup, find a matching handler method at runtime for a given message and invoke it.

Also supports discovering and invoking exception handling methods to process exceptions raised during message handling.

Since:
5.2
Author:
Rossen Stoyanchev
  • Field Details

    • logger

      protected final Log logger
  • Constructor Details

    • AbstractMethodMessageHandler

      public AbstractMethodMessageHandler()
  • Method Details

    • setHandlerPredicate

      public void setHandlerPredicate(@Nullable Predicate<Class<?>> handlerPredicate)
      Configure a predicate for selecting which Spring beans to check for the presence of message handler methods.

      This is not set by default. However, subclasses may initialize it to some default strategy (for example, @Controller classes).

      See Also:
    • getHandlerPredicate

      @Nullable public Predicate<Class<?>> getHandlerPredicate()
      Return the configured handler predicate.
    • setHandlers

      public void setHandlers(List<Object> handlers)
      Manually configure the handlers to check for the presence of message handling methods, which also disables auto-detection via a handlerPredicate. If you do not want to disable auto-detection, then call this method first, and then set the handler predicate.
      Parameters:
      handlers - the handlers to check
    • setArgumentResolverConfigurer

      public void setArgumentResolverConfigurer(ArgumentResolverConfigurer configurer)
      Configure custom resolvers for handler method arguments.
    • getArgumentResolverConfigurer

      public ArgumentResolverConfigurer getArgumentResolverConfigurer()
      Return the configured custom resolvers for handler method arguments.
    • setReturnValueHandlerConfigurer

      public void setReturnValueHandlerConfigurer(ReturnValueHandlerConfigurer configurer)
      Configure custom return value handlers for handler methods.
    • getReturnValueHandlerConfigurer

      public ReturnValueHandlerConfigurer getReturnValueHandlerConfigurer()
      Return the configured return value handlers.
    • setReactiveAdapterRegistry

      public void setReactiveAdapterRegistry(ReactiveAdapterRegistry registry)
      Configure the registry for adapting various reactive types.

      By default this is an instance of ReactiveAdapterRegistry with default settings.

    • getReactiveAdapterRegistry

      public ReactiveAdapterRegistry getReactiveAdapterRegistry()
      Return the configured registry for adapting reactive types.
    • setApplicationContext

      public void setApplicationContext(@Nullable ApplicationContext applicationContext)
      Description copied from interface: ApplicationContextAware
      Set the ApplicationContext that this object runs in. Normally this call will be used to initialize the object.

      Invoked after population of normal bean properties but before an init callback such as InitializingBean.afterPropertiesSet() or a custom init-method. Invoked after ResourceLoaderAware.setResourceLoader(org.springframework.core.io.ResourceLoader), ApplicationEventPublisherAware.setApplicationEventPublisher(org.springframework.context.ApplicationEventPublisher) and MessageSourceAware, if applicable.

      Specified by:
      setApplicationContext in interface ApplicationContextAware
      Parameters:
      applicationContext - the ApplicationContext object to be used by this object
      See Also:
    • getApplicationContext

      @Nullable public ApplicationContext getApplicationContext()
    • setBeanName

      public void setBeanName(String name)
      Description copied from interface: BeanNameAware
      Set the name of the bean in the bean factory that created this bean.

      Invoked after population of normal bean properties but before an init callback such as InitializingBean.afterPropertiesSet() or a custom init-method.

      Specified by:
      setBeanName in interface BeanNameAware
      Parameters:
      name - the name of the bean in the factory. Note that this name is the actual bean name used in the factory, which may differ from the originally specified name: in particular for inner bean names, the actual bean name might have been made unique through appending "#..." suffixes. Use the BeanFactoryUtils.originalBeanName(String) method to extract the original bean name (without suffix), if desired.
    • getBeanName

      public String getBeanName()
    • registerExceptionHandlerAdvice

      protected void registerExceptionHandlerAdvice(MessagingAdviceBean bean, AbstractExceptionHandlerMethodResolver resolver)
      Subclasses can invoke this method to populate the MessagingAdviceBean cache (for example, to support "global" @MessageExceptionHandler).
    • getHandlerMethods

      public Map<T,HandlerMethod> getHandlerMethods()
      Return a read-only map with all handler methods and their mappings.
    • getDestinationLookup

      public MultiValueMap<String,T> getDestinationLookup()
      Return a read-only multi-value map with a direct lookup of mappings, (for example, for non-pattern destinations).
    • getArgumentResolvers

      protected HandlerMethodArgumentResolverComposite getArgumentResolvers()
      Return the argument resolvers initialized during afterPropertiesSet(). Primarily for internal use in subclasses.
      Since:
      5.2.2
    • afterPropertiesSet

      public void afterPropertiesSet()
      Description copied from interface: InitializingBean
      Invoked by the containing BeanFactory after it has set all bean properties and satisfied BeanFactoryAware, ApplicationContextAware etc.

      This method allows the bean instance to perform validation of its overall configuration and final initialization when all bean properties have been set.

      Specified by:
      afterPropertiesSet in interface InitializingBean
    • initArgumentResolvers

      protected abstract List<? extends HandlerMethodArgumentResolver> initArgumentResolvers()
      Return the list of argument resolvers to use.

      Subclasses should also take into account custom argument types configured via setArgumentResolverConfigurer(org.springframework.messaging.handler.invocation.reactive.ArgumentResolverConfigurer).

    • initReturnValueHandlers

      protected abstract List<? extends HandlerMethodReturnValueHandler> initReturnValueHandlers()
      Return the list of return value handlers to use.

      Subclasses should also take into account custom return value types configured via setReturnValueHandlerConfigurer(org.springframework.messaging.handler.invocation.reactive.ReturnValueHandlerConfigurer).

    • detectHandlerMethods

      protected final void detectHandlerMethods(Object handler)
      Detect if the given handler has any methods that can handle messages and if so register it with the extracted mapping information.

      Note: This method is protected and can be invoked by subclasses, but this should be done on startup only as documented in registerHandlerMethod(java.lang.Object, java.lang.reflect.Method, T).

      Parameters:
      handler - the handler to check, either an instance of a Spring bean name
    • getMappingForMethod

      @Nullable protected abstract T getMappingForMethod(Method method, Class<?> handlerType)
      Obtain the mapping for the given method, if any.
      Parameters:
      method - the method to check
      handlerType - the handler type, possibly a subtype of the method's declaring class
      Returns:
      the mapping, or null if the method is not mapped
    • registerHandlerMethod

      public final void registerHandlerMethod(Object handler, Method method, T mapping)
      Register a handler method and its unique mapping.

      Note: As of 5.3 this method is public (rather than protected) and can be used both at startup and at runtime.

      Parameters:
      handler - the bean name of the handler or the handler instance
      method - the method to register
      mapping - the mapping conditions associated with the handler method
      Throws:
      IllegalStateException - if another method was already registered under the same mapping
    • extendMapping

      protected T extendMapping(T mapping, HandlerMethod handlerMethod)
      This method is invoked just before mappings are added. It allows subclasses to update the mapping with the HandlerMethod in mind. This can be useful when the method signature is used to refine the mapping, for example, based on the cardinality of input and output.

      By default this method returns the mapping that is passed in.

      Parameters:
      mapping - the mapping to be added
      handlerMethod - the target handler for the mapping
      Returns:
      a new mapping or the same
      Since:
      5.2.2
    • getDirectLookupMappings

      protected abstract Set<String> getDirectLookupMappings(T mapping)
      Return String-based destinations for the given mapping, if any, that can be used to find matches with a direct lookup (i.e. non-patterns).

      Note: This is completely optional. The mapping metadata for a subclass may support neither direct lookups, nor String based destinations.

    • handleMessage

      public reactor.core.publisher.Mono<Void> handleMessage(Message<?> message) throws MessagingException
      Description copied from interface: ReactiveMessageHandler
      Handle the given message.
      Specified by:
      handleMessage in interface ReactiveMessageHandler
      Parameters:
      message - the message to be handled
      Returns:
      a completion Mono for the result of the message handling
      Throws:
      MessagingException
    • handleMatch

      protected reactor.core.publisher.Mono<Void> handleMatch(T mapping, HandlerMethod handlerMethod, Message<?> message)
    • getDestination

      @Nullable protected abstract RouteMatcher.Route getDestination(Message<?> message)
      Extract the destination from the given message.
      See Also:
    • getMatchingMapping

      @Nullable protected abstract T getMatchingMapping(T mapping, Message<?> message)
      Check if a mapping matches the current message and return a possibly new mapping with conditions relevant to the current request.
      Parameters:
      mapping - the mapping to get a match for
      message - the message being handled
      Returns:
      the match or null if there is no match
    • getMappingComparator

      protected abstract Comparator<T> getMappingComparator(Message<?> message)
      Return a comparator for sorting matching mappings. The returned comparator should sort 'better' matches higher.
      Parameters:
      message - the current Message
      Returns:
      the comparator, never null
    • handleNoMatch

      protected void handleNoMatch(@Nullable RouteMatcher.Route destination, Message<?> message)
      Invoked when no matching handler is found.
      Parameters:
      destination - the destination
      message - the message
    • createExceptionMethodResolverFor

      protected abstract AbstractExceptionHandlerMethodResolver createExceptionMethodResolverFor(Class<?> beanType)
      Create a concrete instance of AbstractExceptionHandlerMethodResolver that finds exception handling methods based on some criteria, for example, based on the presence of @MessageExceptionHandler.
      Parameters:
      beanType - the class in which an exception occurred during handling
      Returns:
      the resolver to use