Search in sources :

Example 6 with HandlerMethod

use of org.springframework.messaging.handler.HandlerMethod in project spring-framework by spring-projects.

the class AbstractMethodMessageHandler method getHandlerMethod.

@Nullable
private Match<T> getHandlerMethod(Message<?> message) {
    List<Match<T>> matches = new ArrayList<>();
    RouteMatcher.Route destination = getDestination(message);
    List<T> mappingsByUrl = (destination != null ? this.destinationLookup.get(destination.value()) : null);
    if (mappingsByUrl != null) {
        addMatchesToCollection(mappingsByUrl, message, matches);
    }
    if (matches.isEmpty()) {
        // No direct hits, go through all mappings
        Set<T> allMappings = this.handlerMethods.keySet();
        addMatchesToCollection(allMappings, message, matches);
    }
    if (matches.isEmpty()) {
        handleNoMatch(destination, message);
        return null;
    }
    Comparator<Match<T>> comparator = new MatchComparator(getMappingComparator(message));
    matches.sort(comparator);
    if (logger.isTraceEnabled()) {
        logger.trace("Found " + matches.size() + " handler methods: " + matches);
    }
    Match<T> bestMatch = matches.get(0);
    if (matches.size() > 1) {
        Match<T> secondBestMatch = matches.get(1);
        if (comparator.compare(bestMatch, secondBestMatch) == 0) {
            HandlerMethod m1 = bestMatch.handlerMethod;
            HandlerMethod m2 = secondBestMatch.handlerMethod;
            throw new IllegalStateException("Ambiguous handler methods mapped for destination '" + (destination != null ? destination.value() : "") + "': {" + m1.getShortLogMessage() + ", " + m2.getShortLogMessage() + "}");
        }
    }
    return bestMatch;
}
Also used : ArrayList(java.util.ArrayList) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) HandlerMethod(org.springframework.messaging.handler.HandlerMethod) RouteMatcher(org.springframework.util.RouteMatcher) Nullable(org.springframework.lang.Nullable)

Example 7 with HandlerMethod

use of org.springframework.messaging.handler.HandlerMethod in project spring-framework by spring-projects.

the class AbstractMethodMessageHandler method createHandlerMethod.

/**
 * Create a HandlerMethod instance from an Object handler that is either a handler
 * instance or a String-based bean name.
 */
private 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, context.getAutowireCapableBeanFactory(), method);
    } else {
        handlerMethod = new HandlerMethod(handler, method);
    }
    return handlerMethod;
}
Also used : ApplicationContext(org.springframework.context.ApplicationContext) HandlerMethod(org.springframework.messaging.handler.HandlerMethod)

Example 8 with HandlerMethod

use of org.springframework.messaging.handler.HandlerMethod in project spring-framework by spring-projects.

the class InvocableHelper method initExceptionHandlerMethod.

/**
 * Find an exception handling method for the given exception.
 * <p>The default implementation searches methods in the class hierarchy of
 * the HandlerMethod first and if not found, it continues searching for
 * additional handling methods registered via
 * {@link #registerExceptionHandlerAdvice}.
 * @param handlerMethod the method where the exception was raised
 * @param ex the exception raised or signaled
 * @return a method to handle the exception, or {@code null}
 */
@Nullable
public InvocableHandlerMethod initExceptionHandlerMethod(HandlerMethod handlerMethod, Throwable ex) {
    if (logger.isDebugEnabled()) {
        logger.debug("Searching for methods to handle " + ex.getClass().getSimpleName());
    }
    Class<?> beanType = handlerMethod.getBeanType();
    AbstractExceptionHandlerMethodResolver resolver = this.exceptionHandlerCache.get(beanType);
    if (resolver == null) {
        resolver = this.exceptionMethodResolverFactory.apply(beanType);
        this.exceptionHandlerCache.put(beanType, resolver);
    }
    InvocableHandlerMethod exceptionHandlerMethod = null;
    Method method = resolver.resolveMethod(ex);
    if (method != null) {
        exceptionHandlerMethod = new InvocableHandlerMethod(handlerMethod.getBean(), method);
    } else {
        for (Map.Entry<MessagingAdviceBean, AbstractExceptionHandlerMethodResolver> entry : this.exceptionHandlerAdviceCache.entrySet()) {
            MessagingAdviceBean advice = entry.getKey();
            if (advice.isApplicableToBeanType(beanType)) {
                resolver = entry.getValue();
                method = resolver.resolveMethod(ex);
                if (method != null) {
                    exceptionHandlerMethod = new InvocableHandlerMethod(advice.resolveBean(), method);
                    break;
                }
            }
        }
    }
    if (exceptionHandlerMethod != null) {
        logger.debug("Found exception handler " + exceptionHandlerMethod.getShortLogMessage());
        exceptionHandlerMethod.setArgumentResolvers(this.argumentResolvers.getResolvers());
    } else {
        logger.error("No exception handling method", ex);
    }
    return exceptionHandlerMethod;
}
Also used : AbstractExceptionHandlerMethodResolver(org.springframework.messaging.handler.invocation.AbstractExceptionHandlerMethodResolver) HandlerMethod(org.springframework.messaging.handler.HandlerMethod) Method(java.lang.reflect.Method) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) MessagingAdviceBean(org.springframework.messaging.handler.MessagingAdviceBean) Nullable(org.springframework.lang.Nullable)

Example 9 with HandlerMethod

use of org.springframework.messaging.handler.HandlerMethod in project spring-framework by spring-projects.

the class AbstractMethodMessageHandler method createHandlerMethod.

/**
 * Create a HandlerMethod instance from an Object handler that is either a handler
 * instance or a String-based bean name.
 */
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, context.getAutowireCapableBeanFactory(), method);
    } else {
        handlerMethod = new HandlerMethod(handler, method);
    }
    return handlerMethod;
}
Also used : ApplicationContext(org.springframework.context.ApplicationContext) HandlerMethod(org.springframework.messaging.handler.HandlerMethod)

Example 10 with HandlerMethod

use of org.springframework.messaging.handler.HandlerMethod in project spring-framework by spring-projects.

the class AbstractMethodMessageHandler method registerHandlerMethod.

/**
 * Register a handler method and its unique mapping.
 * @param handler the bean name of the handler or the handler instance
 * @param method the method to register
 * @param mapping the mapping conditions associated with the handler method
 * @throws IllegalStateException if another method was already registered
 * under the same mapping
 */
protected void registerHandlerMethod(Object handler, Method method, T mapping) {
    Assert.notNull(mapping, "Mapping must not be null");
    HandlerMethod newHandlerMethod = createHandlerMethod(handler, method);
    HandlerMethod oldHandlerMethod = this.handlerMethods.get(mapping);
    if (oldHandlerMethod != null && !oldHandlerMethod.equals(newHandlerMethod)) {
        throw new IllegalStateException("Ambiguous mapping found. Cannot map '" + newHandlerMethod.getBean() + "' bean method \n" + newHandlerMethod + "\nto " + mapping + ": There is already '" + oldHandlerMethod.getBean() + "' bean method\n" + oldHandlerMethod + " mapped.");
    }
    this.handlerMethods.put(mapping, newHandlerMethod);
    for (String pattern : getDirectLookupDestinations(mapping)) {
        this.destinationLookup.add(pattern, mapping);
    }
}
Also used : HandlerMethod(org.springframework.messaging.handler.HandlerMethod)

Aggregations

HandlerMethod (org.springframework.messaging.handler.HandlerMethod)11 Test (org.junit.jupiter.api.Test)3 Nullable (org.springframework.lang.Nullable)3 Method (java.lang.reflect.Method)2 LinkedHashMap (java.util.LinkedHashMap)2 Map (java.util.Map)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 ApplicationContext (org.springframework.context.ApplicationContext)2 MessagingAdviceBean (org.springframework.messaging.handler.MessagingAdviceBean)2 ArrayList (java.util.ArrayList)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1 CompositeMessageCondition (org.springframework.messaging.handler.CompositeMessageCondition)1 DestinationPatternsMessageCondition (org.springframework.messaging.handler.DestinationPatternsMessageCondition)1 AbstractExceptionHandlerMethodResolver (org.springframework.messaging.handler.invocation.AbstractExceptionHandlerMethodResolver)1 LinkedMultiValueMap (org.springframework.util.LinkedMultiValueMap)1 MultiValueMap (org.springframework.util.MultiValueMap)1 RouteMatcher (org.springframework.util.RouteMatcher)1