|
18 | 18 |
|
19 | 19 | import java.lang.annotation.Annotation; |
20 | 20 | import java.lang.reflect.AnnotatedElement; |
| 21 | +import java.lang.reflect.Executable; |
21 | 22 | import java.lang.reflect.Method; |
22 | 23 | import java.lang.reflect.Parameter; |
23 | 24 | import java.util.ArrayList; |
24 | 25 | import java.util.Collections; |
25 | 26 | import java.util.HashSet; |
26 | 27 | import java.util.List; |
27 | 28 | import java.util.Map; |
| 29 | +import java.util.Objects; |
28 | 30 | import java.util.Set; |
29 | 31 | import java.util.concurrent.ConcurrentHashMap; |
30 | 32 |
|
31 | 33 | import org.springframework.core.MethodClassKey; |
| 34 | +import org.springframework.core.MethodParameter; |
| 35 | +import org.springframework.core.annotation.AnnotatedMethod; |
32 | 36 | import org.springframework.core.annotation.AnnotationConfigurationException; |
| 37 | +import org.springframework.core.annotation.AnnotationUtils; |
33 | 38 | import org.springframework.core.annotation.MergedAnnotation; |
34 | 39 | import org.springframework.core.annotation.MergedAnnotations; |
35 | 40 | import org.springframework.core.annotation.RepeatableContainers; |
@@ -103,11 +108,45 @@ final class UniqueSecurityAnnotationScanner<A extends Annotation> extends Abstra |
103 | 108 | this.types = types; |
104 | 109 | } |
105 | 110 |
|
| 111 | + private A findMethodAnnotation(Class<A> annotationClass, Parameter p) { |
| 112 | + Executable executable = p.getDeclaringExecutable(); |
| 113 | + if (executable instanceof Method method) { |
| 114 | + AnnotatedMethod annotatedMethod = new AnnotatedMethod(method); |
| 115 | + MethodParameter parameter = null; |
| 116 | + MethodParameter[] methodParameters = annotatedMethod.getMethodParameters(); |
| 117 | + for (MethodParameter methodParameter : methodParameters) { |
| 118 | + if (p == methodParameter.getParameter()) { |
| 119 | + parameter = methodParameter; |
| 120 | + break; |
| 121 | + } |
| 122 | + } |
| 123 | + if (parameter == null) { |
| 124 | + return null; |
| 125 | + } |
| 126 | + A annotation = parameter.getParameterAnnotation(annotationClass); |
| 127 | + if (annotation != null) { |
| 128 | + return annotation; |
| 129 | + } |
| 130 | + Annotation[] annotationsToSearch = parameter.getParameterAnnotations(); |
| 131 | + for (Annotation toSearch : annotationsToSearch) { |
| 132 | + annotation = AnnotationUtils.findAnnotation(toSearch.annotationType(), annotationClass); |
| 133 | + if (annotation != null) { |
| 134 | + return annotation; |
| 135 | + } |
| 136 | + } |
| 137 | + } |
| 138 | + return null; |
| 139 | + } |
| 140 | + |
106 | 141 | @Override |
107 | 142 | MergedAnnotation<A> merge(AnnotatedElement element, Class<?> targetClass) { |
108 | 143 | if (element instanceof Parameter parameter) { |
109 | 144 | return this.uniqueParameterAnnotationCache.computeIfAbsent(parameter, (p) -> { |
110 | | - List<MergedAnnotation<A>> annotations = findDirectAnnotations(p); |
| 145 | + List<MergedAnnotation<A>> annotations = this.types.stream() |
| 146 | + .map((c) -> findMethodAnnotation(c, p)) |
| 147 | + .filter(Objects::nonNull) |
| 148 | + .map(MergedAnnotation::from) |
| 149 | + .toList(); |
111 | 150 | return requireUnique(p, annotations); |
112 | 151 | }); |
113 | 152 | } |
|
0 commit comments