Consistent use of AnnotatedElementUtils.findMergedAnnotation/hasAnnotation

Issue: SPR-13440
This commit is contained in:
Juergen Hoeller
2016-03-23 18:39:20 +01:00
parent 311d4c95a3
commit 5025c615b1
33 changed files with 357 additions and 238 deletions

View File

@@ -25,7 +25,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.SynthesizingMethodParameter;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -33,10 +33,11 @@ import org.springframework.util.ClassUtils;
/**
* Encapsulates information about a handler method consisting of a
* {@linkplain #getMethod() method} and a {@linkplain #getBean() bean}.
* Provides convenient access to method parameters, method return value, method annotations.
* Provides convenient access to method parameters, the method return value,
* method annotations, etc.
*
* <p>The class may be created with a bean instance or with a bean name (e.g. lazy-init bean,
* prototype bean). Use {@link #createWithResolvedBean()} to obtain a {@link HandlerMethod}
* prototype bean). Use {@link #createWithResolvedBean()} to obtain a {@code HandlerMethod}
* instance with a bean instance resolved through the associated {@link BeanFactory}.
*
* @author Arjen Poutsma
@@ -61,6 +62,8 @@ public class HandlerMethod {
private final MethodParameter[] parameters;
private final HandlerMethod resolvedFromHandlerMethod;
/**
* Create an instance from a bean instance and a method.
@@ -74,6 +77,7 @@ public class HandlerMethod {
this.method = method;
this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
this.parameters = initMethodParameters();
this.resolvedFromHandlerMethod = null;
}
/**
@@ -89,12 +93,13 @@ public class HandlerMethod {
this.method = bean.getClass().getMethod(methodName, parameterTypes);
this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(this.method);
this.parameters = initMethodParameters();
this.resolvedFromHandlerMethod = null;
}
/**
* Create an instance from a bean name, a method, and a {@code BeanFactory}.
* The method {@link #createWithResolvedBean()} may be used later to
* re-create the {@code HandlerMethod} with an initialized the bean.
* re-create the {@code HandlerMethod} with an initialized bean.
*/
public HandlerMethod(String beanName, BeanFactory beanFactory, Method method) {
Assert.hasText(beanName, "Bean name is required");
@@ -106,6 +111,7 @@ public class HandlerMethod {
this.method = method;
this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
this.parameters = initMethodParameters();
this.resolvedFromHandlerMethod = null;
}
/**
@@ -119,6 +125,7 @@ public class HandlerMethod {
this.method = handlerMethod.method;
this.bridgedMethod = handlerMethod.bridgedMethod;
this.parameters = handlerMethod.parameters;
this.resolvedFromHandlerMethod = handlerMethod.resolvedFromHandlerMethod;
}
/**
@@ -133,6 +140,7 @@ public class HandlerMethod {
this.method = handlerMethod.method;
this.bridgedMethod = handlerMethod.bridgedMethod;
this.parameters = handlerMethod.parameters;
this.resolvedFromHandlerMethod = handlerMethod;
}
@@ -183,6 +191,15 @@ public class HandlerMethod {
return this.parameters;
}
/**
* Return the HandlerMethod from which this HandlerMethod instance was
* resolved via {@link #createWithResolvedBean()}.
* @since 4.3
*/
public HandlerMethod getResolvedFromHandlerMethod() {
return this.resolvedFromHandlerMethod;
}
/**
* Return the HandlerMethod return type.
*/
@@ -207,11 +224,24 @@ public class HandlerMethod {
/**
* Returns a single annotation on the underlying method traversing its super methods
* if no annotation can be found on the given method itself.
* @param annotationType the type of annotation to introspect the method for.
* <p>Also supports <em>merged</em> composed annotations with attribute
* overrides as of Spring Framework 4.3.
* @param annotationType the type of annotation to introspect the method for
* @return the annotation, or {@code null} if none found
* @see AnnotatedElementUtils#findMergedAnnotation
*/
public <A extends Annotation> A getMethodAnnotation(Class<A> annotationType) {
return AnnotationUtils.findAnnotation(this.method, annotationType);
return AnnotatedElementUtils.findMergedAnnotation(this.method, annotationType);
}
/**
* Return whether the parameter is declared with the given annotation type.
* @param annotationType the annotation type to look for
* @since 4.3
* @see AnnotatedElementUtils#hasAnnotation
*/
public <A extends Annotation> boolean hasMethodAnnotation(Class<A> annotationType) {
return AnnotatedElementUtils.hasAnnotation(this.method, annotationType);
}
/**
@@ -227,6 +257,9 @@ public class HandlerMethod {
return new HandlerMethod(this, handler);
}
/**
* Return a short representation of this handler method for log message purposes.
*/
public String getShortLogMessage() {
int args = this.method.getParameterTypes().length;
return getBeanType().getName() + "#" + this.method.getName() + "[" + args + " args]";
@@ -279,6 +312,11 @@ public class HandlerMethod {
return HandlerMethod.this.getMethodAnnotation(annotationType);
}
@Override
public <T extends Annotation> boolean hasMethodAnnotation(Class<T> annotationType) {
return HandlerMethod.this.hasMethodAnnotation(annotationType);
}
@Override
public HandlerMethodParameter clone() {
return new HandlerMethodParameter(this);

View File

@@ -21,6 +21,7 @@ import java.security.Principal;
import java.util.Map;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
@@ -132,13 +133,13 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH
@Override
public boolean supportsReturnType(MethodParameter returnType) {
if (returnType.getMethodAnnotation(SendTo.class) != null ||
AnnotationUtils.getAnnotation(returnType.getDeclaringClass(), SendTo.class) != null ||
returnType.getMethodAnnotation(SendToUser.class) != null ||
AnnotationUtils.getAnnotation(returnType.getDeclaringClass(), SendToUser.class) != null) {
if (returnType.hasMethodAnnotation(SendTo.class) ||
AnnotatedElementUtils.hasAnnotation(returnType.getDeclaringClass(), SendTo.class) ||
returnType.hasMethodAnnotation(SendToUser.class) ||
AnnotatedElementUtils.hasAnnotation(returnType.getDeclaringClass(), SendToUser.class)) {
return true;
}
return (!this.annotationRequired);
return !this.annotationRequired;
}
@Override
@@ -186,24 +187,24 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH
}
private SendToUser getSendToUser(MethodParameter returnType) {
SendToUser annot = returnType.getMethodAnnotation(SendToUser.class);
if (annot != null && !ObjectUtils.isEmpty((annot.value()))) {
SendToUser annot = AnnotatedElementUtils.findMergedAnnotation(returnType.getMethod(), SendToUser.class);
if (annot != null && !ObjectUtils.isEmpty(annot.value())) {
return annot;
}
SendToUser typeAnnot = AnnotationUtils.getAnnotation(returnType.getDeclaringClass(), SendToUser.class);
if (typeAnnot != null && !ObjectUtils.isEmpty((typeAnnot.value()))) {
SendToUser typeAnnot = AnnotatedElementUtils.findMergedAnnotation(returnType.getDeclaringClass(), SendToUser.class);
if (typeAnnot != null && !ObjectUtils.isEmpty(typeAnnot.value())) {
return typeAnnot;
}
return (annot != null ? annot : typeAnnot);
}
private SendTo getSendTo(MethodParameter returnType) {
SendTo sendTo = returnType.getMethodAnnotation(SendTo.class);
if (sendTo != null && !ObjectUtils.isEmpty((sendTo.value()))) {
SendTo sendTo = AnnotatedElementUtils.findMergedAnnotation(returnType.getMethod(), SendTo.class);
if (sendTo != null && !ObjectUtils.isEmpty(sendTo.value())) {
return sendTo;
}
else {
return AnnotationUtils.getAnnotation(returnType.getDeclaringClass(), SendTo.class);
return AnnotatedElementUtils.findMergedAnnotation(returnType.getDeclaringClass(), SendTo.class);
}
}

View File

@@ -29,7 +29,7 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.SmartLifecycle;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.convert.ConversionService;
import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.messaging.Message;
@@ -360,14 +360,14 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan
@Override
protected boolean isHandler(Class<?> beanType) {
return (AnnotationUtils.findAnnotation(beanType, Controller.class) != null);
return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class);
}
@Override
protected SimpMessageMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
MessageMapping messageAnn = AnnotationUtils.findAnnotation(method, MessageMapping.class);
MessageMapping messageAnn = AnnotatedElementUtils.findMergedAnnotation(method, MessageMapping.class);
if (messageAnn != null) {
MessageMapping typeAnn = AnnotationUtils.findAnnotation(handlerType, MessageMapping.class);
MessageMapping typeAnn = AnnotatedElementUtils.findMergedAnnotation(handlerType, MessageMapping.class);
// Only actually register it if there are destinations specified;
// otherwise @MessageMapping is just being used as a (meta-annotation) marker.
if (messageAnn.value().length > 0 || (typeAnn != null && typeAnn.value().length > 0)) {
@@ -379,9 +379,9 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan
}
}
SubscribeMapping subscribeAnn = AnnotationUtils.findAnnotation(method, SubscribeMapping.class);
SubscribeMapping subscribeAnn = AnnotatedElementUtils.findMergedAnnotation(method, SubscribeMapping.class);
if (subscribeAnn != null) {
MessageMapping typeAnn = AnnotationUtils.findAnnotation(handlerType, MessageMapping.class);
MessageMapping typeAnn = AnnotatedElementUtils.findMergedAnnotation(handlerType, MessageMapping.class);
// Only actually register it if there are destinations specified;
// otherwise @SubscribeMapping is just being used as a (meta-annotation) marker.
if (subscribeAnn.value().length > 0 || (typeAnn != null && typeAnn.value().length > 0)) {

View File

@@ -95,9 +95,9 @@ public class SubscriptionMethodReturnValueHandler implements HandlerMethodReturn
@Override
public boolean supportsReturnType(MethodParameter returnType) {
return (returnType.getMethodAnnotation(SubscribeMapping.class) != null &&
returnType.getMethodAnnotation(SendTo.class) == null &&
returnType.getMethodAnnotation(SendToUser.class) == null);
return (returnType.hasMethodAnnotation(SubscribeMapping.class) &&
!returnType.hasMethodAnnotation(SendTo.class) &&
!returnType.hasMethodAnnotation(SendToUser.class));
}
@Override