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&lt;AnnotationInfo&lt;Bean&gt;&gt; <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) {

Reply via email to