Browse Source

Introduce getAnnotation() in AnnotatedElementUtils

This commit introduces a "synthesized annotation" alternative to
getAnnotationAttributes() in AnnotatedElementUtils, analogous to the
recently introduced findAnnotation() methods.

Issue: SPR-13082
pull/811/head
Sam Brannen 10 years ago
parent
commit
9f717871e6
  1. 32
      spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java
  2. 4
      spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java
  3. 13
      spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java

32
spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java

@ -218,6 +218,32 @@ public class AnnotatedElementUtils { @@ -218,6 +218,32 @@ public class AnnotatedElementUtils {
}));
}
/**
* Get the first annotation of the specified {@code annotationType} within
* the annotation hierarchy <em>above</em> the supplied {@code element},
* merge that annotation's attributes with <em>matching</em> attributes from
* annotations in lower levels of the annotation hierarchy, and synthesize
* the result back into an annotation of the specified {@code annotationType}.
*
* <p>{@link AliasFor @AliasFor} semantics are fully supported, both
* within a single annotation and within the annotation hierarchy.
*
* <p>This method delegates to {@link #getAnnotationAttributes(AnnotatedElement, Class)}
* and {@link AnnotationUtils#synthesizeAnnotation(Map, Class, AnnotatedElement)}.
*
* @param element the annotated element; never {@code null}
* @param annotationType the annotation type to find; never {@code null}
* @return the merged {@code AnnotationAttributes}, or {@code null} if not found
* @since 4.2
* @see #getAnnotationAttributes(AnnotatedElement, Class)
* @see #findAnnotation(AnnotatedElement, Class)
* @see AnnotationUtils#synthesizeAnnotation(Map, Class, AnnotatedElement)
*/
public static <A extends Annotation> A getAnnotation(AnnotatedElement element, Class<A> annotationType) {
AnnotationAttributes attributes = getAnnotationAttributes(element, annotationType);
return ((attributes != null) ? AnnotationUtils.synthesizeAnnotation(attributes, annotationType, element) : null);
}
/**
* Get the first annotation of the specified {@code annotationType} within
* the annotation hierarchy <em>above</em> the supplied {@code element} and
@ -232,9 +258,10 @@ public class AnnotatedElementUtils { @@ -232,9 +258,10 @@ public class AnnotatedElementUtils {
* @param element the annotated element; never {@code null}
* @param annotationType the annotation type to find; never {@code null}
* @return the merged {@code AnnotationAttributes}, or {@code null} if not found
* @since 4.2
* @see #getAnnotationAttributes(AnnotatedElement, String, boolean, boolean)
* @see #getAllAnnotationAttributes(AnnotatedElement, String)
* @see #findAnnotationAttributes(AnnotatedElement, String, boolean, boolean)
* @see #getAnnotation(AnnotatedElement, Class)
* @see #findAnnotation(AnnotatedElement, Class)
*/
public static AnnotationAttributes getAnnotationAttributes(AnnotatedElement element,
@ -945,8 +972,9 @@ public class AnnotatedElementUtils { @@ -945,8 +972,9 @@ public class AnnotatedElementUtils {
* target annotation during the {@link #process} phase and then merges
* annotation attributes from lower levels in the annotation hierarchy
* during the {@link #postProcess} phase.
* @see AnnotationUtils#getAnnotationAttributes(Annotation)
* @since 4.2
* @see AnnotationUtils#getAnnotationAttributes(AnnotatedElement, Annotation, boolean, boolean, boolean)
* @see AnnotationUtils#postProcessAnnotationAttributes
*/
private static class MergedAnnotationAttributesProcessor implements Processor<AnnotationAttributes> {

4
spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java

@ -766,8 +766,8 @@ public abstract class AnnotationUtils { @@ -766,8 +766,8 @@ public abstract class AnnotationUtils {
* @param annotation the annotation to retrieve the attributes for
* @return the annotation attributes (a specialized Map) with attribute names as keys
* and corresponding attribute values as values; never {@code null}
* @see #getAnnotationAttributes(AnnotatedElement, Annotation, boolean, boolean)
* @since 4.2
* @see #getAnnotationAttributes(AnnotatedElement, Annotation, boolean, boolean)
*/
public static AnnotationAttributes getAnnotationAttributes(AnnotatedElement annotatedElement, Annotation annotation) {
return getAnnotationAttributes(annotatedElement, annotation, false, false);
@ -1233,8 +1233,8 @@ public abstract class AnnotationUtils { @@ -1233,8 +1233,8 @@ public abstract class AnnotationUtils {
* not from an annotation, or if the supplied target type is {@link Annotation}
* @throws AnnotationConfigurationException if invalid configuration of
* {@code @AliasFor} is detected
* @see #getAliasedAttributeName(Method, Class)
* @since 4.2
* @see #getAliasedAttributeName(Method, Class)
*/
static String getAliasedAttributeName(Method attribute) {
return getAliasedAttributeName(attribute, null);

13
spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java

@ -322,6 +322,19 @@ public class AnnotatedElementUtilsTests { @@ -322,6 +322,19 @@ public class AnnotatedElementUtilsTests {
assertTrue(isAnnotated(element, name));
}
@Test
public void getAnnotationWithAliasedValueComposedAnnotation() {
Class<?> element = AliasedValueComposedContextConfigClass.class;
ContextConfig contextConfig = getAnnotation(element, ContextConfig.class);
assertNotNull("Should find @ContextConfig on " + element.getSimpleName(), contextConfig);
assertArrayEquals("locations", new String[] { "test.xml" }, contextConfig.locations());
assertArrayEquals("value", new String[] { "test.xml" }, contextConfig.value());
// Verify contracts between utility methods:
assertTrue(isAnnotated(element, ContextConfig.class.getName()));
}
@Test
public void getAnnotationAttributesWithInvalidConventionBasedComposedAnnotation() {
Class<?> element = InvalidConventionBasedComposedContextConfigClass.class;

Loading…
Cancel
Save