From c5b3848357320d67685744e6ebc32416b0119f66 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 8 May 2019 00:27:47 +0200 Subject: [PATCH] Nullability refinements and related polishing Includes fix for typo in visitor class names. See gh-22909 --- .../core/annotation/AnnotationUtils.java | 2 +- .../MergedAnnotationsCollection.java | 33 +++++----- .../core/annotation/TypeMappedAnnotation.java | 16 +++-- .../core/type/StandardAnnotationMetadata.java | 12 ++-- .../core/type/StandardMethodMetadata.java | 4 +- .../AnnotationMetadataReadingVisitor.java | 1 + .../ClassMetadataReadingVisitor.java | 1 + .../MergedAnnotationReadingVisitor.java | 63 +++++++++---------- .../MethodMetadataReadingVisitor.java | 1 + .../SimpleAnnotationMetadata.java | 16 +++-- ...mpleAnnotationMetadataReadingVisitor.java} | 24 +++++-- .../classreading/SimpleMetadataReader.java | 6 +- .../classreading/SimpleMethodMetadata.java | 5 +- ...> SimpleMethodMetadataReadingVisitor.java} | 45 ++++++------- .../SimpleAnnotationMetadataTests.java | 3 +- .../SimpleMethodMetadataTests.java | 3 +- 16 files changed, 126 insertions(+), 109 deletions(-) rename spring-core/src/main/java/org/springframework/core/type/classreading/{SimpleAnnotationMetadataReadingVistor.java => SimpleAnnotationMetadataReadingVisitor.java} (89%) rename spring-core/src/main/java/org/springframework/core/type/classreading/{SimpleMethodMetadataReadingVistor.java => SimpleMethodMetadataReadingVisitor.java} (81%) diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java index cae01fb25c..0a607113a2 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java @@ -898,7 +898,7 @@ public abstract class AnnotationUtils { for (int i = 0; i < methods.size(); i++) { Method method = methods.get(i); Object defaultValue = method.getDefaultValue(); - if(defaultValue != null) { + if (defaultValue != null) { result.put(method.getName(), new DefaultValueHolder(defaultValue)); } } diff --git a/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotationsCollection.java b/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotationsCollection.java index 48308cdafe..395acfa0e2 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotationsCollection.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotationsCollection.java @@ -43,6 +43,7 @@ final class MergedAnnotationsCollection implements MergedAnnotations { private final AnnotationTypeMappings[] mappings; + private MergedAnnotationsCollection(Collection> annotations) { Assert.notNull(annotations, "Annotations must not be null"); this.annotations = annotations.toArray(new MergedAnnotation[0]); @@ -52,11 +53,11 @@ final class MergedAnnotationsCollection implements MergedAnnotations { Assert.notNull(annotation, "Annotation must not be null"); Assert.isTrue(annotation.isDirectlyPresent(), "Annotation must be directly present"); Assert.isTrue(annotation.getAggregateIndex() == 0, "Annotation must have aggregate index of zero"); - this.mappings[i] = AnnotationTypeMappings.forAnnotationType( - annotation.getType()); + this.mappings[i] = AnnotationTypeMappings.forAnnotationType(annotation.getType()); } } + @Override public Iterator> iterator() { return Spliterators.iterator(spliterator()); @@ -67,8 +68,7 @@ final class MergedAnnotationsCollection implements MergedAnnotations { return spliterator(null); } - private Spliterator> spliterator( - @Nullable Object annotationType) { + private Spliterator> spliterator(@Nullable Object annotationType) { return new AnnotationsSpliterator<>(annotationType); } @@ -128,6 +128,7 @@ final class MergedAnnotationsCollection implements MergedAnnotations { public MergedAnnotation get(Class annotationType, @Nullable Predicate> predicate, @Nullable MergedAnnotationSelector selector) { + MergedAnnotation result = find(annotationType, predicate, selector); return (result != null ? result : MergedAnnotation.missing()); } @@ -154,12 +155,15 @@ final class MergedAnnotationsCollection implements MergedAnnotations { } @SuppressWarnings("unchecked") + @Nullable private MergedAnnotation find(Object requiredType, - Predicate> predicate, - MergedAnnotationSelector selector) { + @Nullable Predicate> predicate, + @Nullable MergedAnnotationSelector selector) { + if (selector == null) { selector = MergedAnnotationSelectors.nearest(); } + MergedAnnotation result = null; for (int i = 0; i < this.annotations.length; i++) { MergedAnnotation root = this.annotations[i]; @@ -208,7 +212,7 @@ final class MergedAnnotationsCollection implements MergedAnnotations { static MergedAnnotations of(Collection> annotations) { Assert.notNull(annotations, "Annotations must not be null"); - if(annotations.isEmpty()) { + if (annotations.isEmpty()) { return TypeMappedAnnotations.NONE; } return new MergedAnnotationsCollection(annotations); @@ -242,7 +246,8 @@ final class MergedAnnotationsCollection implements MergedAnnotations { } } if (annotationResult != -1) { - MergedAnnotation mergedAnnotation = createMergedAnnotationIfPossible(annotationResult, this.mappingCursors[annotationResult]); + MergedAnnotation mergedAnnotation = createMergedAnnotationIfPossible( + annotationResult, this.mappingCursors[annotationResult]); this.mappingCursors[annotationResult]++; if (mergedAnnotation == null) { return tryAdvance(action); @@ -275,20 +280,19 @@ final class MergedAnnotationsCollection implements MergedAnnotations { @Nullable @SuppressWarnings("unchecked") - private MergedAnnotation createMergedAnnotationIfPossible( - int annotationIndex, int mappingIndex) { + private MergedAnnotation createMergedAnnotationIfPossible(int annotationIndex, int mappingIndex) { MergedAnnotation root = annotations[annotationIndex]; - if(mappingIndex == 0) { + if (mappingIndex == 0) { return (MergedAnnotation) root; } - IntrospectionFailureLogger logger = (this.requiredType != null - ? IntrospectionFailureLogger.INFO - : IntrospectionFailureLogger.DEBUG); + IntrospectionFailureLogger logger = (this.requiredType != null ? + IntrospectionFailureLogger.INFO : IntrospectionFailureLogger.DEBUG); return TypeMappedAnnotation.createIfPossible( mappings[annotationIndex].get(mappingIndex), root, logger); } @Override + @Nullable public Spliterator> trySplit() { return null; } @@ -309,7 +313,6 @@ final class MergedAnnotationsCollection implements MergedAnnotations { public int characteristics() { return NONNULL | IMMUTABLE; } - } } diff --git a/spring-core/src/main/java/org/springframework/core/annotation/TypeMappedAnnotation.java b/spring-core/src/main/java/org/springframework/core/annotation/TypeMappedAnnotation.java index 40e7bd356d..0e93da2e54 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/TypeMappedAnnotation.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/TypeMappedAnnotation.java @@ -20,7 +20,6 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.Member; import java.lang.reflect.Method; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; @@ -71,8 +70,6 @@ import org.springframework.util.ReflectionUtils; */ final class TypeMappedAnnotation extends AbstractMergedAnnotation { - private static final Object[] EMPTY_OBJECT_ARRAY = {}; - private static final Map, Object> EMPTY_ARRAYS; static { Map, Object> emptyArrays = new HashMap<>(); @@ -386,7 +383,7 @@ final class TypeMappedAnnotation extends AbstractMergedAnn return (attributeIndex != -1 ? getValue(attributeIndex, type) : null); } - private final Object getRequiredValue(int attributeIndex, String attributeName) { + private Object getRequiredValue(int attributeIndex, String attributeName) { Object value = getValue(attributeIndex, Object.class); if (value == null) { throw new NoSuchElementException("No element at attribute index " @@ -527,7 +524,7 @@ final class TypeMappedAnnotation extends AbstractMergedAnn (attributeType == String[].class && value instanceof Class[])) { return value; } - if(attributeType.isArray() && isEmptyObjectArray(value)) { + if (attributeType.isArray() && isEmptyObjectArray(value)) { return emptyArray(attributeType.getComponentType()); } if (!attributeType.isInstance(value)) { @@ -540,7 +537,7 @@ final class TypeMappedAnnotation extends AbstractMergedAnn } private boolean isEmptyObjectArray(Object value) { - return value instanceof Object[] && Arrays.equals((Object[]) value, EMPTY_OBJECT_ARRAY); + return (value instanceof Object[] && ((Object[]) value).length == 0); } private Object emptyArray(Class componentType) { @@ -556,7 +553,8 @@ final class TypeMappedAnnotation extends AbstractMergedAnn return (MergedAnnotation) value; } AnnotationTypeMapping mapping = AnnotationTypeMappings.forAnnotationType(annotationType).get(0); - return new TypeMappedAnnotation<>(mapping, null, this.source, value, getValueExtractor(value), this.aggregateIndex); + return new TypeMappedAnnotation<>( + mapping, null, this.source, value, getValueExtractor(value), this.aggregateIndex); } private BiFunction getValueExtractor(Object value) { @@ -659,8 +657,8 @@ final class TypeMappedAnnotation extends AbstractMergedAnn } @Nullable - static TypeMappedAnnotation createIfPossible( - AnnotationTypeMapping mapping, @Nullable Object source, Object rootAttribute, + private static TypeMappedAnnotation createIfPossible( + AnnotationTypeMapping mapping, @Nullable Object source, @Nullable Object rootAttribute, BiFunction valueExtractor, int aggregateIndex, IntrospectionFailureLogger logger) { diff --git a/spring-core/src/main/java/org/springframework/core/type/StandardAnnotationMetadata.java b/spring-core/src/main/java/org/springframework/core/type/StandardAnnotationMetadata.java index 22212e83e5..c0f680d260 100644 --- a/spring-core/src/main/java/org/springframework/core/type/StandardAnnotationMetadata.java +++ b/spring-core/src/main/java/org/springframework/core/type/StandardAnnotationMetadata.java @@ -51,8 +51,10 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements private final boolean nestedAnnotationsAsMap; + @Nullable private Set annotationTypes; + /** * Create a new {@code StandardAnnotationMetadata} wrapper for the given Class. * @param introspectedClass the Class to introspect @@ -109,22 +111,20 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements @Nullable public Map getAnnotationAttributes(String annotationName, boolean classValuesAsString) { if (this.nestedAnnotationsAsMap) { - return AnnotationMetadata.super.getAnnotationAttributes(annotationName, - classValuesAsString); + return AnnotationMetadata.super.getAnnotationAttributes(annotationName, classValuesAsString); } return AnnotatedElementUtils.getMergedAnnotationAttributes( - getIntrospectedClass(), annotationName, classValuesAsString, this.nestedAnnotationsAsMap); + getIntrospectedClass(), annotationName, classValuesAsString, false); } @Override @Nullable public MultiValueMap getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) { if (this.nestedAnnotationsAsMap) { - return AnnotationMetadata.super.getAllAnnotationAttributes(annotationName, - classValuesAsString); + return AnnotationMetadata.super.getAllAnnotationAttributes(annotationName, classValuesAsString); } return AnnotatedElementUtils.getAllAnnotationAttributes( - getIntrospectedClass(), annotationName, classValuesAsString, this.nestedAnnotationsAsMap); + getIntrospectedClass(), annotationName, classValuesAsString, false); } @Override diff --git a/spring-core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java b/spring-core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java index b649359ecb..05205aa837 100644 --- a/spring-core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java +++ b/spring-core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java @@ -138,7 +138,7 @@ public class StandardMethodMetadata implements MethodMetadata { return MethodMetadata.super.getAnnotationAttributes(annotationName, classValuesAsString); } return AnnotatedElementUtils.getMergedAnnotationAttributes(this.introspectedMethod, - annotationName, classValuesAsString, this.nestedAnnotationsAsMap); + annotationName, classValuesAsString, false); } @Override @@ -148,7 +148,7 @@ public class StandardMethodMetadata implements MethodMetadata { return MethodMetadata.super.getAllAnnotationAttributes(annotationName, classValuesAsString); } return AnnotatedElementUtils.getAllAnnotationAttributes(this.introspectedMethod, - annotationName, classValuesAsString, this.nestedAnnotationsAsMap); + annotationName, classValuesAsString, false); } } diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java index 93ca1bbedc..025fa05800 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java @@ -91,6 +91,7 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito } @Override + @Nullable public AnnotationVisitor visitAnnotation(String desc, boolean visible) { if (!visible) { return null; diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java index a9df087633..b89c7c14b2 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java @@ -118,6 +118,7 @@ class ClassMetadataReadingVisitor extends ClassVisitor implements ClassMetadata } @Override + @Nullable public AnnotationVisitor visitAnnotation(String desc, boolean visible) { // no-op return new EmptyAnnotationVisitor(); diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/MergedAnnotationReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/MergedAnnotationReadingVisitor.java index eff8d5a16d..4a86118843 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/MergedAnnotationReadingVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/MergedAnnotationReadingVisitor.java @@ -55,9 +55,10 @@ class MergedAnnotationReadingVisitor extends AnnotationVis private final Map attributes = new LinkedHashMap<>(4); - public MergedAnnotationReadingVisitor(ClassLoader classLoader, - @Nullable Object source, Class annotationType, - Consumer> consumer) { + + public MergedAnnotationReadingVisitor(@Nullable ClassLoader classLoader, @Nullable Object source, + Class annotationType, Consumer> consumer) { + super(SpringAsmInfo.ASM_VERSION); this.classLoader = classLoader; this.source = source; @@ -65,6 +66,7 @@ class MergedAnnotationReadingVisitor extends AnnotationVis this.consumer = consumer; } + @Override public void visit(String name, Object value) { if (value instanceof Type) { @@ -79,9 +81,9 @@ class MergedAnnotationReadingVisitor extends AnnotationVis } @Override + @Nullable public AnnotationVisitor visitAnnotation(String name, String descriptor) { - return visitAnnotation(descriptor, - annotation -> this.attributes.put(name, annotation)); + return visitAnnotation(descriptor, annotation -> this.attributes.put(name, annotation)); } @Override @@ -91,61 +93,57 @@ class MergedAnnotationReadingVisitor extends AnnotationVis @Override public void visitEnd() { - MergedAnnotation annotation = MergedAnnotation.of(this.classLoader, - this.source, this.annotationType, this.attributes); + MergedAnnotation annotation = MergedAnnotation.of( + this.classLoader, this.source, this.annotationType, this.attributes); this.consumer.accept(annotation); } @SuppressWarnings("unchecked") - public > void visitEnum(String descriptor, String value, - Consumer consumer) { - + public > void visitEnum(String descriptor, String value, Consumer consumer) { String className = Type.getType(descriptor).getClassName(); Class type = (Class) ClassUtils.resolveClassName(className, this.classLoader); - E enumValue = Enum.valueOf(type, value); - if (enumValue != null) { - consumer.accept(enumValue); - } + consumer.accept(Enum.valueOf(type, value)); } @SuppressWarnings("unchecked") - private AnnotationVisitor visitAnnotation(String descriptor, - Consumer> consumer) { + @Nullable + private AnnotationVisitor visitAnnotation( + String descriptor, Consumer> consumer) { String className = Type.getType(descriptor).getClassName(); if (AnnotationFilter.PLAIN.matches(className)) { return null; } - Class type = (Class) ClassUtils.resolveClassName(className, - this.classLoader); - return new MergedAnnotationReadingVisitor<>(this.classLoader, this.source, type, - consumer); + Class type = (Class) ClassUtils.resolveClassName(className, this.classLoader); + return new MergedAnnotationReadingVisitor<>(this.classLoader, this.source, type, consumer); } - @Nullable @SuppressWarnings("unchecked") + @Nullable static AnnotationVisitor get(@Nullable ClassLoader classLoader, @Nullable Supplier sourceSupplier, String descriptor, boolean visible, Consumer> consumer) { + if (!visible) { return null; } + String typeName = Type.getType(descriptor).getClassName(); if (AnnotationFilter.PLAIN.matches(typeName)) { return null; } - Object source = sourceSupplier != null ? sourceSupplier.get() : null; + + Object source = (sourceSupplier != null ? sourceSupplier.get() : null); try { - Class annotationType = (Class) ClassUtils.forName(typeName, - classLoader); - return new MergedAnnotationReadingVisitor<>(classLoader, source, - annotationType, consumer); + Class annotationType = (Class) ClassUtils.forName(typeName, classLoader); + return new MergedAnnotationReadingVisitor<>(classLoader, source, annotationType, consumer); } catch (ClassNotFoundException | LinkageError ex) { return null; } } + /** * {@link AnnotationVisitor} to deal with array attributes. */ @@ -170,21 +168,19 @@ class MergedAnnotationReadingVisitor extends AnnotationVis @Override public void visitEnum(String name, String descriptor, String value) { - MergedAnnotationReadingVisitor.this.visitEnum(descriptor, value, - enumValue -> this.elements.add(enumValue)); + MergedAnnotationReadingVisitor.this.visitEnum(descriptor, value, this.elements::add); } @Override + @Nullable public AnnotationVisitor visitAnnotation(String name, String descriptor) { - return MergedAnnotationReadingVisitor.this.visitAnnotation(descriptor, - annotation -> this.elements.add(annotation)); + return MergedAnnotationReadingVisitor.this.visitAnnotation(descriptor, this.elements::add); } @Override public void visitEnd() { Class componentType = getComponentType(); - Object[] array = (Object[]) Array.newInstance(componentType, - this.elements.size()); + Object[] array = (Object[]) Array.newInstance(componentType, this.elements.size()); this.consumer.accept(this.elements.toArray(array)); } @@ -193,12 +189,11 @@ class MergedAnnotationReadingVisitor extends AnnotationVis return Object.class; } Object firstElement = this.elements.get(0); - if(firstElement instanceof Enum) { + if (firstElement instanceof Enum) { return ((Enum) firstElement).getDeclaringClass(); } return firstElement.getClass(); } - } } diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java index fce67facd8..b440a0c3e9 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java @@ -85,6 +85,7 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho } @Override + @Nullable public AnnotationVisitor visitAnnotation(final String desc, boolean visible) { if (!visible) { return null; diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadata.java b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadata.java index 923aaf0f37..340eecb6c6 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadata.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadata.java @@ -28,7 +28,7 @@ import org.springframework.lang.Nullable; /** * {@link AnnotationMetadata} created from a - * {@link SimpleAnnotationMetadataReadingVistor}. + * {@link SimpleAnnotationMetadataReadingVisitor}. * * @author Phillip Webb * @since 5.2 @@ -39,8 +39,10 @@ final class SimpleAnnotationMetadata implements AnnotationMetadata { private final int access; + @Nullable private final String enclosingClassName; + @Nullable private final String superClassName; private final boolean independentInnerClass; @@ -53,12 +55,14 @@ final class SimpleAnnotationMetadata implements AnnotationMetadata { private final MergedAnnotations annotations; + @Nullable private Set annotationTypes; - SimpleAnnotationMetadata(String className, int access, String enclosingClassName, - String superClassName, boolean independentInnerClass, String[] interfaceNames, - String[] memberClassNames, MethodMetadata[] annotatedMethods, - MergedAnnotations annotations) { + + SimpleAnnotationMetadata(String className, int access, @Nullable String enclosingClassName, + @Nullable String superClassName, boolean independentInnerClass, String[] interfaceNames, + String[] memberClassNames, MethodMetadata[] annotatedMethods, MergedAnnotations annotations) { + this.className = className; this.access = access; this.enclosingClassName = enclosingClassName; @@ -97,7 +101,7 @@ final class SimpleAnnotationMetadata implements AnnotationMetadata { @Override public boolean isIndependent() { - return this.enclosingClassName == null || this.independentInnerClass; + return (this.enclosingClassName == null || this.independentInnerClass); } @Override diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadataReadingVistor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadataReadingVisitor.java similarity index 89% rename from spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadataReadingVistor.java rename to spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadataReadingVisitor.java index 6b0f2c4b60..402fea42dc 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadataReadingVistor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadataReadingVisitor.java @@ -30,6 +30,7 @@ import org.springframework.core.annotation.MergedAnnotation; import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.type.MethodMetadata; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; @@ -39,7 +40,7 @@ import org.springframework.util.StringUtils; * @author Phillip Webb * @since 5.2 */ -class SimpleAnnotationMetadataReadingVistor extends ClassVisitor { +final class SimpleAnnotationMetadataReadingVisitor extends ClassVisitor { @Nullable private final ClassLoader classLoader; @@ -48,10 +49,12 @@ class SimpleAnnotationMetadataReadingVistor extends ClassVisitor { private int access; + @Nullable private String superClassName; - private String[] interfaceNames; + private String[] interfaceNames = new String[0]; + @Nullable private String enclosingClassName; private boolean independentInnerClass; @@ -62,18 +65,23 @@ class SimpleAnnotationMetadataReadingVistor extends ClassVisitor { private List annotatedMethods = new ArrayList<>(); + @Nullable private SimpleAnnotationMetadata metadata; + @Nullable private Source source; - SimpleAnnotationMetadataReadingVistor(@Nullable ClassLoader classLoader) { + + SimpleAnnotationMetadataReadingVisitor(@Nullable ClassLoader classLoader) { super(SpringAsmInfo.ASM_VERSION); this.classLoader = classLoader; } + @Override public void visit(int version, int access, String name, String signature, @Nullable String supername, String[] interfaces) { + this.className = toClassName(name); this.access = access; if (supername != null && !isInterface(access)) { @@ -107,21 +115,24 @@ class SimpleAnnotationMetadataReadingVistor extends ClassVisitor { } @Override + @Nullable public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { return MergedAnnotationReadingVisitor.get(this.classLoader, this::getSource, descriptor, visible, this.annotations::add); } @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, - String signature, String[] exceptions) { + @Nullable + public MethodVisitor visitMethod( + int access, String name, String descriptor, String signature, String[] exceptions) { + // Skip bridge methods - we're only interested in original // annotation-defining user methods. On JDK 8, we'd otherwise run into // double detection of the same annotated method... if (isBridge(access)) { return null; } - return new SimpleMethodMetadataReadingVistor(this.classLoader, this.className, + return new SimpleMethodMetadataReadingVisitor(this.classLoader, this.className, access, name, descriptor, this.annotatedMethods::add); } @@ -136,6 +147,7 @@ class SimpleAnnotationMetadataReadingVistor extends ClassVisitor { } public SimpleAnnotationMetadata getMetadata() { + Assert.state(this.metadata != null, "AnnotationMetadata not initialized"); return this.metadata; } diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReader.java b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReader.java index 188fedeab0..58bffb0486 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReader.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReader.java @@ -46,14 +46,13 @@ final class SimpleMetadataReader implements MetadataReader { SimpleMetadataReader(Resource resource, @Nullable ClassLoader classLoader) throws IOException { - SimpleAnnotationMetadataReadingVistor visitor = new SimpleAnnotationMetadataReadingVistor(classLoader); + SimpleAnnotationMetadataReadingVisitor visitor = new SimpleAnnotationMetadataReadingVisitor(classLoader); getClassReader(resource).accept(visitor, PARSING_OPTIONS); this.resource = resource; this.annotationMetadata = visitor.getMetadata(); } - private ClassReader getClassReader(Resource resource) - throws IOException, NestedIOException { + private static ClassReader getClassReader(Resource resource) throws IOException { try (InputStream is = new BufferedInputStream(resource.getInputStream())) { try { return new ClassReader(is); @@ -65,6 +64,7 @@ final class SimpleMetadataReader implements MetadataReader { } } + @Override public Resource getResource() { return this.resource; diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadata.java b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadata.java index 3f165483c3..5d1b21d3c0 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadata.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadata.java @@ -22,7 +22,7 @@ import org.springframework.core.type.MethodMetadata; /** * {@link MethodMetadata} created from a - * {@link SimpleMethodMetadataReadingVistor}. + * {@link SimpleMethodMetadataReadingVisitor}. * * @author Phillip Webb * @since 5.2 @@ -39,8 +39,10 @@ final class SimpleMethodMetadata implements MethodMetadata { private final MergedAnnotations annotations; + public SimpleMethodMetadata(String methodName, int access, String declaringClassName, String returnTypeName, MergedAnnotations annotations) { + this.methodName = methodName; this.access = access; this.declaringClassName = declaringClassName; @@ -48,6 +50,7 @@ final class SimpleMethodMetadata implements MethodMetadata { this.annotations = annotations; } + @Override public String getMethodName() { return this.methodName; diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadataReadingVistor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadataReadingVisitor.java similarity index 81% rename from spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadataReadingVistor.java rename to spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadataReadingVisitor.java index dcf9d38dc4..b1b3a2da90 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadataReadingVistor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadataReadingVisitor.java @@ -35,7 +35,7 @@ import org.springframework.lang.Nullable; * @author Phillip Webb * @since 5.2 */ -class SimpleMethodMetadataReadingVistor extends MethodVisitor { +final class SimpleMethodMetadataReadingVisitor extends MethodVisitor { @Nullable private final ClassLoader classLoader; @@ -48,16 +48,17 @@ class SimpleMethodMetadataReadingVistor extends MethodVisitor { private final String descriptor; - private final List> annotations = new ArrayList>( - 4); + private final List> annotations = new ArrayList<>(4); private final Consumer consumer; + @Nullable private Source source; - SimpleMethodMetadataReadingVistor(@Nullable ClassLoader classLoader, - String declaringClassName, int access, String name, String descriptor, - Consumer consumer) { + + SimpleMethodMetadataReadingVisitor(@Nullable ClassLoader classLoader, String declaringClassName, + int access, String name, String descriptor, Consumer consumer) { + super(SpringAsmInfo.ASM_VERSION); this.classLoader = classLoader; this.declaringClassName = declaringClassName; @@ -67,7 +68,9 @@ class SimpleMethodMetadataReadingVistor extends MethodVisitor { this.consumer = consumer; } + @Override + @Nullable public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { return MergedAnnotationReadingVisitor.get(this.classLoader, this::getSource, descriptor, visible, this.annotations::add); @@ -93,6 +96,7 @@ class SimpleMethodMetadataReadingVistor extends MethodVisitor { return source; } + /** * {@link MergedAnnotation} source. */ @@ -104,7 +108,8 @@ class SimpleMethodMetadataReadingVistor extends MethodVisitor { private final String descriptor; - private String string; + @Nullable + private String toStringValue; Source(String declaringClassName, String name, String descriptor) { this.declaringClassName = declaringClassName; @@ -122,25 +127,22 @@ class SimpleMethodMetadataReadingVistor extends MethodVisitor { } @Override - public boolean equals(Object obj) { - if (this == obj) { + public boolean equals(Object other) { + if (this == other) { return true; } - if (obj == null || getClass() != obj.getClass()) { + if (other == null || getClass() != other.getClass()) { return false; } - Source other = (Source) obj; - boolean result = true; - result = result &= this.declaringClassName.equals(other.declaringClassName); - result = result &= this.name.equals(other.name); - result = result &= this.descriptor.equals(other.descriptor); - return result; + Source otherSource = (Source) other; + return (this.declaringClassName.equals(otherSource.declaringClassName) && + this.name.equals(otherSource.name) && this.descriptor.equals(otherSource.descriptor)); } @Override public String toString() { - String string = this.string; - if (string == null) { + String value = this.toStringValue; + if (value == null) { StringBuilder builder = new StringBuilder(); builder.append(this.declaringClassName); builder.append("."); @@ -151,12 +153,11 @@ class SimpleMethodMetadataReadingVistor extends MethodVisitor { builder.append(type.getClassName()); } builder.append(")"); - string = builder.toString(); - this.string = string; + value = builder.toString(); + this.toStringValue = value; } - return string; + return value; } - } } diff --git a/spring-core/src/test/java/org/springframework/core/type/classreading/SimpleAnnotationMetadataTests.java b/spring-core/src/test/java/org/springframework/core/type/classreading/SimpleAnnotationMetadataTests.java index 06a692c4ce..59726d6763 100644 --- a/spring-core/src/test/java/org/springframework/core/type/classreading/SimpleAnnotationMetadataTests.java +++ b/spring-core/src/test/java/org/springframework/core/type/classreading/SimpleAnnotationMetadataTests.java @@ -18,11 +18,10 @@ package org.springframework.core.type.classreading; import org.springframework.core.type.AbstractAnnotationMetadataTests; import org.springframework.core.type.AnnotationMetadata; -import org.springframework.core.type.classreading.SimpleMetadataReaderFactory; /** * Tests for {@link SimpleAnnotationMetadata} and - * {@link SimpleAnnotationMetadataReadingVistor}. + * {@link SimpleAnnotationMetadataReadingVisitor}. * * @author Phillip Webb */ diff --git a/spring-core/src/test/java/org/springframework/core/type/classreading/SimpleMethodMetadataTests.java b/spring-core/src/test/java/org/springframework/core/type/classreading/SimpleMethodMetadataTests.java index f99c0bffc4..3118a460a0 100644 --- a/spring-core/src/test/java/org/springframework/core/type/classreading/SimpleMethodMetadataTests.java +++ b/spring-core/src/test/java/org/springframework/core/type/classreading/SimpleMethodMetadataTests.java @@ -18,11 +18,10 @@ package org.springframework.core.type.classreading; import org.springframework.core.type.AbstractMethodMetadataTests; import org.springframework.core.type.AnnotationMetadata; -import org.springframework.core.type.classreading.SimpleMetadataReaderFactory; /** * Tests for {@link SimpleMethodMetadata} and - * {@link SimpleMethodMetadataReadingVistor}. + * {@link SimpleMethodMetadataReadingVisitor}. * * @author Phillip Webb */