This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new 409bc0b5d6 org.apache.juneau.common.reflect API improvements
409bc0b5d6 is described below
commit 409bc0b5d6d29eacef1ca8483a49ec47ae662bfa
Author: James Bognar <[email protected]>
AuthorDate: Wed Nov 19 09:55:41 2025 -0500
org.apache.juneau.common.reflect API improvements
---
.../apache/juneau/common/reflect/MethodInfo.java | 47 ++++++++++++++++++----
1 file changed, 39 insertions(+), 8 deletions(-)
diff --git
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/MethodInfo.java
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/MethodInfo.java
index 20aac2d9e3..a228923e89 100644
---
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/MethodInfo.java
+++
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/MethodInfo.java
@@ -74,7 +74,7 @@ public class MethodInfo extends ExecutableInfo implements
Comparable<MethodInfo>
private final Method inner;
private final Supplier<ClassInfo> returnType;
private final Supplier<List<MethodInfo>> matchingMethods;
- private final Supplier<List<AnnotationInfo<Annotation>>>
annotationInfos;
+ private final Supplier<List<AnnotationInfo<Annotation>>> annotations;
private final Supplier<List<AnnotationInfo<Annotation>>>
allAnnotationInfos;
/**
@@ -88,7 +88,7 @@ public class MethodInfo extends ExecutableInfo implements
Comparable<MethodInfo>
this.inner = inner;
this.returnType = memoize(() ->
ClassInfo.of(inner.getReturnType(), inner.getGenericReturnType()));
this.matchingMethods = memoize(this::findMatchingMethods);
- this.annotationInfos = memoize(() ->
getMatchingMethods().stream().flatMap(m ->
m.getDeclaredAnnotations().stream()).toList());
+ this.annotations = memoize(() ->
getMatchingMethods().stream().flatMap(m ->
m.getDeclaredAnnotations().stream()).toList());
this.allAnnotationInfos = memoize(this::findAllAnnotationInfos);
}
@@ -137,7 +137,7 @@ public class MethodInfo extends ExecutableInfo implements
Comparable<MethodInfo>
* Returns all annotations on this method and parent overridden methods
in child-to-parent order.
*
* <p>
- * Results include annotations from:
+ * Results include annotations from:
* <ul>
* <li>This method
* <li>Matching methods in parent classes
@@ -145,20 +145,51 @@ public class MethodInfo extends ExecutableInfo implements
Comparable<MethodInfo>
* </ul>
*
* <p>
- * List is unmodifiable.
+ * <b>Note on Repeatable Annotations:</b>
+ * Repeatable annotations (those marked with {@link
java.lang.annotation.Repeatable @Repeatable}) are automatically
+ * expanded into their individual annotation instances. For example, if
a method has multiple {@code @Bean} annotations,
+ * this method returns each {@code @Bean} annotation separately, rather
than the container annotation.
+ *
+ * <p>
+ * List is unmodifiable.
*
- * @return A list of all annotations on this method and overridden
methods.
+ * @return
+ * A list of all annotations on this method and overridden methods.
+ * <br>Repeatable annotations are expanded into individual
instances.
*/
public List<AnnotationInfo<Annotation>> getAnnotations() {
- return annotationInfos.get();
+ return annotations.get();
}
/**
- * Returns all annotations of the specified type on this method and
parent overridden methods.
+ * Returns all annotations of the specified type on this method and
parent overridden methods in child-to-parent order.
+ *
+ * <p>
+ * Results include annotations from:
+ * <ul>
+ * <li>This method
+ * <li>Matching methods in parent classes
+ * <li>Matching methods in interfaces
+ * </ul>
+ *
+ * <p>
+ * <b>Note on Repeatable Annotations:</b>
+ * If the specified annotation type is repeatable (marked with {@link
java.lang.annotation.Repeatable @Repeatable}),
+ * this method automatically expands container annotations into
individual instances. This allows you to filter for
+ * a repeatable annotation and get back all individual occurrences
without manually handling the container.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * <jc>// Get all @Bean annotations on this method and overridden
methods</jc>
+ * Stream<AnnotationInfo<Bean>> <jv>beans</jv> =
<jv>methodInfo</jv>.getAnnotations(Bean.<jk>class</jk>);
+ * <jc>// If method has @Beans({@Bean(...), @Bean(...)}), both
individual @Bean instances are returned</jc>
+ * </p>
*
* @param <A> The annotation type.
* @param type The annotation type to filter by.
- * @return A stream of matching annotation infos.
+ * @return
+ * A stream of matching annotation infos in child-to-parent order.
+ * <br>Repeatable annotations are expanded into individual
instances.
*/
@SuppressWarnings("unchecked")
public <A extends Annotation> Stream<AnnotationInfo<A>>
getAnnotations(Class<A> type) {