Polishing
This commit is contained in:
parent
210b178922
commit
635305647c
|
|
@ -668,12 +668,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
|||
@Nullable
|
||||
public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
|
||||
throws NoSuchBeanDefinitionException {
|
||||
return findMergedAnnotationOnBean(beanName, annotationType).synthesize(
|
||||
MergedAnnotation::isPresent).orElse(null);
|
||||
|
||||
return findMergedAnnotationOnBean(beanName, annotationType)
|
||||
.synthesize(MergedAnnotation::isPresent).orElse(null);
|
||||
}
|
||||
|
||||
private <A extends Annotation> MergedAnnotation<A> findMergedAnnotationOnBean(
|
||||
String beanName, Class<A> annotationType) {
|
||||
|
||||
Class<?> beanType = getType(beanName);
|
||||
if (beanType != null) {
|
||||
MergedAnnotation<A> annotation = MergedAnnotations.from(beanType,
|
||||
|
|
|
|||
|
|
@ -76,27 +76,19 @@ final class AnnotationTypeMapping {
|
|||
private final Set<Method> claimedAliases = new HashSet<>();
|
||||
|
||||
|
||||
AnnotationTypeMapping(Class<? extends Annotation> annotationType) {
|
||||
this(null, annotationType, null);
|
||||
}
|
||||
|
||||
AnnotationTypeMapping(AnnotationTypeMapping parent, Annotation annotation) {
|
||||
this(parent, annotation.annotationType(), annotation);
|
||||
}
|
||||
|
||||
AnnotationTypeMapping(@Nullable AnnotationTypeMapping parent,
|
||||
Class<? extends Annotation> annotationType, @Nullable Annotation annotation) {
|
||||
|
||||
this.parent = parent;
|
||||
this.root = parent != null ? parent.getRoot() : this;
|
||||
this.depth = parent == null ? 0 : parent.getDepth() + 1;
|
||||
this.root = (parent != null ? parent.getRoot() : this);
|
||||
this.depth = (parent == null ? 0 : parent.getDepth() + 1);
|
||||
this.annotationType = annotationType;
|
||||
this.annotation = annotation;
|
||||
this.attributes = AttributeMethods.forAnnotationType(annotationType);
|
||||
this.mirrorSets = new MirrorSets();
|
||||
this.aliasMappings = filledIntArray(this.attributes.size(), -1);
|
||||
this.conventionMappings = filledIntArray(this.attributes.size(), -1);
|
||||
this.annotationValueMappings = filledIntArray(this.attributes.size(), -1);
|
||||
this.aliasMappings = filledIntArray(this.attributes.size());
|
||||
this.conventionMappings = filledIntArray(this.attributes.size());
|
||||
this.annotationValueMappings = filledIntArray(this.attributes.size());
|
||||
this.annotationValueSource = new AnnotationTypeMapping[this.attributes.size()];
|
||||
this.aliasedBy = resolveAliasedForTargets();
|
||||
processAliases();
|
||||
|
|
@ -109,12 +101,10 @@ final class AnnotationTypeMapping {
|
|||
Map<Method, List<Method>> aliasedBy = new HashMap<>();
|
||||
for (int i = 0; i < this.attributes.size(); i++) {
|
||||
Method attribute = this.attributes.get(i);
|
||||
AliasFor aliasFor = AnnotationsScanner.getDeclaredAnnotation(attribute,
|
||||
AliasFor.class);
|
||||
AliasFor aliasFor = AnnotationsScanner.getDeclaredAnnotation(attribute, AliasFor.class);
|
||||
if (aliasFor != null) {
|
||||
Method target = resolveAliasTarget(attribute, aliasFor);
|
||||
aliasedBy.computeIfAbsent(target, key -> new ArrayList<>()).add(
|
||||
attribute);
|
||||
aliasedBy.computeIfAbsent(target, key -> new ArrayList<>()).add(attribute);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableMap(aliasedBy);
|
||||
|
|
@ -125,12 +115,10 @@ final class AnnotationTypeMapping {
|
|||
}
|
||||
|
||||
private Method resolveAliasTarget(Method attribute, AliasFor aliasFor, boolean checkAliasPair) {
|
||||
if (StringUtils.hasText(aliasFor.value()) &&
|
||||
StringUtils.hasText(aliasFor.attribute())) {
|
||||
if (StringUtils.hasText(aliasFor.value()) && StringUtils.hasText(aliasFor.attribute())) {
|
||||
throw new AnnotationConfigurationException(String.format(
|
||||
"In @AliasFor declared on %s, attribute 'attribute' and its alias "
|
||||
+ "'value' are present with values of '%s' and '%s', but "
|
||||
+ "only one is permitted.",
|
||||
"In @AliasFor declared on %s, attribute 'attribute' and its alias 'value' " +
|
||||
"are present with values of '%s' and '%s', but only one is permitted.",
|
||||
AttributeMethods.describe(attribute), aliasFor.attribute(),
|
||||
aliasFor.value()));
|
||||
}
|
||||
|
|
@ -145,13 +133,11 @@ final class AnnotationTypeMapping {
|
|||
if (!StringUtils.hasLength(targetAttributeName)) {
|
||||
targetAttributeName = attribute.getName();
|
||||
}
|
||||
Method target = AttributeMethods.forAnnotationType(targetAnnotation)
|
||||
.get(targetAttributeName);
|
||||
Method target = AttributeMethods.forAnnotationType(targetAnnotation).get(targetAttributeName);
|
||||
if (target == null) {
|
||||
if (targetAnnotation == this.annotationType) {
|
||||
throw new AnnotationConfigurationException(String.format(
|
||||
"@AliasFor declaration on %s declares an "
|
||||
+ "alias for '%s' which is not present.",
|
||||
"@AliasFor declaration on %s declares an alias for '%s' which is not present.",
|
||||
AttributeMethods.describe(attribute), targetAttributeName));
|
||||
}
|
||||
throw new AnnotationConfigurationException(String.format(
|
||||
|
|
@ -161,9 +147,8 @@ final class AnnotationTypeMapping {
|
|||
}
|
||||
if (target == attribute) {
|
||||
throw new AnnotationConfigurationException(String.format(
|
||||
"@AliasFor declaration on %s points to itself. "
|
||||
+ "Specify 'annotation' to point to a same-named "
|
||||
+ "attribute on a meta-annotation.",
|
||||
"@AliasFor declaration on %s points to itself. " +
|
||||
"Specify 'annotation' to point to a same-named attribute on a meta-annotation.",
|
||||
AttributeMethods.describe(attribute)));
|
||||
}
|
||||
if (!isCompatibleReturnType(attribute.getReturnType(), target.getReturnType())) {
|
||||
|
|
@ -175,10 +160,10 @@ final class AnnotationTypeMapping {
|
|||
if (isAliasPair(target) && checkAliasPair) {
|
||||
AliasFor targetAliasFor = target.getAnnotation(AliasFor.class);
|
||||
if (targetAliasFor == null) {
|
||||
throw new AnnotationConfigurationException(
|
||||
String.format("%s must be declared as an @AliasFor '%s'.",
|
||||
StringUtils.capitalize(AttributeMethods.describe(target)),
|
||||
attribute.getName()));
|
||||
throw new AnnotationConfigurationException(String.format(
|
||||
"%s must be declared as an @AliasFor '%s'.",
|
||||
StringUtils.capitalize(AttributeMethods.describe(target)),
|
||||
attribute.getName()));
|
||||
}
|
||||
Method mirror = resolveAliasTarget(target, targetAliasFor, false);
|
||||
if (mirror != attribute) {
|
||||
|
|
@ -288,10 +273,10 @@ final class AnnotationTypeMapping {
|
|||
for (int i = 0; i < this.attributes.size(); i++) {
|
||||
Method attribute = this.attributes.get(i);
|
||||
AnnotationTypeMapping mapping = this;
|
||||
while (mapping.depth > 0) {
|
||||
while (mapping != null && mapping.depth > 0) {
|
||||
int mapped = mapping.getAttributes().indexOf(attribute.getName());
|
||||
if (mapped != -1 && (this.annotationValueMappings[i] == -1
|
||||
|| this.annotationValueSource[i].depth > mapping.depth)) {
|
||||
if (mapped != -1 && (this.annotationValueMappings[i] == -1 ||
|
||||
this.annotationValueSource[i].depth > mapping.depth)) {
|
||||
this.annotationValueMappings[i] = mapped;
|
||||
this.annotationValueSource[i] = mapping;
|
||||
}
|
||||
|
|
@ -320,8 +305,7 @@ final class AnnotationTypeMapping {
|
|||
Method target = resolveAliasTarget(attribute, aliasFor);
|
||||
throw new AnnotationConfigurationException(String.format(
|
||||
"@AliasFor declaration on %s declares an alias for %s which is not meta-present.",
|
||||
AttributeMethods.describe(attribute),
|
||||
AttributeMethods.describe(target)));
|
||||
AttributeMethods.describe(attribute), AttributeMethods.describe(target)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -335,14 +319,12 @@ final class AnnotationTypeMapping {
|
|||
if (firstDefaultValue == null || mirrorDefaultValue == null) {
|
||||
throw new AnnotationConfigurationException(String.format(
|
||||
"Misconfigured aliases: %s and %s must declare default values.",
|
||||
AttributeMethods.describe(firstAttribute),
|
||||
AttributeMethods.describe(mirrorAttribute)));
|
||||
AttributeMethods.describe(firstAttribute), AttributeMethods.describe(mirrorAttribute)));
|
||||
}
|
||||
if (!ObjectUtils.nullSafeEquals(firstDefaultValue, mirrorDefaultValue)) {
|
||||
throw new AnnotationConfigurationException(String.format(
|
||||
"Misconfigured aliases: %s and %s must declare the same default value.",
|
||||
AttributeMethods.describe(firstAttribute),
|
||||
AttributeMethods.describe(mirrorAttribute)));
|
||||
AttributeMethods.describe(firstAttribute), AttributeMethods.describe(mirrorAttribute)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -438,8 +420,7 @@ final class AnnotationTypeMapping {
|
|||
return null;
|
||||
}
|
||||
AnnotationTypeMapping source = this.annotationValueSource[attributeIndex];
|
||||
return ReflectionUtils.invokeMethod(source.attributes.get(mapped),
|
||||
source.annotation);
|
||||
return ReflectionUtils.invokeMethod(source.attributes.get(mapped), source.annotation);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -453,6 +434,7 @@ final class AnnotationTypeMapping {
|
|||
*/
|
||||
boolean isEquivalentToDefaultValue(int attributeIndex, Object value,
|
||||
BiFunction<Method, Object, Object> valueExtractor) {
|
||||
|
||||
Method attribute = this.attributes.get(attributeIndex);
|
||||
return isEquivalentToDefaultValue(attribute, value, valueExtractor);
|
||||
}
|
||||
|
|
@ -465,20 +447,22 @@ final class AnnotationTypeMapping {
|
|||
return this.mirrorSets;
|
||||
}
|
||||
|
||||
private static int[] filledIntArray(int size, int value) {
|
||||
|
||||
private static int[] filledIntArray(int size) {
|
||||
int[] array = new int[size];
|
||||
Arrays.fill(array, value);
|
||||
Arrays.fill(array, -1);
|
||||
return array;
|
||||
}
|
||||
|
||||
private static boolean isEquivalentToDefaultValue(Method attribute, Object value,
|
||||
BiFunction<Method, Object, Object> valueExtractor) {
|
||||
|
||||
return areEquivalent(attribute.getDefaultValue(), value, valueExtractor);
|
||||
}
|
||||
|
||||
private static boolean areEquivalent(@Nullable Object value,
|
||||
@Nullable Object extractedValue,
|
||||
private static boolean areEquivalent(@Nullable Object value, @Nullable Object extractedValue,
|
||||
BiFunction<Method, Object, Object> valueExtractor) {
|
||||
|
||||
if (ObjectUtils.nullSafeEquals(value, extractedValue)) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -512,8 +496,8 @@ final class AnnotationTypeMapping {
|
|||
|
||||
private static boolean areEquivalent(Annotation value, @Nullable Object extractedValue,
|
||||
BiFunction<Method, Object, Object> valueExtractor) {
|
||||
AttributeMethods attributes = AttributeMethods.forAnnotationType(
|
||||
value.annotationType());
|
||||
|
||||
AttributeMethods attributes = AttributeMethods.forAnnotationType(value.annotationType());
|
||||
for (int i = 0; i < attributes.size(); i++) {
|
||||
Method attribute = attributes.get(i);
|
||||
if (!areEquivalent(ReflectionUtils.invokeMethod(attribute, value),
|
||||
|
|
@ -535,13 +519,11 @@ final class AnnotationTypeMapping {
|
|||
|
||||
private final MirrorSet[] assigned;
|
||||
|
||||
|
||||
MirrorSets() {
|
||||
this.assigned = new MirrorSet[attributes.size()];
|
||||
this.mirrorSets = new MirrorSet[0];
|
||||
}
|
||||
|
||||
|
||||
void updateFrom(Collection<Method> aliases) {
|
||||
MirrorSet mirrorSet = null;
|
||||
int size = 0;
|
||||
|
|
@ -562,8 +544,7 @@ final class AnnotationTypeMapping {
|
|||
}
|
||||
if (mirrorSet != null) {
|
||||
mirrorSet.update();
|
||||
LinkedHashSet<MirrorSet> unique = new LinkedHashSet<>(
|
||||
Arrays.asList(this.assigned));
|
||||
Set<MirrorSet> unique = new LinkedHashSet<>(Arrays.asList(this.assigned));
|
||||
unique.remove(null);
|
||||
this.mirrorSets = unique.toArray(new MirrorSet[0]);
|
||||
}
|
||||
|
|
@ -609,7 +590,6 @@ final class AnnotationTypeMapping {
|
|||
|
||||
private final int[] indexes = new int[attributes.size()];
|
||||
|
||||
|
||||
void update() {
|
||||
this.size = 0;
|
||||
Arrays.fill(this.indexes, -1);
|
||||
|
|
@ -629,8 +609,8 @@ final class AnnotationTypeMapping {
|
|||
for (int i = 0; i < this.size; i++) {
|
||||
Method attribute = attributes.get(this.indexes[i]);
|
||||
Object value = valueExtractor.apply(attribute, annotation);
|
||||
boolean isDefaultValue = value == null || isEquivalentToDefaultValue(
|
||||
attribute, value, valueExtractor);
|
||||
boolean isDefaultValue = (value == null ||
|
||||
isEquivalentToDefaultValue(attribute, value, valueExtractor));
|
||||
if (isDefaultValue || ObjectUtils.nullSafeEquals(lastValue, value)) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -638,8 +618,8 @@ final class AnnotationTypeMapping {
|
|||
!ObjectUtils.nullSafeEquals(lastValue, value)) {
|
||||
String on = (source != null) ? " declared on " + source : "";
|
||||
throw new AnnotationConfigurationException(String.format(
|
||||
"Different @AliasFor mirror values for annotation [%s]%s, "
|
||||
+ "attribute '%s' and its alias '%s' are declared with values of [%s] and [%s].",
|
||||
"Different @AliasFor mirror values for annotation [%s]%s, attribute '%s' " +
|
||||
"and its alias '%s' are declared with values of [%s] and [%s].",
|
||||
getAnnotationType().getName(), on,
|
||||
attributes.get(result).getName(),
|
||||
attribute.getName(),
|
||||
|
|
@ -664,8 +644,7 @@ final class AnnotationTypeMapping {
|
|||
int getAttributeIndex(int index) {
|
||||
return this.indexes[index];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,17 +118,13 @@ abstract class AnnotationsScanner {
|
|||
|
||||
switch (searchStrategy) {
|
||||
case DIRECT:
|
||||
return processElement(context, source,
|
||||
processor, classFilter);
|
||||
return processElement(context, source, processor, classFilter);
|
||||
case INHERITED_ANNOTATIONS:
|
||||
return processClassInheritedAnnotations(context, source,
|
||||
processor, classFilter);
|
||||
return processClassInheritedAnnotations(context, source, processor, classFilter);
|
||||
case SUPER_CLASS:
|
||||
return processClassHierarchy(context, new int[] { 0 }, source,
|
||||
processor, classFilter, false);
|
||||
return processClassHierarchy(context, new int[] {0}, source, processor, classFilter, false);
|
||||
case EXHAUSTIVE:
|
||||
return processClassHierarchy(context, new int[] { 0 }, source,
|
||||
processor, classFilter, true);
|
||||
return processClassHierarchy(context, new int[] {0}, source, processor, classFilter, true);
|
||||
}
|
||||
throw new IllegalStateException("Unsupported search strategy " + searchStrategy);
|
||||
}
|
||||
|
|
@ -405,8 +401,8 @@ abstract class AnnotationsScanner {
|
|||
AnnotationsProcessor<C, R> processor, @Nullable BiPredicate<C, Class<?>> classFilter) {
|
||||
|
||||
R result = processor.doWithAggregate(context, 0);
|
||||
return (result != null ? result : processor.doWithAnnotations(context, 0, source,
|
||||
getDeclaredAnnotations(context, source, classFilter, false)));
|
||||
return (result != null ? result : processor.doWithAnnotations(
|
||||
context, 0, source, getDeclaredAnnotations(context, source, classFilter, false)));
|
||||
}
|
||||
|
||||
private static <C, R> Annotation[] getDeclaredAnnotations(C context,
|
||||
|
|
@ -426,7 +422,7 @@ abstract class AnnotationsScanner {
|
|||
static <A extends Annotation> A getDeclaredAnnotation(AnnotatedElement source, Class<A> annotationType) {
|
||||
Annotation[] annotations = getDeclaredAnnotations(source, false);
|
||||
for (Annotation annotation : annotations) {
|
||||
if (annotation != null && annotationType.equals(annotation.annotationType())) {
|
||||
if (annotation != null && annotationType == annotation.annotationType()) {
|
||||
return (A) annotation;
|
||||
}
|
||||
}
|
||||
|
|
@ -500,9 +496,12 @@ abstract class AnnotationsScanner {
|
|||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type == Ordered.class) {
|
||||
return true;
|
||||
}
|
||||
String name = type.getName();
|
||||
return (type == Ordered.class ||
|
||||
name.startsWith("java") ||
|
||||
return (name.startsWith("java") ||
|
||||
name.startsWith("org.springframework.lang.") ||
|
||||
name.startsWith("org.springframework.util.") ||
|
||||
(name.startsWith("com.sun") && !name.contains("Proxy")));
|
||||
|
|
|
|||
|
|
@ -111,8 +111,8 @@ public abstract class RepeatableContainers {
|
|||
* {@code repeatable}.
|
||||
* @return a {@link RepeatableContainers} instance
|
||||
*/
|
||||
public static RepeatableContainers of(Class<? extends Annotation> repeatable,
|
||||
@Nullable Class<? extends Annotation> container) {
|
||||
public static RepeatableContainers of(
|
||||
Class<? extends Annotation> repeatable, @Nullable Class<? extends Annotation> container) {
|
||||
|
||||
return new ExplicitRepeatableContainer(null, repeatable, container);
|
||||
}
|
||||
|
|
@ -133,13 +133,11 @@ public abstract class RepeatableContainers {
|
|||
*/
|
||||
private static class StandardRepeatableContainers extends RepeatableContainers {
|
||||
|
||||
private static final Map<Class<? extends Annotation>, Object> cache =
|
||||
new ConcurrentReferenceHashMap<>();
|
||||
private static final Map<Class<? extends Annotation>, Object> cache = new ConcurrentReferenceHashMap<>();
|
||||
|
||||
private static final Object NONE = new Object();
|
||||
|
||||
private static StandardRepeatableContainers INSTANCE =
|
||||
new StandardRepeatableContainers();
|
||||
private static StandardRepeatableContainers INSTANCE = new StandardRepeatableContainers();
|
||||
|
||||
StandardRepeatableContainers() {
|
||||
super(null);
|
||||
|
|
@ -156,17 +154,13 @@ public abstract class RepeatableContainers {
|
|||
}
|
||||
|
||||
@Nullable
|
||||
private static Method getRepeatedAnnotationsMethod(
|
||||
Class<? extends Annotation> annotationType) {
|
||||
|
||||
private static Method getRepeatedAnnotationsMethod(Class<? extends Annotation> annotationType) {
|
||||
Object result = cache.computeIfAbsent(annotationType,
|
||||
StandardRepeatableContainers::computeRepeatedAnnotationsMethod);
|
||||
return result != NONE ? (Method) result : null;
|
||||
return (result != NONE ? (Method) result : null);
|
||||
}
|
||||
|
||||
private static Object computeRepeatedAnnotationsMethod(
|
||||
Class<? extends Annotation> annotationType) {
|
||||
|
||||
private static Object computeRepeatedAnnotationsMethod(Class<? extends Annotation> annotationType) {
|
||||
AttributeMethods methods = AttributeMethods.forAnnotationType(annotationType);
|
||||
if (methods.isOnlyValueAttribute()) {
|
||||
Method method = methods.get("value");
|
||||
|
|
@ -176,15 +170,14 @@ public abstract class RepeatableContainers {
|
|||
Class<?> returnType = method.getReturnType();
|
||||
if (returnType.isArray()) {
|
||||
Class<?> componentType = returnType.getComponentType();
|
||||
if (Annotation.class.isAssignableFrom(componentType)
|
||||
&& componentType.isAnnotationPresent(Repeatable.class)) {
|
||||
if (Annotation.class.isAssignableFrom(componentType) &&
|
||||
componentType.isAnnotationPresent(Repeatable.class)) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NONE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -248,9 +248,8 @@ final class TypeMappedAnnotations implements MergedAnnotations {
|
|||
return null;
|
||||
}
|
||||
|
||||
static MergedAnnotations from(@Nullable AnnotatedElement element,
|
||||
SearchStrategy searchStrategy, RepeatableContainers repeatableContainers,
|
||||
AnnotationFilter annotationFilter) {
|
||||
static MergedAnnotations from(@Nullable AnnotatedElement element, SearchStrategy searchStrategy,
|
||||
RepeatableContainers repeatableContainers, AnnotationFilter annotationFilter) {
|
||||
|
||||
if (element == null || AnnotationsScanner.isKnownEmpty(element, searchStrategy, annotationFilter)) {
|
||||
return NONE;
|
||||
|
|
@ -324,11 +323,11 @@ final class TypeMappedAnnotations implements MergedAnnotations {
|
|||
if (type == requiredType || type.getName().equals(requiredType)) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
Annotation[] repeatedAnnotations = this.repeatableContainers
|
||||
.findRepeatedAnnotations(annotation);
|
||||
Annotation[] repeatedAnnotations =
|
||||
this.repeatableContainers.findRepeatedAnnotations(annotation);
|
||||
if (repeatedAnnotations != null) {
|
||||
Boolean result = doWithAnnotations(requiredType, aggregateIndex,
|
||||
source, repeatedAnnotations);
|
||||
Boolean result = doWithAnnotations(
|
||||
requiredType, aggregateIndex, source, repeatedAnnotations);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
|
@ -402,8 +401,7 @@ final class TypeMappedAnnotations implements MergedAnnotations {
|
|||
@Nullable Object source, Annotation[] annotations) {
|
||||
|
||||
for (Annotation annotation : annotations) {
|
||||
if (annotation != null &&
|
||||
!annotationFilter.matches(annotation)) {
|
||||
if (annotation != null && !annotationFilter.matches(annotation)) {
|
||||
MergedAnnotation<A> result = process(type, aggregateIndex, source, annotation);
|
||||
if (result != null) {
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -68,8 +68,7 @@ public class AnnotationIntrospectionFailureTests {
|
|||
assertThat(AnnotatedElementUtils.getMergedAnnotationAttributes(
|
||||
withExampleMetaAnnotation, exampleAnnotationClass)).isNull();
|
||||
assertThat(AnnotatedElementUtils.getMergedAnnotationAttributes(
|
||||
withExampleMetaAnnotation,
|
||||
exampleMetaAnnotationClass)).isNull();
|
||||
withExampleMetaAnnotation, exampleMetaAnnotationClass)).isNull();
|
||||
assertThat(AnnotatedElementUtils.hasAnnotation(withExampleMetaAnnotation,
|
||||
exampleAnnotationClass)).isFalse();
|
||||
assertThat(AnnotatedElementUtils.hasAnnotation(withExampleMetaAnnotation,
|
||||
|
|
@ -97,12 +96,10 @@ public class AnnotationIntrospectionFailureTests {
|
|||
|
||||
static class FilteringClassLoader extends OverridingClassLoader {
|
||||
|
||||
|
||||
FilteringClassLoader(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean isEligibleForOverriding(String className) {
|
||||
return className.startsWith(
|
||||
|
|
@ -110,36 +107,31 @@ public class AnnotationIntrospectionFailureTests {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> loadClass(String name, boolean resolve)
|
||||
throws ClassNotFoundException {
|
||||
if (name.startsWith(AnnotationIntrospectionFailureTests.class.getName())
|
||||
&& name.contains("Filtered")) {
|
||||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
||||
if (name.startsWith(AnnotationIntrospectionFailureTests.class.getName()) &&
|
||||
name.contains("Filtered")) {
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
return super.loadClass(name, resolve);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class FilteredType {
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface ExampleAnnotation {
|
||||
@interface ExampleAnnotation {
|
||||
|
||||
Class<?> value() default Void.class;
|
||||
|
||||
}
|
||||
|
||||
@ExampleAnnotation(FilteredType.class)
|
||||
static class WithExampleAnnotation {
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ExampleAnnotation
|
||||
static @interface ExampleMetaAnnotation {
|
||||
@interface ExampleMetaAnnotation {
|
||||
|
||||
@AliasFor(annotation = ExampleAnnotation.class, attribute = "value")
|
||||
Class<?> example1() default Void.class;
|
||||
|
|
@ -151,7 +143,6 @@ public class AnnotationIntrospectionFailureTests {
|
|||
|
||||
@ExampleMetaAnnotation(example1 = FilteredType.class)
|
||||
static class WithExampleMetaAnnotation {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue