Consistent method selection for listeners and endpoint mappings
Issue: SPR-13654
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,14 +17,9 @@
|
||||
package org.springframework.web.method;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.BridgeMethodResolver;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.core.MethodIntrospector;
|
||||
import org.springframework.util.ReflectionUtils.MethodFilter;
|
||||
|
||||
/**
|
||||
@@ -33,7 +28,9 @@ import org.springframework.util.ReflectionUtils.MethodFilter;
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
* @deprecated as of Spring 4.2.3, in favor of the generalized and refined {@link MethodIntrospector}
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class HandlerMethodSelector {
|
||||
|
||||
/**
|
||||
@@ -42,31 +39,10 @@ public abstract class HandlerMethodSelector {
|
||||
* @param handlerType the handler type to search handler methods on
|
||||
* @param handlerMethodFilter a {@link MethodFilter} to help recognize handler methods of interest
|
||||
* @return the selected methods, or an empty set
|
||||
* @see MethodIntrospector#selectMethods(Class, MethodFilter)
|
||||
*/
|
||||
public static Set<Method> selectMethods(final Class<?> handlerType, final MethodFilter handlerMethodFilter) {
|
||||
final Set<Method> handlerMethods = new LinkedHashSet<Method>();
|
||||
Set<Class<?>> handlerTypes = new LinkedHashSet<Class<?>>();
|
||||
Class<?> specificHandlerType = null;
|
||||
if (!Proxy.isProxyClass(handlerType)) {
|
||||
handlerTypes.add(handlerType);
|
||||
specificHandlerType = handlerType;
|
||||
}
|
||||
handlerTypes.addAll(Arrays.asList(handlerType.getInterfaces()));
|
||||
for (Class<?> currentHandlerType : handlerTypes) {
|
||||
final Class<?> targetClass = (specificHandlerType != null ? specificHandlerType : currentHandlerType);
|
||||
ReflectionUtils.doWithMethods(currentHandlerType, new ReflectionUtils.MethodCallback() {
|
||||
@Override
|
||||
public void doWith(Method method) {
|
||||
Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
|
||||
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
|
||||
if (handlerMethodFilter.matches(specificMethod) &&
|
||||
(bridgedMethod == specificMethod || !handlerMethodFilter.matches(bridgedMethod))) {
|
||||
handlerMethods.add(specificMethod);
|
||||
}
|
||||
}
|
||||
}, ReflectionUtils.USER_DECLARED_METHODS);
|
||||
}
|
||||
return handlerMethods;
|
||||
public static Set<Method> selectMethods(Class<?> handlerType, MethodFilter handlerMethodFilter) {
|
||||
return MethodIntrospector.selectMethods(handlerType, handlerMethodFilter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,12 +25,12 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.core.ExceptionDepthComparator;
|
||||
import org.springframework.core.MethodIntrospector;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils.MethodFilter;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.method.HandlerMethodSelector;
|
||||
|
||||
/**
|
||||
* Discovers {@linkplain ExceptionHandler @ExceptionHandler} methods in a given class,
|
||||
@@ -70,7 +70,7 @@ public class ExceptionHandlerMethodResolver {
|
||||
* @param handlerType the type to introspect
|
||||
*/
|
||||
public ExceptionHandlerMethodResolver(Class<?> handlerType) {
|
||||
for (Method method : HandlerMethodSelector.selectMethods(handlerType, EXCEPTION_HANDLER_METHODS)) {
|
||||
for (Method method : MethodIntrospector.selectMethods(handlerType, EXCEPTION_HANDLER_METHODS)) {
|
||||
for (Class<? extends Throwable> exceptionType : detectExceptionMappings(method)) {
|
||||
addExceptionMapping(exceptionType, method);
|
||||
}
|
||||
@@ -105,9 +105,8 @@ public class ExceptionHandlerMethodResolver {
|
||||
private void addExceptionMapping(Class<? extends Throwable> exceptionType, Method method) {
|
||||
Method oldMethod = this.mappedMethods.put(exceptionType, method);
|
||||
if (oldMethod != null && !oldMethod.equals(method)) {
|
||||
throw new IllegalStateException(
|
||||
"Ambiguous @ExceptionHandler method mapped for [" + exceptionType + "]: {" +
|
||||
oldMethod + ", " + method + "}.");
|
||||
throw new IllegalStateException("Ambiguous @ExceptionHandler method mapped for [" +
|
||||
exceptionType + "]: {" + oldMethod + ", " + method + "}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user