parent
d194724a04
commit
1760e7fac8
|
@ -19,7 +19,9 @@ package org.springframework.security.core.annotation;
|
|||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Factory for creating {@link SecurityAnnotationScanner} instances.
|
||||
|
@ -29,6 +31,12 @@ import java.util.List;
|
|||
*/
|
||||
public final class SecurityAnnotationScanners {
|
||||
|
||||
private static final Map<Class<? extends Annotation>, SecurityAnnotationScanner<? extends Annotation>> uniqueScanners = new HashMap<>();
|
||||
|
||||
private static final Map<Class<? extends Annotation>, SecurityAnnotationScanner<? extends Annotation>> uniqueTemplateScanners = new HashMap<>();
|
||||
|
||||
private static final Map<List<Class<? extends Annotation>>, SecurityAnnotationScanner<? extends Annotation>> uniqueTypesScanners = new HashMap<>();
|
||||
|
||||
private SecurityAnnotationScanners() {
|
||||
}
|
||||
|
||||
|
@ -40,7 +48,8 @@ public final class SecurityAnnotationScanners {
|
|||
* @return the default {@link SecurityAnnotationScanner}
|
||||
*/
|
||||
public static <A extends Annotation> SecurityAnnotationScanner<A> requireUnique(Class<A> type) {
|
||||
return new UniqueSecurityAnnotationScanner<>(type);
|
||||
return (SecurityAnnotationScanner<A>) uniqueScanners.computeIfAbsent(type,
|
||||
(t) -> new UniqueSecurityAnnotationScanner<>(type));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,9 +69,10 @@ public final class SecurityAnnotationScanners {
|
|||
public static <A extends Annotation> SecurityAnnotationScanner<A> requireUnique(Class<A> type,
|
||||
AnnotationTemplateExpressionDefaults templateDefaults) {
|
||||
if (templateDefaults == null) {
|
||||
return new UniqueSecurityAnnotationScanner<>(type);
|
||||
return requireUnique(type);
|
||||
}
|
||||
return new ExpressionTemplateSecurityAnnotationScanner<>(type, templateDefaults);
|
||||
return (SecurityAnnotationScanner<A>) uniqueTemplateScanners.computeIfAbsent(type,
|
||||
(t) -> new ExpressionTemplateSecurityAnnotationScanner<>(t, templateDefaults));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -75,7 +85,8 @@ public final class SecurityAnnotationScanners {
|
|||
public static SecurityAnnotationScanner<Annotation> requireUnique(List<Class<? extends Annotation>> types) {
|
||||
List<Class<Annotation>> casted = new ArrayList<>();
|
||||
types.forEach((type) -> casted.add((Class<Annotation>) type));
|
||||
return new UniqueSecurityAnnotationScanner<>(casted);
|
||||
return (SecurityAnnotationScanner<Annotation>) uniqueTypesScanners.computeIfAbsent(types,
|
||||
(t) -> new UniqueSecurityAnnotationScanner<>(casted));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,10 +22,13 @@ import java.lang.reflect.Method;
|
|||
import java.lang.reflect.Parameter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.MethodClassKey;
|
||||
import org.springframework.core.annotation.AnnotationConfigurationException;
|
||||
import org.springframework.core.annotation.MergedAnnotation;
|
||||
import org.springframework.core.annotation.MergedAnnotations;
|
||||
|
@ -86,6 +89,10 @@ final class UniqueSecurityAnnotationScanner<A extends Annotation> extends Abstra
|
|||
|
||||
private final List<Class<A>> types;
|
||||
|
||||
private final Map<Parameter, MergedAnnotation<A>> uniqueParameterAnnotationCache = new HashMap<>();
|
||||
|
||||
private final Map<MethodClassKey, MergedAnnotation<A>> uniqueMethodAnnotationCache = new HashMap<>();
|
||||
|
||||
UniqueSecurityAnnotationScanner(Class<A> type) {
|
||||
Assert.notNull(type, "type cannot be null");
|
||||
this.types = List.of(type);
|
||||
|
@ -99,12 +106,16 @@ final class UniqueSecurityAnnotationScanner<A extends Annotation> extends Abstra
|
|||
@Override
|
||||
MergedAnnotation<A> merge(AnnotatedElement element, Class<?> targetClass) {
|
||||
if (element instanceof Parameter parameter) {
|
||||
List<MergedAnnotation<A>> annotations = findDirectAnnotations(parameter);
|
||||
return requireUnique(parameter, annotations);
|
||||
return this.uniqueParameterAnnotationCache.computeIfAbsent(parameter, (p) -> {
|
||||
List<MergedAnnotation<A>> annotations = findDirectAnnotations(p);
|
||||
return requireUnique(p, annotations);
|
||||
});
|
||||
}
|
||||
if (element instanceof Method method) {
|
||||
List<MergedAnnotation<A>> annotations = findMethodAnnotations(method, targetClass);
|
||||
return requireUnique(method, annotations);
|
||||
return this.uniqueMethodAnnotationCache.computeIfAbsent(new MethodClassKey(method, targetClass), (k) -> {
|
||||
List<MergedAnnotation<A>> annotations = findMethodAnnotations(method, targetClass);
|
||||
return requireUnique(method, annotations);
|
||||
});
|
||||
}
|
||||
throw new AnnotationConfigurationException("Unsupported element of type " + element.getClass());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue