From d82e70e345f1a7071fcd0863654713057ab99d3b Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Thu, 13 Feb 2025 14:30:02 +0100 Subject: [PATCH 1/2] Cross reference annotation search APIs in Javadoc Closes gh-34421 --- .../annotation/AnnotatedElementUtils.java | 11 +++++--- .../core/annotation/AnnotationUtils.java | 8 +++--- .../core/annotation/MergedAnnotations.java | 8 ++++-- .../context/TestContextAnnotationUtils.java | 27 +++++++++++-------- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java index 1ac4f84a5e8..545b8a098ed 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2025 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. @@ -36,8 +36,12 @@ import org.springframework.util.MultiValueMap; * *

{@code AnnotatedElementUtils} defines the public API for Spring's * meta-annotation programming model with support for annotation attribute - * overrides. If you do not need support for annotation attribute - * overrides, consider using {@link AnnotationUtils} instead. + * overrides and {@link AliasFor @AliasFor}. Note, however, that + * {@code AnnotatedElementUtils} is effectively a facade for the + * {@link MergedAnnotations} API. For fine-grained support consider using the + * {@code MergedAnnotations} API directly. If you do not need support for + * annotation attribute overrides, {@code @AliasFor}, or merged annotations, + * consider using {@link AnnotationUtils} instead. * *

Note that the features of this class are not provided by the JDK's * introspection facilities themselves. @@ -87,6 +91,7 @@ import org.springframework.util.MultiValueMap; * @since 4.0 * @see AliasFor * @see AnnotationAttributes + * @see MergedAnnotations * @see AnnotationUtils * @see BridgeMethodResolver */ diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java index b46bd281ec6..68f9e96e5a2 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -60,7 +60,7 @@ import org.springframework.util.StringUtils; *

Terminology

* The terms directly present, indirectly present, and * present have the same meanings as defined in the class-level - * javadoc for {@link AnnotatedElement} (in Java 8). + * javadoc for {@link AnnotatedElement}. * *

An annotation is meta-present on an element if the annotation * is declared as a meta-annotation on some other annotation which is @@ -73,7 +73,8 @@ import org.springframework.util.StringUtils; * provide support for finding annotations used as meta-annotations. Consult the * javadoc for each method in this class for details. For fine-grained support for * meta-annotations with attribute overrides in composed annotations, - * consider using {@link AnnotatedElementUtils}'s more specific methods instead. + * consider using the {@link MergedAnnotations} API directly or the more specific + * methods in {@link AnnotatedElementUtils} instead. * *

Attribute Aliases

*

All public methods in this class that return annotations, arrays of @@ -97,6 +98,7 @@ import org.springframework.util.StringUtils; * @since 2.0 * @see AliasFor * @see AnnotationAttributes + * @see MergedAnnotations * @see AnnotatedElementUtils * @see BridgeMethodResolver * @see java.lang.reflect.AnnotatedElement#getAnnotations() diff --git a/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotations.java b/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotations.java index 7d054454a1c..96bcd5ae507 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotations.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotations.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 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. @@ -37,7 +37,7 @@ import org.springframework.util.Assert; *

@@ -140,6 +140,9 @@ import org.springframework.util.Assert; * @see MergedAnnotationCollectors * @see MergedAnnotationPredicates * @see MergedAnnotationSelectors + * @see AliasFor + * @see AnnotationUtils + * @see AnnotatedElementUtils */ public interface MergedAnnotations extends Iterable> { @@ -560,6 +563,7 @@ public interface MergedAnnotations extends Iterable * @see #withRepeatableContainers(RepeatableContainers) * @see #withAnnotationFilter(AnnotationFilter) * @see #from(AnnotatedElement) + * @see org.springframework.test.context.TestContextAnnotationUtils#searchEnclosingClass(Class) */ public Search withEnclosingClasses(Predicate> searchEnclosingClass) { Assert.notNull(searchEnclosingClass, "Predicate must not be null"); diff --git a/spring-test/src/main/java/org/springframework/test/context/TestContextAnnotationUtils.java b/spring-test/src/main/java/org/springframework/test/context/TestContextAnnotationUtils.java index 6053c115726..39e70bd32f7 100644 --- a/spring-test/src/main/java/org/springframework/test/context/TestContextAnnotationUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/TestContextAnnotationUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -43,19 +43,20 @@ import org.springframework.util.ObjectUtils; /** * {@code TestContextAnnotationUtils} is a collection of utility methods that - * complements the standard support already available in {@link AnnotationUtils} - * and {@link AnnotatedElementUtils}, while transparently honoring - * {@link NestedTestConfiguration @NestedTestConfiguration} semantics. + * complements the standard support already available in {@link MergedAnnotations}, + * {@link AnnotationUtils}, and {@link AnnotatedElementUtils}, while transparently + * honoring {@link NestedTestConfiguration @NestedTestConfiguration} semantics. * *

Mainly for internal use within the Spring TestContext Framework * but also supported for third-party integrations with the TestContext framework. * - *

Whereas {@code AnnotationUtils} and {@code AnnotatedElementUtils} provide - * utilities for getting or finding annotations, - * {@code TestContextAnnotationUtils} goes a step further by providing support - * for determining the root class on which an annotation is declared, - * either directly or indirectly via a composed annotation. This - * additional information is encapsulated in an {@link AnnotationDescriptor}. + *

Whereas {@code MergedAnnotations}, {@code AnnotationUtils} and + * {@code AnnotatedElementUtils} provide utilities for getting or + * finding annotations, {@code TestContextAnnotationUtils} goes a step + * further by providing support for determining the root class on which + * an annotation is declared, either directly or indirectly via a + * composed annotation. This additional information is encapsulated in + * an {@link AnnotationDescriptor}. * *

The additional information provided by an {@code AnnotationDescriptor} is * required by the Spring TestContext Framework in order to be able to @@ -67,7 +68,11 @@ import org.springframework.util.ObjectUtils; * example, {@link ContextConfiguration#inheritLocations}. * * @author Sam Brannen - * @since 5.3, though originally since 4.0 as {@code org.springframework.test.util.MetaAnnotationUtils} + * @since 5.3 + * @see MergedAnnotations + * @see MergedAnnotations.Search + * @see MergedAnnotations.Search#withEnclosingClasses(Predicate) + * @see #searchEnclosingClass(Class) * @see AnnotationUtils * @see AnnotatedElementUtils * @see AnnotationDescriptor From 9e4517820241a4b96b945e4f5816a578a100320a Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Thu, 13 Feb 2025 15:51:56 +0100 Subject: [PATCH 2/2] Stop referring to "Java 8" in AnnotationUtils --- .../core/annotation/AnnotationUtils.java | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java index 68f9e96e5a2..98e912e33e0 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java @@ -309,11 +309,11 @@ public abstract class AnnotationUtils { * {@code annotationType} from the supplied {@link AnnotatedElement}, where * such annotations are either present, indirectly present, * or meta-present on the element. - *

This method mimics the functionality of Java 8's + *

This method mimics the functionality of * {@link java.lang.reflect.AnnotatedElement#getAnnotationsByType(Class)} * with support for automatic detection of a container annotation - * declared via @{@link java.lang.annotation.Repeatable} (when running on - * Java 8 or higher) and with additional support for meta-annotations. + * declared via {@link java.lang.annotation.Repeatable @Repeatable} and with + * additional support for meta-annotations. *

Handles both single annotations and annotations nested within a * container annotation. *

Correctly handles bridge methods generated by the @@ -344,7 +344,7 @@ public abstract class AnnotationUtils { * {@code annotationType} from the supplied {@link AnnotatedElement}, where * such annotations are either present, indirectly present, * or meta-present on the element. - *

This method mimics the functionality of Java 8's + *

This method mimics the functionality * {@link java.lang.reflect.AnnotatedElement#getAnnotationsByType(Class)} * with additional support for meta-annotations. *

Handles both single annotations and annotations nested within a @@ -355,10 +355,9 @@ public abstract class AnnotationUtils { * present on the supplied element. * @param annotatedElement the element to look for annotations on * @param annotationType the annotation type to look for - * @param containerAnnotationType the type of the container that holds - * the annotations; may be {@code null} if a container is not supported - * or if it should be looked up via @{@link java.lang.annotation.Repeatable} - * when running on Java 8 or higher + * @param containerAnnotationType the type of the container that holds the + * annotations; may be {@code null} if a container is not supported or if it + * should be looked up via {@link java.lang.annotation.Repeatable @Repeatable} * @return the annotations found or an empty set (never {@code null}) * @since 4.2 * @see #getRepeatableAnnotations(AnnotatedElement, Class) @@ -390,11 +389,11 @@ public abstract class AnnotationUtils { * of {@code annotationType} from the supplied {@link AnnotatedElement}, * where such annotations are either directly present, * indirectly present, or meta-present on the element. - *

This method mimics the functionality of Java 8's + *

This method mimics the functionality of * {@link java.lang.reflect.AnnotatedElement#getDeclaredAnnotationsByType(Class)} * with support for automatic detection of a container annotation - * declared via @{@link java.lang.annotation.Repeatable} (when running on - * Java 8 or higher) and with additional support for meta-annotations. + * declared via {@link java.lang.annotation.Repeatable @Repeatable} and with + * additional support for meta-annotations. *

Handles both single annotations and annotations nested within a * container annotation. *

Correctly handles bridge methods generated by the @@ -426,7 +425,7 @@ public abstract class AnnotationUtils { * of {@code annotationType} from the supplied {@link AnnotatedElement}, * where such annotations are either directly present, * indirectly present, or meta-present on the element. - *

This method mimics the functionality of Java 8's + *

This method mimics the functionality of * {@link java.lang.reflect.AnnotatedElement#getDeclaredAnnotationsByType(Class)} * with additional support for meta-annotations. *

Handles both single annotations and annotations nested within a @@ -437,10 +436,9 @@ public abstract class AnnotationUtils { * present on the supplied element. * @param annotatedElement the element to look for annotations on * @param annotationType the annotation type to look for - * @param containerAnnotationType the type of the container that holds - * the annotations; may be {@code null} if a container is not supported - * or if it should be looked up via @{@link java.lang.annotation.Repeatable} - * when running on Java 8 or higher + * @param containerAnnotationType the type of the container that holds the + * annotations; may be {@code null} if a container is not supported or if it + * should be looked up via {@link java.lang.annotation.Repeatable @Repeatable} * @return the annotations found or an empty set (never {@code null}) * @since 4.2 * @see #getRepeatableAnnotations(AnnotatedElement, Class)