Consistent hasAnnotation check for findMergedAnnotation lookup

Issue: SPR-16933
This commit is contained in:
Juergen Hoeller
2018-08-08 23:54:56 +02:00
parent 3f7d4b107e
commit 247ec572b2
5 changed files with 50 additions and 45 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@@ -24,7 +24,7 @@ import java.util.List;
import java.util.Map;
import org.springframework.core.MethodIntrospector;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.messaging.handler.annotation.MessageExceptionHandler;
import org.springframework.messaging.handler.invocation.AbstractExceptionHandlerMethodResolver;
@@ -35,6 +35,7 @@ import org.springframework.messaging.handler.invocation.AbstractExceptionHandler
* or from the method signature as a fallback option.
*
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @since 4.0
*/
public class AnnotationExceptionHandlerMethodResolver extends AbstractExceptionHandlerMethodResolver {
@@ -50,7 +51,7 @@ public class AnnotationExceptionHandlerMethodResolver extends AbstractExceptionH
private static Map<Class<? extends Throwable>, Method> initExceptionMappings(Class<?> handlerType) {
Map<Method, MessageExceptionHandler> methods = MethodIntrospector.selectMethods(handlerType,
(MethodIntrospector.MetadataLookup<MessageExceptionHandler>) method ->
AnnotationUtils.findAnnotation(method, MessageExceptionHandler.class));
AnnotatedElementUtils.findMergedAnnotation(method, MessageExceptionHandler.class));
Map<Class<? extends Throwable>, Method> result = new HashMap<>();
for (Map.Entry<Method, MessageExceptionHandler> entry : methods.entrySet()) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2018 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.
@@ -21,11 +21,11 @@ import java.lang.reflect.Method;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.EventListenerFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.AnnotatedElementUtils;
/**
* {@link EventListenerFactory} implementation that handles {@link TransactionalEventListener}
* annotated method.
* annotated methods.
*
* @author Stephane Nicoll
* @since 4.2
@@ -47,7 +47,7 @@ public class TransactionalEventListenerFactory implements EventListenerFactory,
@Override
public boolean supportsMethod(Method method) {
return (AnnotationUtils.findAnnotation(method, TransactionalEventListener.class) != null);
return AnnotatedElementUtils.hasAnnotation(method, TransactionalEventListener.class);
}
@Override

View File

@@ -25,7 +25,7 @@ import java.util.Map;
import org.springframework.core.ExceptionDepthComparator;
import org.springframework.core.MethodIntrospector;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ConcurrentReferenceHashMap;
@@ -47,7 +47,7 @@ public class ExceptionHandlerMethodResolver {
* A filter for selecting {@code @ExceptionHandler} methods.
*/
public static final MethodFilter EXCEPTION_HANDLER_METHODS = method ->
(AnnotationUtils.findAnnotation(method, ExceptionHandler.class) != null);
AnnotatedElementUtils.hasAnnotation(method, ExceptionHandler.class);
private final Map<Class<? extends Throwable>, Method> mappedMethods = new HashMap<>(16);
@@ -89,8 +89,8 @@ public class ExceptionHandlerMethodResolver {
return result;
}
protected void detectAnnotationExceptionMappings(Method method, List<Class<? extends Throwable>> result) {
ExceptionHandler ann = AnnotationUtils.findAnnotation(method, ExceptionHandler.class);
private void detectAnnotationExceptionMappings(Method method, List<Class<? extends Throwable>> result) {
ExceptionHandler ann = AnnotatedElementUtils.findMergedAnnotation(method, ExceptionHandler.class);
Assert.state(ann != null, "No ExceptionHandler annotation");
result.addAll(Arrays.asList(ann.value()));
}

View File

@@ -32,13 +32,14 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.MethodIntrospector;
import org.springframework.core.ReactiveAdapterRegistry;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.MethodFilter;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -50,8 +51,6 @@ import org.springframework.web.reactive.result.method.InvocableHandlerMethod;
import org.springframework.web.reactive.result.method.SyncHandlerMethodArgumentResolver;
import org.springframework.web.reactive.result.method.SyncInvocableHandlerMethod;
import static org.springframework.core.MethodIntrospector.selectMethods;
/**
* Package-private class to assist {@link RequestMappingHandlerAdapter} with
* resolving, initializing, and caching annotated methods declared in
@@ -69,8 +68,21 @@ import static org.springframework.core.MethodIntrospector.selectMethods;
*/
class ControllerMethodResolver {
private static Log logger = LogFactory.getLog(ControllerMethodResolver.class);
/**
* MethodFilter that matches {@link InitBinder @InitBinder} methods.
*/
public static final MethodFilter INIT_BINDER_METHODS = method ->
AnnotatedElementUtils.hasAnnotation(method, InitBinder.class);
/**
* MethodFilter that matches {@link ModelAttribute @ModelAttribute} methods.
*/
public static final MethodFilter MODEL_ATTRIBUTE_METHODS = method ->
(!AnnotatedElementUtils.hasAnnotation(method, RequestMapping.class) &&
AnnotatedElementUtils.hasAnnotation(method, ModelAttribute.class));
private static Log logger = LogFactory.getLog(ControllerMethodResolver.class);
private final List<SyncHandlerMethodArgumentResolver> initBinderResolvers;
@@ -212,11 +224,11 @@ class ControllerMethodResolver {
for (ControllerAdviceBean bean : beans) {
Class<?> beanType = bean.getBeanType();
if (beanType != null) {
Set<Method> attrMethods = selectMethods(beanType, ATTRIBUTE_METHODS);
Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);
if (!attrMethods.isEmpty()) {
this.modelAttributeAdviceCache.put(bean, attrMethods);
}
Set<Method> binderMethods = selectMethods(beanType, BINDER_METHODS);
Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);
if (!binderMethods.isEmpty()) {
this.initBinderAdviceCache.put(bean, binderMethods);
}
@@ -270,7 +282,8 @@ class ControllerMethodResolver {
});
this.initBinderMethodCache
.computeIfAbsent(handlerType, aClass -> selectMethods(handlerType, BINDER_METHODS))
.computeIfAbsent(handlerType,
clazz -> MethodIntrospector.selectMethods(handlerType, INIT_BINDER_METHODS))
.forEach(method -> {
Object bean = handlerMethod.getBean();
result.add(getInitBinderMethod(bean, method));
@@ -302,7 +315,8 @@ class ControllerMethodResolver {
});
this.modelAttributeMethodCache
.computeIfAbsent(handlerType, aClass -> selectMethods(handlerType, ATTRIBUTE_METHODS))
.computeIfAbsent(handlerType,
clazz -> MethodIntrospector.selectMethods(handlerType, MODEL_ATTRIBUTE_METHODS))
.forEach(method -> {
Object bean = handlerMethod.getBean();
result.add(createAttributeMethod(bean, method));
@@ -373,14 +387,4 @@ class ControllerMethodResolver {
return result;
}
/** Filter for {@link InitBinder @InitBinder} methods. */
private static final ReflectionUtils.MethodFilter BINDER_METHODS = method ->
AnnotationUtils.findAnnotation(method, InitBinder.class) != null;
/** Filter for {@link ModelAttribute @ModelAttribute} methods. */
private static final ReflectionUtils.MethodFilter ATTRIBUTE_METHODS = method ->
(AnnotationUtils.findAnnotation(method, RequestMapping.class) == null) &&
(AnnotationUtils.findAnnotation(method, ModelAttribute.class) != null);
}

View File

@@ -36,8 +36,8 @@ import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.MethodIntrospector;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.ReactiveAdapterRegistry;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
@@ -114,6 +114,20 @@ import org.springframework.web.util.WebUtils;
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
implements BeanFactoryAware, InitializingBean {
/**
* MethodFilter that matches {@link InitBinder @InitBinder} methods.
*/
public static final MethodFilter INIT_BINDER_METHODS = method ->
AnnotatedElementUtils.hasAnnotation(method, InitBinder.class);
/**
* MethodFilter that matches {@link ModelAttribute @ModelAttribute} methods.
*/
public static final MethodFilter MODEL_ATTRIBUTE_METHODS = method ->
(!AnnotatedElementUtils.hasAnnotation(method, RequestMapping.class) &&
AnnotatedElementUtils.hasAnnotation(method, ModelAttribute.class));
@Nullable
private List<HandlerMethodArgumentResolver> customArgumentResolvers;
@@ -1005,18 +1019,4 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
return mav;
}
/**
* MethodFilter that matches {@link InitBinder @InitBinder} methods.
*/
public static final MethodFilter INIT_BINDER_METHODS = method ->
AnnotationUtils.findAnnotation(method, InitBinder.class) != null;
/**
* MethodFilter that matches {@link ModelAttribute @ModelAttribute} methods.
*/
public static final MethodFilter MODEL_ATTRIBUTE_METHODS = method ->
((AnnotationUtils.findAnnotation(method, RequestMapping.class) == null) &&
(AnnotationUtils.findAnnotation(method, ModelAttribute.class) != null));
}