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
Constructor Summary
Constructors Constructor Description AbstractMethodMessageHandler()
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description void
afterPropertiesSet()
Invoked by the containingBeanFactory
after it has set all bean properties and satisfiedBeanFactoryAware
,ApplicationContextAware
etc.protected abstract AbstractExceptionHandlerMethodResolver
createExceptionMethodResolverFor(Class<?> beanType)
Create a concrete instance ofAbstractExceptionHandlerMethodResolver
that finds exception handling methods based on some criteria, e.g.protected 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.protected T
extendMapping(T mapping, HandlerMethod handlerMethod)
This method is invoked just before mappings are added.ApplicationContext
getApplicationContext()
ArgumentResolverConfigurer
getArgumentResolverConfigurer()
Return the configured custom resolvers for handler method arguments.protected HandlerMethodArgumentResolverComposite
getArgumentResolvers()
Return the argument resolvers initialized duringafterPropertiesSet()
.String
getBeanName()
protected abstract RouteMatcher.Route
getDestination(Message<?> message)
Extract the destination from the given message.MultiValueMap<String,T>
getDestinationLookup()
Return a read-only multi-value map with a direct lookup of mappings, (e.g.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.Map<T,HandlerMethod>
getHandlerMethods()
Return a read-only map with all handler methods and their mappings.Predicate<Class<?>>
getHandlerPredicate()
Return theconfigured
handler predicate.protected abstract Comparator<T>
getMappingComparator(Message<?> message)
Return a comparator for sorting matching mappings.protected abstract T
getMappingForMethod(Method method, Class<?> handlerType)
Obtain the mapping for the given method, if any.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.ReactiveAdapterRegistry
getReactiveAdapterRegistry()
Return the configured registry for adapting reactive types.ReturnValueHandlerConfigurer
getReturnValueHandlerConfigurer()
Return the configured return value handlers.protected reactor.core.publisher.Mono<Void>
handleMatch(T mapping, HandlerMethod handlerMethod, Message<?> message)
reactor.core.publisher.Mono<Void>
handleMessage(Message<?> message)
Handle the given message.protected void
handleNoMatch(RouteMatcher.Route destination, Message<?> message)
Invoked when no matching handler is found.protected abstract List<? extends HandlerMethodArgumentResolver>
initArgumentResolvers()
Return the list of argument resolvers to use.protected abstract List<? extends HandlerMethodReturnValueHandler>
initReturnValueHandlers()
Return the list of return value handlers to use.protected void
registerExceptionHandlerAdvice(MessagingAdviceBean bean, AbstractExceptionHandlerMethodResolver resolver)
Subclasses can invoke this method to populate the MessagingAdviceBean cache (e.g.protected void
registerHandlerMethod(Object handler, Method method, T mapping)
Register a handler method and its unique mapping.void
setApplicationContext(ApplicationContext applicationContext)
Set the ApplicationContext that this object runs in.void
setArgumentResolverConfigurer(ArgumentResolverConfigurer configurer)
Configure custom resolvers for handler method arguments.void
setBeanName(String name)
Set the name of the bean in the bean factory that created this bean.void
setHandlerPredicate(Predicate<Class<?>> handlerPredicate)
Configure a predicate for selecting which Spring beans to check for the presence of message handler methods.void
setHandlers(List<Object> handlers)
Manually configure the handlers to check for the presence of message handling methods, which also disables auto-detection via ahandlerPredicate
.void
setReactiveAdapterRegistry(ReactiveAdapterRegistry registry)
Configure the registry for adapting various reactive types.void
setReturnValueHandlerConfigurer(ReturnValueHandlerConfigurer configurer)
Configure custom return value handlers for handler methods.
Constructor Detail
AbstractMethodMessageHandler
public AbstractMethodMessageHandler()
Method Detail
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 sub-classes may initialize it to some default strategy (e.g.
@Controller
classes).- See Also:
setHandlers(List)
getHandlerPredicate
@Nullable public Predicate<Class<?>> getHandlerPredicate()
Return theconfigured
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 ahandlerPredicate
. 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 afterResourceLoaderAware.setResourceLoader(org.springframework.core.io.ResourceLoader)
,ApplicationEventPublisherAware.setApplicationEventPublisher(org.springframework.context.ApplicationEventPublisher)
andMessageSourceAware
, if applicable.- Specified by:
setApplicationContext
in interfaceApplicationContextAware
- Parameters:
applicationContext
- the ApplicationContext object to be used by this object- See Also:
BeanInitializationException
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 interfaceBeanNameAware
- 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 theBeanFactoryUtils.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 (e.g. 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, (e.g. for non-pattern destinations).
getArgumentResolvers
protected HandlerMethodArgumentResolverComposite getArgumentResolvers()
Return the argument resolvers initialized duringafterPropertiesSet()
. Primarily for internal use in sub-classes.- Since:
- 5.2.2
afterPropertiesSet
public void afterPropertiesSet()
Description copied from interface:InitializingBean
Invoked by the containingBeanFactory
after it has set all bean properties and satisfiedBeanFactoryAware
,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 interfaceInitializingBean
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 checkhandlerType
- the handler type, possibly a sub-type of the method's declaring class- Returns:
- the mapping, or
null
if the method is not mapped
registerHandlerMethod
protected final void registerHandlerMethod(Object handler, Method method, T mapping)
Register a handler method and its unique mapping.Note: This method is protected and can be invoked by subclasses. Keep in mind however that the registration is not protected for concurrent use, and is expected to be done on startup.
- Parameters:
handler
- the bean name of the handler or the handler instancemethod
- the method to registermapping
- 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 sub-classes to update the mapping with theHandlerMethod
in mind. This can be useful when the method signature is used to refine the mapping, e.g. 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 addedhandlerMethod
- 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 interfaceReactiveMessageHandler
- 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:
getDirectLookupMappings(Object)
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 formessage
- 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 destinationmessage
- the message
createExceptionMethodResolverFor
protected abstract AbstractExceptionHandlerMethodResolver createExceptionMethodResolverFor(Class<?> beanType)
Create a concrete instance ofAbstractExceptionHandlerMethodResolver
that finds exception handling methods based on some criteria, e.g. based on the presence of@MessageExceptionHandler
.- Parameters:
beanType
- the class in which an exception occurred during handling- Returns:
- the resolver to use