annotationType) {
+ return HandlerMethod.this.hasMethodAnnotation(annotationType);
+ }
+
@Override
public HandlerMethodParameter clone() {
return new HandlerMethodParameter(this);
diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java
index 1fe4a35533..d5299ce09f 100644
--- a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java
+++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java
@@ -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);
}
}
diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java
index 424e09c11d..f32f62af88 100644
--- a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java
+++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java
@@ -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)) {
diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SubscriptionMethodReturnValueHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SubscriptionMethodReturnValueHandler.java
index 05877c6f3b..e18af8df8b 100644
--- a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SubscriptionMethodReturnValueHandler.java
+++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SubscriptionMethodReturnValueHandler.java
@@ -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
diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandlerTests.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandlerTests.java
index 683ecd5963..af573a7df6 100644
--- a/spring-messaging/src/test/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandlerTests.java
+++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandlerTests.java
@@ -16,6 +16,8 @@
package org.springframework.messaging.simp.annotation.support;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
@@ -34,6 +36,7 @@ import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.core.MethodParameter;
+import org.springframework.core.annotation.AliasFor;
import org.springframework.core.annotation.SynthesizingMethodParameter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
@@ -52,7 +55,7 @@ import org.springframework.util.MimeType;
import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*;
-import static org.springframework.messaging.handler.DestinationPatternsMessageCondition.LOOKUP_DESTINATION_HEADER;
+import static org.springframework.messaging.handler.DestinationPatternsMessageCondition.*;
import static org.springframework.messaging.handler.annotation.support.DestinationVariableMethodArgumentResolver.*;
import static org.springframework.messaging.support.MessageHeaderAccessor.*;
@@ -110,31 +113,31 @@ public class SendToMethodReturnValueHandlerTests {
jsonMessagingTemplate.setMessageConverter(new MappingJackson2MessageConverter());
this.jsonHandler = new SendToMethodReturnValueHandler(jsonMessagingTemplate, true);
- Method method = this.getClass().getDeclaredMethod("handleNoAnnotations");
+ Method method = getClass().getDeclaredMethod("handleNoAnnotations");
this.noAnnotationsReturnType = new SynthesizingMethodParameter(method, -1);
- method = this.getClass().getDeclaredMethod("handleAndSendToDefaultDestination");
+ method = getClass().getDeclaredMethod("handleAndSendToDefaultDestination");
this.sendToDefaultDestReturnType = new SynthesizingMethodParameter(method, -1);
- method = this.getClass().getDeclaredMethod("handleAndSendTo");
+ method = getClass().getDeclaredMethod("handleAndSendTo");
this.sendToReturnType = new SynthesizingMethodParameter(method, -1);
- method = this.getClass().getDeclaredMethod("handleAndSendToWithPlaceholders");
+ method = getClass().getDeclaredMethod("handleAndSendToWithPlaceholders");
this.sendToWithPlaceholdersReturnType = new SynthesizingMethodParameter(method, -1);
- method = this.getClass().getDeclaredMethod("handleAndSendToUser");
+ method = getClass().getDeclaredMethod("handleAndSendToUser");
this.sendToUserReturnType = new SynthesizingMethodParameter(method, -1);
- method = this.getClass().getDeclaredMethod("handleAndSendToUserSingleSession");
+ method = getClass().getDeclaredMethod("handleAndSendToUserSingleSession");
this.sendToUserSingleSessionReturnType = new SynthesizingMethodParameter(method, -1);
- method = this.getClass().getDeclaredMethod("handleAndSendToUserDefaultDestination");
+ method = getClass().getDeclaredMethod("handleAndSendToUserDefaultDestination");
this.sendToUserDefaultDestReturnType = new SynthesizingMethodParameter(method, -1);
- method = this.getClass().getDeclaredMethod("handleAndSendToUserDefaultDestinationSingleSession");
+ method = getClass().getDeclaredMethod("handleAndSendToUserDefaultDestinationSingleSession");
this.sendToUserSingleSessionDefaultDestReturnType = new SynthesizingMethodParameter(method, -1);
- method = this.getClass().getDeclaredMethod("handleAndSendToJsonView");
+ method = getClass().getDeclaredMethod("handleAndSendToJsonView");
this.jsonViewReturnType = new SynthesizingMethodParameter(method, -1);
method = SendToTestBean.class.getDeclaredMethod("handleNoAnnotation");
@@ -287,6 +290,7 @@ public class SendToMethodReturnValueHandlerTests {
private void assertResponse(MethodParameter methodParameter, String sessionId,
int index, String destination) {
+
SimpMessageHeaderAccessor accessor = getCapturedAccessor(index);
assertEquals(sessionId, accessor.getSessionId());
assertEquals(destination, accessor.getDestination());
@@ -546,6 +550,23 @@ public class SendToMethodReturnValueHandlerTests {
}
}
+ @SendTo
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface MySendTo {
+
+ @AliasFor(annotation = SendTo.class, attribute = "value")
+ String[] dest();
+ }
+
+ @SendToUser
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface MySendToUser {
+
+ @AliasFor(annotation = SendToUser.class, attribute = "destinations")
+ String[] dest();
+ }
+
+
@SuppressWarnings("unused")
public String handleNoAnnotations() {
return PAYLOAD;
@@ -586,7 +607,6 @@ public class SendToMethodReturnValueHandlerTests {
return PAYLOAD;
}
- @SendTo("/dest")
@JsonView(MyJacksonView1.class) @SuppressWarnings("unused")
public JacksonViewBean handleAndSendToJsonView() {
JacksonViewBean payload = new JacksonViewBean();
@@ -596,7 +616,8 @@ public class SendToMethodReturnValueHandlerTests {
return payload;
}
- @SendTo("/dest-default") @SuppressWarnings("unused")
+
+ @MySendTo(dest = "/dest-default") @SuppressWarnings("unused")
private static class SendToTestBean {
public String handleNoAnnotation() {
@@ -608,14 +629,13 @@ public class SendToMethodReturnValueHandlerTests {
return PAYLOAD;
}
- @SendTo({"/dest3", "/dest4"})
+ @MySendTo(dest = {"/dest3", "/dest4"})
public String handleAndSendToOverride() {
return PAYLOAD;
}
-
}
- @SendToUser("/dest-default") @SuppressWarnings("unused")
+ @MySendToUser(dest = "/dest-default") @SuppressWarnings("unused")
private static class SendToUserTestBean {
public String handleNoAnnotation() {
@@ -627,11 +647,10 @@ public class SendToMethodReturnValueHandlerTests {
return PAYLOAD;
}
- @SendToUser({"/dest3", "/dest4"})
+ @MySendToUser(dest = {"/dest3", "/dest4"})
public String handleAndSendToOverride() {
return PAYLOAD;
}
-
}
diff --git a/spring-test/src/main/java/org/springframework/test/annotation/ProfileValueUtils.java b/spring-test/src/main/java/org/springframework/test/annotation/ProfileValueUtils.java
index 27ce7f640c..17c60cad01 100644
--- a/spring-test/src/main/java/org/springframework/test/annotation/ProfileValueUtils.java
+++ b/spring-test/src/main/java/org/springframework/test/annotation/ProfileValueUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2016 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,13 +21,12 @@ import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
-import static org.springframework.core.annotation.AnnotationUtils.*;
-
/**
* General utility methods for working with profile values.
*
@@ -49,12 +48,10 @@ public abstract class ProfileValueUtils {
* {@link ProfileValueSourceConfiguration
* @ProfileValueSourceConfiguration} annotation and instantiates a new
* instance of that type.
- *
- * If {@link ProfileValueSourceConfiguration
+ *
If {@link ProfileValueSourceConfiguration
* @ProfileValueSourceConfiguration} is not present on the specified
* class or if a custom {@link ProfileValueSource} is not declared, the
* default {@link SystemProfileValueSource} will be returned instead.
- *
* @param testClass The test class for which the ProfileValueSource should
* be retrieved
* @return the configured (or default) ProfileValueSource for the specified
@@ -66,10 +63,10 @@ public abstract class ProfileValueUtils {
Assert.notNull(testClass, "testClass must not be null");
Class annotationType = ProfileValueSourceConfiguration.class;
- ProfileValueSourceConfiguration config = findAnnotation(testClass, annotationType);
+ ProfileValueSourceConfiguration config = AnnotatedElementUtils.findMergedAnnotation(testClass, annotationType);
if (logger.isDebugEnabled()) {
- logger.debug("Retrieved @ProfileValueSourceConfiguration [" + config + "] for test class ["
- + testClass.getName() + "]");
+ logger.debug("Retrieved @ProfileValueSourceConfiguration [" + config + "] for test class [" +
+ testClass.getName() + "]");
}
Class extends ProfileValueSource> profileValueSourceType;
@@ -80,8 +77,8 @@ public abstract class ProfileValueUtils {
profileValueSourceType = (Class extends ProfileValueSource>) AnnotationUtils.getDefaultValue(annotationType);
}
if (logger.isDebugEnabled()) {
- logger.debug("Retrieved ProfileValueSource type [" + profileValueSourceType + "] for class ["
- + testClass.getName() + "]");
+ logger.debug("Retrieved ProfileValueSource type [" + profileValueSourceType + "] for class [" +
+ testClass.getName() + "]");
}
ProfileValueSource profileValueSource;
@@ -92,10 +89,10 @@ public abstract class ProfileValueUtils {
try {
profileValueSource = profileValueSourceType.newInstance();
}
- catch (Exception e) {
+ catch (Exception ex) {
if (logger.isWarnEnabled()) {
- logger.warn("Could not instantiate a ProfileValueSource of type [" + profileValueSourceType
- + "] for class [" + testClass.getName() + "]: using default.", e);
+ logger.warn("Could not instantiate a ProfileValueSource of type [" + profileValueSourceType +
+ "] for class [" + testClass.getName() + "]: using default.", ex);
}
profileValueSource = SystemProfileValueSource.getInstance();
}
@@ -108,16 +105,14 @@ public abstract class ProfileValueUtils {
* Determine if the supplied {@code testClass} is enabled in
* the current environment, as specified by the {@link IfProfileValue
* @IfProfileValue} annotation at the class level.
- *
- * Defaults to {@code true} if no {@link IfProfileValue
+ *
Defaults to {@code true} if no {@link IfProfileValue
* @IfProfileValue} annotation is declared.
- *
* @param testClass the test class
* @return {@code true} if the test is enabled in the current
* environment
*/
public static boolean isTestEnabledInThisEnvironment(Class> testClass) {
- IfProfileValue ifProfileValue = findAnnotation(testClass, IfProfileValue.class);
+ IfProfileValue ifProfileValue = AnnotatedElementUtils.findMergedAnnotation(testClass, IfProfileValue.class);
return isTestEnabledInThisEnvironment(retrieveProfileValueSource(testClass), ifProfileValue);
}
@@ -127,10 +122,8 @@ public abstract class ProfileValueUtils {
* @IfProfileValue} annotation, which may be declared on the test
* method itself or at the class level. Class-level usage overrides
* method-level usage.
- *
- * Defaults to {@code true} if no {@link IfProfileValue
+ *
Defaults to {@code true} if no {@link IfProfileValue
* @IfProfileValue} annotation is declared.
- *
* @param testMethod the test method
* @param testClass the test class
* @return {@code true} if the test is enabled in the current
@@ -146,10 +139,8 @@ public abstract class ProfileValueUtils {
* @IfProfileValue} annotation, which may be declared on the test
* method itself or at the class level. Class-level usage overrides
* method-level usage.
- *
- * Defaults to {@code true} if no {@link IfProfileValue
+ *
Defaults to {@code true} if no {@link IfProfileValue
* @IfProfileValue} annotation is declared.
- *
* @param profileValueSource the ProfileValueSource to use to determine if
* the test is enabled
* @param testMethod the test method
@@ -160,11 +151,11 @@ public abstract class ProfileValueUtils {
public static boolean isTestEnabledInThisEnvironment(ProfileValueSource profileValueSource, Method testMethod,
Class> testClass) {
- IfProfileValue ifProfileValue = findAnnotation(testClass, IfProfileValue.class);
+ IfProfileValue ifProfileValue = AnnotatedElementUtils.findMergedAnnotation(testClass, IfProfileValue.class);
boolean classLevelEnabled = isTestEnabledInThisEnvironment(profileValueSource, ifProfileValue);
if (classLevelEnabled) {
- ifProfileValue = findAnnotation(testMethod, IfProfileValue.class);
+ ifProfileValue = AnnotatedElementUtils.findMergedAnnotation(testMethod, IfProfileValue.class);
return isTestEnabledInThisEnvironment(profileValueSource, ifProfileValue);
}
@@ -175,7 +166,6 @@ public abstract class ProfileValueUtils {
* Determine if the {@code value} (or one of the {@code values})
* in the supplied {@link IfProfileValue @IfProfileValue} annotation is
* enabled in the current environment.
- *
* @param profileValueSource the ProfileValueSource to use to determine if
* the test is enabled
* @param ifProfileValue the annotation to introspect; may be
@@ -195,8 +185,8 @@ public abstract class ProfileValueUtils {
String[] annotatedValues = ifProfileValue.values();
if (StringUtils.hasLength(ifProfileValue.value())) {
if (annotatedValues.length > 0) {
- throw new IllegalArgumentException("Setting both the 'value' and 'values' attributes "
- + "of @IfProfileValue is not allowed: choose one or the other.");
+ throw new IllegalArgumentException("Setting both the 'value' and 'values' attributes " +
+ "of @IfProfileValue is not allowed: choose one or the other.");
}
annotatedValues = new String[] { ifProfileValue.value() };
}
diff --git a/spring-test/src/main/java/org/springframework/test/annotation/TestAnnotationUtils.java b/spring-test/src/main/java/org/springframework/test/annotation/TestAnnotationUtils.java
index 5f4eb1c247..a2b33faa51 100644
--- a/spring-test/src/main/java/org/springframework/test/annotation/TestAnnotationUtils.java
+++ b/spring-test/src/main/java/org/springframework/test/annotation/TestAnnotationUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -19,7 +19,6 @@ package org.springframework.test.annotation;
import java.lang.reflect.Method;
import org.springframework.core.annotation.AnnotatedElementUtils;
-import org.springframework.core.annotation.AnnotationUtils;
/**
* Collection of utility methods for working with Spring's core testing annotations.
@@ -52,7 +51,7 @@ public class TestAnnotationUtils {
* not annotated with {@code @Repeat}
*/
public static int getRepeatCount(Method method) {
- Repeat repeat = AnnotationUtils.findAnnotation(method, Repeat.class);
+ Repeat repeat = AnnotatedElementUtils.findMergedAnnotation(method, Repeat.class);
if (repeat == null) {
return 1;
}
diff --git a/spring-test/src/main/java/org/springframework/test/context/junit4/statements/ProfileValueChecker.java b/spring-test/src/main/java/org/springframework/test/context/junit4/statements/ProfileValueChecker.java
index e2b5195ae0..5d53bbff71 100644
--- a/spring-test/src/main/java/org/springframework/test/context/junit4/statements/ProfileValueChecker.java
+++ b/spring-test/src/main/java/org/springframework/test/context/junit4/statements/ProfileValueChecker.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -22,7 +22,7 @@ import java.lang.reflect.Method;
import org.junit.AssumptionViolatedException;
import org.junit.runners.model.Statement;
-import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.test.annotation.IfProfileValue;
import org.springframework.test.annotation.ProfileValueUtils;
import org.springframework.util.Assert;
@@ -64,6 +64,7 @@ public class ProfileValueChecker extends Statement {
this.testMethod = testMethod;
}
+
/**
* Determine if the test specified by arguments to the
* {@linkplain #ProfileValueChecker constructor} is enabled in
@@ -83,17 +84,17 @@ public class ProfileValueChecker extends Statement {
public void evaluate() throws Throwable {
if (this.testMethod == null) {
if (!ProfileValueUtils.isTestEnabledInThisEnvironment(this.testClass)) {
- Annotation ann = AnnotationUtils.findAnnotation(this.testClass, IfProfileValue.class);
- throw new AssumptionViolatedException(
- String.format("Profile configured via [%s] is not enabled in this environment for test class [%s].",
+ Annotation ann = AnnotatedElementUtils.findMergedAnnotation(this.testClass, IfProfileValue.class);
+ throw new AssumptionViolatedException(String.format(
+ "Profile configured via [%s] is not enabled in this environment for test class [%s].",
ann, this.testClass.getName()));
}
}
else {
if (!ProfileValueUtils.isTestEnabledInThisEnvironment(this.testMethod, this.testClass)) {
throw new AssumptionViolatedException(String.format(
- "Profile configured via @IfProfileValue is not enabled in this environment for test method [%s].",
- this.testMethod));
+ "Profile configured via @IfProfileValue is not enabled in this environment for test method [%s].",
+ this.testMethod));
}
}
diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java b/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java
index 51bbee68da..8fa0040e1a 100644
--- a/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java
+++ b/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java
@@ -31,8 +31,8 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanInstantiationException;
import org.springframework.beans.BeanUtils;
+import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
-import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.test.context.BootstrapContext;
import org.springframework.test.context.CacheAwareContextLoaderDelegate;
@@ -278,7 +278,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
return buildDefaultMergedContextConfiguration(testClass, cacheAwareContextLoaderDelegate);
}
- if (AnnotationUtils.findAnnotation(testClass, ContextHierarchy.class) != null) {
+ if (AnnotatedElementUtils.findMergedAnnotation(testClass, ContextHierarchy.class) != null) {
Map> hierarchyMap = ContextLoaderUtils.buildContextHierarchyMap(testClass);
MergedContextConfiguration parentConfig = null;
MergedContextConfiguration mergedConfig = null;
diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoaderUtils.java b/spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoaderUtils.java
index baa15001b2..968d2300e8 100644
--- a/spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoaderUtils.java
+++ b/spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoaderUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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 org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.annotation.Configuration;
-import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.test.context.SmartContextLoader;
import org.springframework.util.Assert;
@@ -103,7 +103,7 @@ public abstract class AnnotationConfigContextLoaderUtils {
*/
private static boolean isDefaultConfigurationClassCandidate(Class> clazz) {
return (clazz != null && isStaticNonPrivateAndNonFinal(clazz) &&
- (AnnotationUtils.findAnnotation(clazz, Configuration.class) != null));
+ AnnotatedElementUtils.hasAnnotation(clazz, Configuration.class));
}
private static boolean isStaticNonPrivateAndNonFinal(Class> clazz) {
diff --git a/spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java b/spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java
index da3383cb37..fb3aab8502 100644
--- a/spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java
+++ b/spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -95,11 +95,10 @@ abstract class ContextLoaderUtils {
@SuppressWarnings("unchecked")
static List> resolveContextHierarchyAttributes(Class> testClass) {
Assert.notNull(testClass, "Class must not be null");
- Assert.state(findAnnotation(testClass, ContextHierarchy.class) != null, "@ContextHierarchy must be present");
- final Class contextConfigType = ContextConfiguration.class;
- final Class contextHierarchyType = ContextHierarchy.class;
- final List> hierarchyAttributes = new ArrayList>();
+ Class contextConfigType = ContextConfiguration.class;
+ Class contextHierarchyType = ContextHierarchy.class;
+ List> hierarchyAttributes = new ArrayList>();
UntypedAnnotationDescriptor desc =
findAnnotationDescriptorForTypes(testClass, contextConfigType, contextHierarchyType);
@@ -124,7 +123,7 @@ abstract class ContextLoaderUtils {
throw new IllegalStateException(msg);
}
- final List configAttributesList = new ArrayList();
+ List configAttributesList = new ArrayList();
if (contextConfigDeclaredLocally) {
ContextConfiguration contextConfiguration = AnnotationUtils.synthesizeAnnotation(
diff --git a/spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java
index 668717a701..d81f1ddaa4 100644
--- a/spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java
+++ b/spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java
@@ -30,6 +30,7 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.test.annotation.Commit;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.TestContext;
@@ -44,9 +45,6 @@ import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
-import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
-import static org.springframework.core.annotation.AnnotationUtils.getAnnotation;
-
/**
* {@code TestExecutionListener} that provides support for executing tests
* within test-managed transactions by honoring Spring's
@@ -181,8 +179,8 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
transactionAttribute);
if (logger.isDebugEnabled()) {
- logger.debug("Explicit transaction definition [" + transactionAttribute + "] found for test context "
- + testContext);
+ logger.debug("Explicit transaction definition [" + transactionAttribute + "] found for test context " +
+ testContext);
}
if (transactionAttribute.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
@@ -193,8 +191,8 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
if (tm == null) {
throw new IllegalStateException(String.format(
- "Failed to retrieve PlatformTransactionManager for @Transactional test for test context %s.",
- testContext));
+ "Failed to retrieve PlatformTransactionManager for @Transactional test for test context %s.",
+ testContext));
}
}
@@ -255,8 +253,10 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
}
}
catch (InvocationTargetException ex) {
- logger.error("Exception encountered while executing @BeforeTransaction methods for test context "
- + testContext + ".", ex.getTargetException());
+ if (logger.isErrorEnabled()) {
+ logger.error("Exception encountered while executing @BeforeTransaction methods for test context " +
+ testContext + ".", ex.getTargetException());
+ }
ReflectionUtils.rethrowException(ex.getTargetException());
}
}
@@ -286,15 +286,15 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
if (afterTransactionException == null) {
afterTransactionException = targetException;
}
- logger.error("Exception encountered while executing @AfterTransaction method [" + method
- + "] for test context " + testContext, targetException);
+ logger.error("Exception encountered while executing @AfterTransaction method [" + method +
+ "] for test context " + testContext, targetException);
}
catch (Exception ex) {
if (afterTransactionException == null) {
afterTransactionException = ex;
}
- logger.error("Exception encountered while executing @AfterTransaction method [" + method
- + "] for test context " + testContext, ex);
+ logger.error("Exception encountered while executing @AfterTransaction method [" + method +
+ "] for test context " + testContext, ex);
}
}
@@ -317,20 +317,18 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
* @see #getTransactionManager(TestContext)
*/
protected PlatformTransactionManager getTransactionManager(TestContext testContext, String qualifier) {
- // look up by type and qualifier from @Transactional
+ // Look up by type and qualifier from @Transactional
if (StringUtils.hasText(qualifier)) {
try {
- // Use autowire-capable factory in order to support extended qualifier
- // matching (only exposed on the internal BeanFactory, not on the
- // ApplicationContext).
+ // Use autowire-capable factory in order to support extended qualifier matching
+ // (only exposed on the internal BeanFactory, not on the ApplicationContext).
BeanFactory bf = testContext.getApplicationContext().getAutowireCapableBeanFactory();
return BeanFactoryAnnotationUtils.qualifiedBeanOfType(bf, PlatformTransactionManager.class, qualifier);
}
catch (RuntimeException ex) {
if (logger.isWarnEnabled()) {
- logger.warn(
- String.format(
+ logger.warn(String.format(
"Caught exception while retrieving transaction manager with qualifier '%s' for test context %s",
qualifier, testContext), ex);
}
@@ -376,7 +374,7 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
@SuppressWarnings("deprecation")
protected final boolean isDefaultRollback(TestContext testContext) throws Exception {
Class> testClass = testContext.getTestClass();
- Rollback rollback = findAnnotation(testClass, Rollback.class);
+ Rollback rollback = AnnotatedElementUtils.findMergedAnnotation(testClass, Rollback.class);
boolean rollbackPresent = (rollback != null);
TransactionConfigurationAttributes txConfigAttributes = retrieveConfigurationAttributes(testContext);
@@ -411,21 +409,22 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
*/
protected final boolean isRollback(TestContext testContext) throws Exception {
boolean rollback = isDefaultRollback(testContext);
- Rollback rollbackAnnotation = findAnnotation(testContext.getTestMethod(), Rollback.class);
+ Rollback rollbackAnnotation =
+ AnnotatedElementUtils.findMergedAnnotation(testContext.getTestMethod(), Rollback.class);
if (rollbackAnnotation != null) {
boolean rollbackOverride = rollbackAnnotation.value();
if (logger.isDebugEnabled()) {
logger.debug(String.format(
- "Method-level @Rollback(%s) overrides default rollback [%s] for test context %s.",
- rollbackOverride, rollback, testContext));
+ "Method-level @Rollback(%s) overrides default rollback [%s] for test context %s.",
+ rollbackOverride, rollback, testContext));
}
rollback = rollbackOverride;
}
else {
if (logger.isDebugEnabled()) {
logger.debug(String.format(
- "No method-level @Rollback override: using default rollback [%s] for test context %s.", rollback,
- testContext));
+ "No method-level @Rollback override: using default rollback [%s] for test context %s.",
+ rollback, testContext));
}
}
return rollback;
@@ -466,7 +465,7 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
List results = new ArrayList();
for (Class> current : getSuperClasses(clazz)) {
for (Method method : current.getDeclaredMethods()) {
- Annotation annotation = getAnnotation(method, annotationType);
+ Annotation annotation = AnnotationUtils.getAnnotation(method, annotationType);
if (annotation != null && !isShadowed(method, results)) {
results.add(method);
}
@@ -537,19 +536,18 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
if (this.configurationAttributes == null) {
Class> clazz = testContext.getTestClass();
- TransactionConfiguration txConfig = AnnotatedElementUtils.findMergedAnnotation(clazz,
- TransactionConfiguration.class);
+ TransactionConfiguration txConfig =
+ AnnotatedElementUtils.findMergedAnnotation(clazz, TransactionConfiguration.class);
if (logger.isDebugEnabled()) {
logger.debug(String.format("Retrieved @TransactionConfiguration [%s] for test class [%s].",
- txConfig, clazz.getName()));
+ txConfig, clazz.getName()));
}
- TransactionConfigurationAttributes configAttributes = (txConfig == null ? defaultTxConfigAttributes
- : new TransactionConfigurationAttributes(txConfig.transactionManager(), txConfig.defaultRollback()));
-
+ TransactionConfigurationAttributes configAttributes = (txConfig == null ? defaultTxConfigAttributes :
+ new TransactionConfigurationAttributes(txConfig.transactionManager(), txConfig.defaultRollback()));
if (logger.isDebugEnabled()) {
logger.debug(String.format("Using TransactionConfigurationAttributes %s for test class [%s].",
- configAttributes, clazz.getName()));
+ configAttributes, clazz.getName()));
}
this.configurationAttributes = configAttributes;
}
diff --git a/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java
index 9585552bc3..170b617422 100644
--- a/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java
+++ b/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java
@@ -25,7 +25,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.Conventions;
-import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
@@ -33,7 +33,6 @@ import org.springframework.test.context.TestContext;
import org.springframework.test.context.TestExecutionListener;
import org.springframework.test.context.support.AbstractTestExecutionListener;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
-import org.springframework.util.Assert;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
@@ -58,7 +57,7 @@ import org.springframework.web.context.request.ServletWebRequest;
* Note that {@code ServletTestExecutionListener} is enabled by default but
* generally takes no action if the {@linkplain TestContext#getTestClass() test
* class} is not annotated with {@link WebAppConfiguration @WebAppConfiguration}.
- * See the Javadoc for individual methods in this class for details.
+ * See the javadocs for individual methods in this class for details.
*
* @author Sam Brannen
* @author Phillip Webb
@@ -71,45 +70,41 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
* whether or not the {@code ServletTestExecutionListener} should {@linkplain
* RequestContextHolder#resetRequestAttributes() reset} Spring Web's
* {@code RequestContextHolder} in {@link #afterTestMethod(TestContext)}.
- *
*
Permissible values include {@link Boolean#TRUE} and {@link Boolean#FALSE}.
*/
public static final String RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE = Conventions.getQualifiedAttributeName(
- ServletTestExecutionListener.class, "resetRequestContextHolder");
+ ServletTestExecutionListener.class, "resetRequestContextHolder");
/**
* Attribute name for a {@link TestContext} attribute which indicates that
* {@code ServletTestExecutionListener} has already populated Spring Web's
* {@code RequestContextHolder}.
- *
*
Permissible values include {@link Boolean#TRUE} and {@link Boolean#FALSE}.
*/
public static final String POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE = Conventions.getQualifiedAttributeName(
- ServletTestExecutionListener.class, "populatedRequestContextHolder");
+ ServletTestExecutionListener.class, "populatedRequestContextHolder");
/**
* Attribute name for a request attribute which indicates that the
* {@link MockHttpServletRequest} stored in the {@link RequestAttributes}
* in Spring Web's {@link RequestContextHolder} was created by the TestContext
* framework.
- *
*
Permissible values include {@link Boolean#TRUE} and {@link Boolean#FALSE}.
* @since 4.2
*/
public static final String CREATED_BY_THE_TESTCONTEXT_FRAMEWORK = Conventions.getQualifiedAttributeName(
- ServletTestExecutionListener.class, "createdByTheTestContextFramework");
+ ServletTestExecutionListener.class, "createdByTheTestContextFramework");
/**
* Attribute name for a {@link TestContext} attribute which indicates that that
* the {@code ServletTestExecutionListener} should be activated. When not set to
* {@code true}, activation occurs when the {@linkplain TestContext#getTestClass()
* test class} is annotated with {@link WebAppConfiguration @WebAppConfiguration}.
- *
*
Permissible values include {@link Boolean#TRUE} and {@link Boolean#FALSE}.
* @since 4.3
*/
public static final String ACTIVATE_LISTENER = Conventions.getQualifiedAttributeName(
- ServletTestExecutionListener.class, "activateListener");
+ ServletTestExecutionListener.class, "activateListener");
private static final Log logger = LogFactory.getLog(ServletTestExecutionListener.class);
@@ -181,8 +176,8 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
}
private boolean isActivated(TestContext testContext) {
- return (Boolean.TRUE.equals(testContext.getAttribute(ACTIVATE_LISTENER))
- || AnnotationUtils.findAnnotation(testContext.getTestClass(), WebAppConfiguration.class) != null);
+ return (Boolean.TRUE.equals(testContext.getAttribute(ACTIVATE_LISTENER)) ||
+ AnnotatedElementUtils.hasAnnotation(testContext.getTestClass(), WebAppConfiguration.class));
}
private boolean alreadyPopulatedRequestContextHolder(TestContext testContext) {
@@ -199,14 +194,16 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
if (context instanceof WebApplicationContext) {
WebApplicationContext wac = (WebApplicationContext) context;
ServletContext servletContext = wac.getServletContext();
- Assert.state(servletContext instanceof MockServletContext, String.format(
- "The WebApplicationContext for test context %s must be configured with a MockServletContext.",
- testContext));
+ if (!(servletContext instanceof MockServletContext)) {
+ throw new IllegalStateException(String.format(
+ "The WebApplicationContext for test context %s must be configured with a MockServletContext.",
+ testContext));
+ }
if (logger.isDebugEnabled()) {
logger.debug(String.format(
- "Setting up MockHttpServletRequest, MockHttpServletResponse, ServletWebRequest, and RequestContextHolder for test context %s.",
- testContext));
+ "Setting up MockHttpServletRequest, MockHttpServletResponse, ServletWebRequest, and RequestContextHolder for test context %s.",
+ testContext));
}
MockServletContext mockServletContext = (MockServletContext) servletContext;
diff --git a/spring-test/src/main/java/org/springframework/test/context/web/WebTestContextBootstrapper.java b/spring-test/src/main/java/org/springframework/test/context/web/WebTestContextBootstrapper.java
index 94741f5aec..f779450c48 100644
--- a/spring-test/src/main/java/org/springframework/test/context/web/WebTestContextBootstrapper.java
+++ b/spring-test/src/main/java/org/springframework/test/context/web/WebTestContextBootstrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2014 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -16,7 +16,7 @@
package org.springframework.test.context.web;
-import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.test.context.ContextLoader;
import org.springframework.test.context.MergedContextConfiguration;
import org.springframework.test.context.TestContextBootstrapper;
@@ -45,12 +45,12 @@ public class WebTestContextBootstrapper extends DefaultTestContextBootstrapper {
*/
@Override
protected Class extends ContextLoader> getDefaultContextLoaderClass(Class> testClass) {
- if (AnnotationUtils.findAnnotation(testClass, WebAppConfiguration.class) != null) {
+ if (AnnotatedElementUtils.findMergedAnnotation(testClass, WebAppConfiguration.class) != null) {
return WebDelegatingSmartContextLoader.class;
}
-
- // else...
- return super.getDefaultContextLoaderClass(testClass);
+ else {
+ return super.getDefaultContextLoaderClass(testClass);
+ }
}
/**
@@ -61,14 +61,14 @@ public class WebTestContextBootstrapper extends DefaultTestContextBootstrapper {
*/
@Override
protected MergedContextConfiguration processMergedContextConfiguration(MergedContextConfiguration mergedConfig) {
- WebAppConfiguration webAppConfiguration = AnnotationUtils.findAnnotation(mergedConfig.getTestClass(),
- WebAppConfiguration.class);
+ WebAppConfiguration webAppConfiguration =
+ AnnotatedElementUtils.findMergedAnnotation(mergedConfig.getTestClass(), WebAppConfiguration.class);
if (webAppConfiguration != null) {
return new WebMergedContextConfiguration(mergedConfig, webAppConfiguration.value());
}
-
- // else...
- return mergedConfig;
+ else {
+ return mergedConfig;
+ }
}
}
diff --git a/spring-test/src/test/java/org/springframework/test/context/support/ContextLoaderUtilsContextHierarchyTests.java b/spring-test/src/test/java/org/springframework/test/context/support/ContextLoaderUtilsContextHierarchyTests.java
index 3faab20416..810910c993 100644
--- a/spring-test/src/test/java/org/springframework/test/context/support/ContextLoaderUtilsContextHierarchyTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/support/ContextLoaderUtilsContextHierarchyTests.java
@@ -22,6 +22,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import org.junit.Ignore;
import org.junit.Test;
import org.springframework.context.ApplicationContextInitializer;
@@ -60,6 +61,7 @@ public class ContextLoaderUtilsContextHierarchyTests extends AbstractContextConf
}
@Test(expected = IllegalStateException.class)
+ @Ignore // an upfront findAnnotation check just for an assertion seems too expensive
public void resolveContextHierarchyAttributesForSingleTestClassWithImplicitSingleLevelContextHierarchy() {
resolveContextHierarchyAttributes(BareAnnotations.class);
}
diff --git a/spring-tx/src/main/java/org/springframework/transaction/event/ApplicationListenerMethodTransactionalAdapter.java b/spring-tx/src/main/java/org/springframework/transaction/event/ApplicationListenerMethodTransactionalAdapter.java
index 6228d01cb9..23db045521 100644
--- a/spring-tx/src/main/java/org/springframework/transaction/event/ApplicationListenerMethodTransactionalAdapter.java
+++ b/spring-tx/src/main/java/org/springframework/transaction/event/ApplicationListenerMethodTransactionalAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -54,7 +54,10 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM
public ApplicationListenerMethodTransactionalAdapter(String beanName, Class> targetClass, Method method) {
super(beanName, targetClass, method);
- this.annotation = findAnnotation(method);
+ this.annotation = AnnotatedElementUtils.findMergedAnnotation(method, TransactionalEventListener.class);
+ if (this.annotation == null) {
+ throw new IllegalStateException("No TransactionalEventListener annotation found on '" + method + "'");
+ }
}
@@ -81,14 +84,6 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM
return new TransactionSynchronizationEventAdapter(this, event, this.annotation.phase());
}
- static TransactionalEventListener findAnnotation(Method method) {
- TransactionalEventListener annotation =
- AnnotatedElementUtils.findMergedAnnotation(method, TransactionalEventListener.class);
- if (annotation == null) {
- throw new IllegalStateException("No TransactionalEventListener annotation found on '" + method + "'");
- }
- return annotation;
- }
private static class TransactionSynchronizationEventAdapter extends TransactionSynchronizationAdapter {
diff --git a/spring-tx/src/test/java/org/springframework/transaction/event/ApplicationListenerMethodTransactionalAdapterTests.java b/spring-tx/src/test/java/org/springframework/transaction/event/ApplicationListenerMethodTransactionalAdapterTests.java
index 901398f3d4..5ed470b904 100644
--- a/spring-tx/src/test/java/org/springframework/transaction/event/ApplicationListenerMethodTransactionalAdapterTests.java
+++ b/spring-tx/src/test/java/org/springframework/transaction/event/ApplicationListenerMethodTransactionalAdapterTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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,6 +25,7 @@ import org.junit.rules.ExpectedException;
import org.springframework.context.PayloadApplicationEvent;
import org.springframework.context.event.ApplicationListenerMethodAdapter;
import org.springframework.core.ResolvableType;
+import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.util.ReflectionUtils;
import static org.junit.Assert.*;
@@ -37,15 +38,6 @@ public class ApplicationListenerMethodTransactionalAdapterTests {
@Rule
public final ExpectedException thrown = ExpectedException.none();
- @Test
- public void noAnnotation() {
- Method m = ReflectionUtils.findMethod(SampleEvents.class,
- "noAnnotation", String.class);
-
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("noAnnotation");
- ApplicationListenerMethodTransactionalAdapter.findAnnotation(m);
- }
@Test
public void defaultPhase() {
@@ -78,7 +70,8 @@ public class ApplicationListenerMethodTransactionalAdapterTests {
private void assertPhase(Method method, TransactionPhase expected) {
assertNotNull("Method must not be null", method);
- TransactionalEventListener annotation = ApplicationListenerMethodTransactionalAdapter.findAnnotation(method);
+ TransactionalEventListener annotation =
+ AnnotatedElementUtils.findMergedAnnotation(method, TransactionalEventListener.class);
assertEquals("Wrong phase for '" + method + "'", expected, annotation.phase());
}
@@ -96,10 +89,8 @@ public class ApplicationListenerMethodTransactionalAdapterTests {
return ResolvableType.forClassWithGenerics(PayloadApplicationEvent.class, payloadType);
}
- static class SampleEvents {
- public void noAnnotation(String data) {
- }
+ static class SampleEvents {
@TransactionalEventListener
public void defaultPhase(String data) {
@@ -117,7 +108,6 @@ public class ApplicationListenerMethodTransactionalAdapterTests {
@TransactionalEventListener(String.class)
public void valueSet() {
}
-
}
}
diff --git a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java
index 3ddde8915a..74f99557d8 100644
--- a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java
+++ b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java
@@ -226,7 +226,7 @@ public class HandlerMethod {
* if no annotation can be found on the given method itself.
*
Also supports merged composed annotations with attribute
* overrides as of Spring Framework 4.2.2.
- * @param annotationType the type of annotation to introspect the method for.
+ * @param annotationType the type of annotation to introspect the method for
* @return the annotation, or {@code null} if none found
* @see AnnotatedElementUtils#findMergedAnnotation
*/
@@ -234,6 +234,16 @@ public class HandlerMethod {
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 boolean hasMethodAnnotation(Class annotationType) {
+ return AnnotatedElementUtils.hasAnnotation(this.method, annotationType);
+ }
+
/**
* If the provided instance contains a bean name rather than an object instance,
* the bean name is resolved before a {@link HandlerMethod} is created and returned.
@@ -247,6 +257,15 @@ public class HandlerMethod {
return new HandlerMethod(this, handler);
}
+ /**
+ * Return a short representation of this handler method for log message purposes.
+ * @since 4.3
+ */
+ public String getShortLogMessage() {
+ int args = this.method.getParameterTypes().length;
+ return getBeanType().getName() + "#" + this.method.getName() + "[" + args + " args]";
+ }
+
@Override
public boolean equals(Object other) {
@@ -294,6 +313,11 @@ public class HandlerMethod {
return HandlerMethod.this.getMethodAnnotation(annotationType);
}
+ @Override
+ public boolean hasMethodAnnotation(Class annotationType) {
+ return HandlerMethod.this.hasMethodAnnotation(annotationType);
+ }
+
@Override
public HandlerMethodParameter clone() {
return new HandlerMethodParameter(this);
diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessor.java b/spring-web/src/main/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessor.java
index d7b9e43f6f..81030d3bf2 100644
--- a/spring-web/src/main/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessor.java
+++ b/spring-web/src/main/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessor.java
@@ -102,8 +102,8 @@ public class ModelAttributeMethodProcessor
createAttribute(name, parameter, binderFactory, webRequest));
if (!mavContainer.isBindingDisabled(name)) {
- ModelAttribute annotation = parameter.getParameterAnnotation(ModelAttribute.class);
- if (annotation != null && !annotation.binding()) {
+ ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);
+ if (ann != null && !ann.binding()) {
mavContainer.setBindingDisabled(name);
}
}
@@ -192,8 +192,8 @@ public class ModelAttributeMethodProcessor
*/
@Override
public boolean supportsReturnType(MethodParameter returnType) {
- return (returnType.getMethodAnnotation(ModelAttribute.class) != null ||
- this.annotationNotRequired && !BeanUtils.isSimpleProperty(returnType.getParameterType()));
+ return (returnType.hasMethodAnnotation(ModelAttribute.class) ||
+ (this.annotationNotRequired && !BeanUtils.isSimpleProperty(returnType.getParameterType())));
}
/**
diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java b/spring-web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java
index 3ff2b31540..8cc07e465d 100644
--- a/spring-web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java
+++ b/spring-web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionAttributeStore;
@@ -65,10 +65,11 @@ public class SessionAttributesHandler {
* @param sessionAttributeStore used for session access
*/
public SessionAttributesHandler(Class> handlerType, SessionAttributeStore sessionAttributeStore) {
- Assert.notNull(sessionAttributeStore, "SessionAttributeStore may not be null.");
+ Assert.notNull(sessionAttributeStore, "SessionAttributeStore may not be null");
this.sessionAttributeStore = sessionAttributeStore;
- SessionAttributes annotation = AnnotationUtils.findAnnotation(handlerType, SessionAttributes.class);
+ SessionAttributes annotation =
+ AnnotatedElementUtils.findMergedAnnotation(handlerType, SessionAttributes.class);
if (annotation != null) {
this.attributeNames.addAll(Arrays.asList(annotation.names()));
this.attributeTypes.addAll(Arrays.asList(annotation.types()));
@@ -84,7 +85,7 @@ public class SessionAttributesHandler {
* session attributes through an {@link SessionAttributes} annotation.
*/
public boolean hasSessionAttributes() {
- return ((this.attributeNames.size() > 0) || (this.attributeTypes.size() > 0));
+ return (this.attributeNames.size() > 0 || this.attributeTypes.size() > 0);
}
/**
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/JsonViewResponseBodyAdvice.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/JsonViewResponseBodyAdvice.java
index 3ed6bb8f9c..2cb56bc2d3 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/JsonViewResponseBodyAdvice.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/JsonViewResponseBodyAdvice.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -47,7 +47,7 @@ public class JsonViewResponseBodyAdvice extends AbstractMappingJacksonResponseBo
@Override
public boolean supports(MethodParameter returnType, Class extends HttpMessageConverter>> converterType) {
- return (super.supports(returnType, converterType) && returnType.getMethodAnnotation(JsonView.class) != null);
+ return super.supports(returnType, converterType) && returnType.hasMethodAnnotation(JsonView.class);
}
@Override
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java
index d74a1bbc35..dc03d03747 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java
@@ -23,7 +23,6 @@ import java.util.List;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.core.annotation.AnnotatedElementUtils;
-import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -168,8 +167,8 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
*/
@Override
protected boolean isHandler(Class> beanType) {
- return ((AnnotationUtils.findAnnotation(beanType, Controller.class) != null) ||
- (AnnotationUtils.findAnnotation(beanType, RequestMapping.class) != null));
+ return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
+ AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
/**
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java
index 5780b2d11c..9e82398f1c 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java
@@ -23,7 +23,7 @@ import javax.servlet.http.HttpServletRequest;
import org.springframework.core.Conventions;
import org.springframework.core.MethodParameter;
-import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRange;
@@ -114,8 +114,8 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter
@Override
public boolean supportsReturnType(MethodParameter returnType) {
- return (AnnotationUtils.findAnnotation(returnType.getContainingClass(), ResponseBody.class) != null ||
- returnType.getMethodAnnotation(ResponseBody.class) != null);
+ return (AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) ||
+ returnType.hasMethodAnnotation(ResponseBody.class));
}
/**
@@ -173,14 +173,15 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter
ServletServerHttpRequest inputMessage = createInputMessage(webRequest);
ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);
- if(inputMessage.getHeaders().containsKey(HttpHeaders.RANGE) &&
+ if (inputMessage.getHeaders().containsKey(HttpHeaders.RANGE) &&
Resource.class.isAssignableFrom(returnValue.getClass())) {
try {
List httpRanges = inputMessage.getHeaders().getRange();
Resource bodyResource = (Resource) returnValue;
returnValue = new HttpRangeResource(httpRanges, bodyResource);
outputMessage.setStatusCode(HttpStatus.PARTIAL_CONTENT);
- } catch (IllegalArgumentException exc) {
+ }
+ catch (IllegalArgumentException ex) {
outputMessage.setStatusCode(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE);
outputMessage.flush();
return;
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java
index 3eb84cbe6a..362e74961f 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java
@@ -242,6 +242,14 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
public A getMethodAnnotation(Class annotationType) {
return ServletInvocableHandlerMethod.this.getMethodAnnotation(annotationType);
}
+
+ /**
+ * Bridge to controller method-level annotations.
+ */
+ @Override
+ public boolean hasMethodAnnotation(Class annotationType) {
+ return ServletInvocableHandlerMethod.this.hasMethodAnnotation(annotationType);
+ }
}