Skip to content

Latest commit

 

History

History
872 lines (689 loc) · 24.8 KB

Spring-Metadata.md

File metadata and controls

872 lines (689 loc) · 24.8 KB

Spring 元信息

ClassMetadata

publicinterfaceClassMetadata { /** * 类名 */StringgetClassName(); /** * 是否是接口 */booleanisInterface(); /** * 是否是注解 */booleanisAnnotation(); /** * 是否是超类 */booleanisAbstract(); /** * 是否允许创建,实例化 */defaultbooleanisConcrete() { return !(isInterface() || isAbstract()); } /** * 是否有final修饰 */booleanisFinal(); /** * 是否独立 */booleanisIndependent(); /** * 是否有内部类 */defaultbooleanhasEnclosingClass() { return (getEnclosingClassName() != null); } /** * 是否是基础类 */@NullableStringgetEnclosingClassName(); /** * 是否有父类 */defaultbooleanhasSuperClass() { return (getSuperClassName() != null); } /** * 父类名称 */@NullableStringgetSuperClassName(); /** * 实现类名称列表 */String[] getInterfaceNames(); /** * 成员列表 * @since 3.1 */String[] getMemberClassNames(); }

image-20200824094154847

AnnotatedTypeMetadata

publicinterfaceAnnotatedTypeMetadata { /** * 获取所有注解 */MergedAnnotationsgetAnnotations(); /** * 是否有注解 */defaultbooleanisAnnotated(StringannotationName) { returngetAnnotations().isPresent(annotationName); } /** * 获取注解的属性 */@NullabledefaultMap<String, Object> getAnnotationAttributes(StringannotationName) { returngetAnnotationAttributes(annotationName, false); } // 省略其他 }

AnnotationMetadata

publicinterfaceAnnotationMetadataextendsClassMetadata, AnnotatedTypeMetadata { /** * 获取注解名称,全类名 */defaultSet<String> getAnnotationTypes() { returngetAnnotations().stream() .filter(MergedAnnotation::isDirectlyPresent) .map(annotation -> annotation.getType().getName()) .collect(Collectors.toCollection(LinkedHashSet::new)); } /** * 注解全类名 */defaultSet<String> getMetaAnnotationTypes(StringannotationName) { MergedAnnotation<?> annotation = getAnnotations().get(annotationName, MergedAnnotation::isDirectlyPresent); if (!annotation.isPresent()) { returnCollections.emptySet(); } returnMergedAnnotations.from(annotation.getType(), SearchStrategy.INHERITED_ANNOTATIONS).stream() .map(mergedAnnotation -> mergedAnnotation.getType().getName()) .collect(Collectors.toCollection(LinkedHashSet::new)); } /** * 是否包含某个注解 */defaultbooleanhasAnnotation(StringannotationName) { returngetAnnotations().isDirectlyPresent(annotationName); } /** * 是否被某个注解标记过 */defaultbooleanhasMetaAnnotation(StringmetaAnnotationName) { returngetAnnotations().get(metaAnnotationName, MergedAnnotation::isMetaPresent).isPresent(); } /** * 是否有注解,类里面有一个注解就返回true */defaultbooleanhasAnnotatedMethods(StringannotationName) { return !getAnnotatedMethods(annotationName).isEmpty(); } /** * 获取包含注解的方法 */Set<MethodMetadata> getAnnotatedMethods(StringannotationName); /** * 通过反射创建一个注解的元信息 */staticAnnotationMetadataintrospect(Class<?> type) { returnStandardAnnotationMetadata.from(type); } }

MethodMetadata

publicinterfaceMethodMetadataextendsAnnotatedTypeMetadata { /** * 方法名称 */StringgetMethodName(); /** * 方法全路径 */StringgetDeclaringClassName(); /** * 返回值类型 */StringgetReturnTypeName(); /** * 是不是abstrac修饰 */booleanisAbstract(); /** * 是否 static 修饰 */booleanisStatic(); /** * 是否 final 修饰 */booleanisFinal(); /** * 是否重载 */booleanisOverridable(); }

MetadataReader

publicinterfaceMetadataReader { /** * Return the resource reference for the class file. * * 获取资源 */ResourcegetResource(); /** * Read basic class metadata for the underlying class. * 获取类的元信息 */ClassMetadatagetClassMetadata(); /** * Read full annotation metadata for the underlying class, * including metadata for annotated methods. * * 获取注解的元信息 */AnnotationMetadatagetAnnotationMetadata(); }

MetadataReaderFactory

  • 用来创建 MetadataReader
publicinterfaceMetadataReaderFactory { /** * Obtain a MetadataReader for the given class name. * @param className the class name (to be resolved to a ".class" file) * @return a holder for the ClassReader instance (never {@code null}) * @throws IOException in case of I/O failure */MetadataReadergetMetadataReader(StringclassName) throwsIOException; /** * Obtain a MetadataReader for the given resource. * @param resource the resource (pointing to a ".class" file) * @return a holder for the ClassReader instance (never {@code null}) * @throws IOException in case of I/O failure */MetadataReadergetMetadataReader(Resourceresource) throwsIOException; }
  • 接口解释的差不多了.接下来看一些实现

StandardClassMetadata

  • 通过 JAVA 反射来获取类的元信息

  • 这个类采用的方式是 Java class 的方法,通过构造方法来填写一个 Class 对象. 之后使用这个对象的方法

publicclassStandardClassMetadataimplementsClassMetadata { privatefinalClass<?> introspectedClass; @DeprecatedpublicStandardClassMetadata(Class<?> introspectedClass) { Assert.notNull(introspectedClass, "Class must not be null"); this.introspectedClass = introspectedClass; } /** * Return the underlying Class. */publicfinalClass<?> getIntrospectedClass() { returnthis.introspectedClass; } @OverridepublicStringgetClassName() { returnthis.introspectedClass.getName(); } @OverridepublicbooleanisInterface() { returnthis.introspectedClass.isInterface(); } @OverridepublicbooleanisAnnotation() { returnthis.introspectedClass.isAnnotation(); } @OverridepublicbooleanisAbstract() { returnModifier.isAbstract(this.introspectedClass.getModifiers()); } @OverridepublicbooleanisFinal() { returnModifier.isFinal(this.introspectedClass.getModifiers()); } @OverridepublicbooleanisIndependent() { return (!hasEnclosingClass() || (this.introspectedClass.getDeclaringClass() != null && Modifier.isStatic(this.introspectedClass.getModifiers()))); } @Override@NullablepublicStringgetEnclosingClassName() { Class<?> enclosingClass = this.introspectedClass.getEnclosingClass(); return (enclosingClass != null ? enclosingClass.getName() : null); } @Override@NullablepublicStringgetSuperClassName() { Class<?> superClass = this.introspectedClass.getSuperclass(); return (superClass != null ? superClass.getName() : null); } @OverridepublicString[] getInterfaceNames() { Class<?>[] ifcs = this.introspectedClass.getInterfaces(); String[] ifcNames = newString[ifcs.length]; for (inti = 0; i < ifcs.length; i++) { ifcNames[i] = ifcs[i].getName(); } returnifcNames; } @OverridepublicString[] getMemberClassNames() { LinkedHashSet<String> memberClassNames = newLinkedHashSet<>(4); for (Class<?> nestedClass : this.introspectedClass.getDeclaredClasses()) { memberClassNames.add(nestedClass.getName()); } returnStringUtils.toStringArray(memberClassNames); } }

StandardMethodMetadata

  • 通过 java 反射获取方法的元信息
  • 构造方法传递一个 method
    • 如果这个方法有注解,会进行注解的解析
publicclassStandardMethodMetadataimplementsMethodMetadata { privatefinalMethodintrospectedMethod; privatefinalbooleannestedAnnotationsAsMap; privatefinalMergedAnnotationsmergedAnnotations; @DeprecatedpublicStandardMethodMetadata(MethodintrospectedMethod) { this(introspectedMethod, false); } @DeprecatedpublicStandardMethodMetadata(MethodintrospectedMethod, booleannestedAnnotationsAsMap) { Assert.notNull(introspectedMethod, "Method must not be null"); this.introspectedMethod = introspectedMethod; this.nestedAnnotationsAsMap = nestedAnnotationsAsMap; this.mergedAnnotations = MergedAnnotations.from( introspectedMethod, SearchStrategy.DIRECT, RepeatableContainers.none()); } @OverridepublicMergedAnnotationsgetAnnotations() { returnthis.mergedAnnotations; } /** * Return the underlying Method. */publicfinalMethodgetIntrospectedMethod() { returnthis.introspectedMethod; } @OverridepublicStringgetMethodName() { returnthis.introspectedMethod.getName(); } @OverridepublicStringgetDeclaringClassName() { returnthis.introspectedMethod.getDeclaringClass().getName(); } @OverridepublicStringgetReturnTypeName() { returnthis.introspectedMethod.getReturnType().getName(); } @OverridepublicbooleanisAbstract() { returnModifier.isAbstract(this.introspectedMethod.getModifiers()); } @OverridepublicbooleanisStatic() { returnModifier.isStatic(this.introspectedMethod.getModifiers()); } @OverridepublicbooleanisFinal() { returnModifier.isFinal(this.introspectedMethod.getModifiers()); } @OverridepublicbooleanisOverridable() { return !isStatic() && !isFinal() && !isPrivate(); } privatebooleanisPrivate() { returnModifier.isPrivate(this.introspectedMethod.getModifiers()); } @Override@NullablepublicMap<String, Object> getAnnotationAttributes(StringannotationName, booleanclassValuesAsString) { if (this.nestedAnnotationsAsMap) { returnMethodMetadata.super.getAnnotationAttributes(annotationName, classValuesAsString); } returnAnnotatedElementUtils.getMergedAnnotationAttributes(this.introspectedMethod, annotationName, classValuesAsString, false); } /** * 获取所有注解的信息 */@Override@NullablepublicMultiValueMap<String, Object> getAllAnnotationAttributes(StringannotationName, booleanclassValuesAsString) { if (this.nestedAnnotationsAsMap) { returnMethodMetadata.super.getAllAnnotationAttributes(annotationName, classValuesAsString); } returnAnnotatedElementUtils.getAllAnnotationAttributes(this.introspectedMethod, annotationName, classValuesAsString, false); } }

StandardAnnotationMetadata

  • StandardAnnotationMetadata 是 StandardClassMetadata 的子类

  • 还是一个基于 JAVA 反射做的一个类

  • 获取注解属性 map

@Override@NullablepublicMap<String, Object> getAnnotationAttributes(StringannotationName, booleanclassValuesAsString) { if (this.nestedAnnotationsAsMap) { returnAnnotationMetadata.super.getAnnotationAttributes(annotationName, classValuesAsString); } returnAnnotatedElementUtils.getMergedAnnotationAttributes( getIntrospectedClass(), annotationName, classValuesAsString, false); }
  • org.springframework.core.annotation.AnnotatedElementUtils#getMergedAnnotationAttributes(java.lang.reflect.AnnotatedElement, java.lang.String, boolean, boolean)
    • org.springframework.core.annotation.AnnotatedElementUtils#getAnnotationAttributes
      • org.springframework.core.annotation.MergedAnnotation#asAnnotationAttributes
@NullablepublicstaticAnnotationAttributesgetMergedAnnotationAttributes(AnnotatedElementelement, StringannotationName, booleanclassValuesAsString, booleannestedAnnotationsAsMap) { MergedAnnotation<?> mergedAnnotation = getAnnotations(element) .get(annotationName, null, MergedAnnotationSelectors.firstDirectlyDeclared()); returngetAnnotationAttributes(mergedAnnotation, classValuesAsString, nestedAnnotationsAsMap); }
  • 查看这个方法的源码借助测试类org.springframework.core.annotation.AnnotatedElementUtilsTests#getMergedAnnotationAttributesOnClassWithLocalAnnotation
  • getAnnotations() 方法

getAnnotations

  • org.springframework.core.annotation.MergedAnnotations#from(java.lang.reflect.AnnotatedElement, org.springframework.core.annotation.MergedAnnotations.SearchStrategy, org.springframework.core.annotation.RepeatableContainers)

    • org.springframework.core.annotation.TypeMappedAnnotations#from(java.lang.reflect.AnnotatedElement, org.springframework.core.annotation.MergedAnnotations.SearchStrategy, org.springframework.core.annotation.RepeatableContainers, org.springframework.core.annotation.AnnotationFilter)
  • 最终我们找到的代码如下

staticMergedAnnotationsfrom(AnnotatedElementelement, SearchStrategysearchStrategy, RepeatableContainersrepeatableContainers, AnnotationFilterannotationFilter) { if (AnnotationsScanner.isKnownEmpty(element, searchStrategy)) { returnNONE; } returnnewTypeMappedAnnotations(element, searchStrategy, repeatableContainers, annotationFilter); }
  • 判断是否为空. 为空返回 None,不会为空构造出一个对象 org.springframework.core.annotation.TypeMappedAnnotations

MergedAnnotations

publicinterfaceMergedAnnotationsextendsIterable<MergedAnnotation<Annotation>> { //确定注解是否存在 <AextendsAnnotation> booleanisPresent(Class<A> annotationType); //注解是否直接存在 <AextendsAnnotation> booleanisDirectlyPresent(Class<A> annotationType); // 获取匹配的注解 <AextendsAnnotation> MergedAnnotation<A> get(Class<A> annotationType); // 省略其他 }
  • 这个接口中还有两个方法

    1. of 将多个MergedAnnotations合并

    2. from

      将多个注解合并

SearchStrategy

enumSearchStrategy { /** * Find only directly declared annotations, without considering * {@link Inherited @Inherited} annotations and without searching * superclasses or implemented interfaces. * * 直接查找 */DIRECT, /** * Find all directly declared annotations as well as any * {@link Inherited @Inherited} superclass annotations. This strategy * is only really useful when used with {@link Class} types since the * {@link Inherited @Inherited} annotation is ignored for all other * {@linkplain AnnotatedElement annotated elements}. This strategy does * not search implemented interfaces. * * 继承查找 */INHERITED_ANNOTATIONS, /** * Find all directly declared and superclass annotations. This strategy * is similar to {@link #INHERITED_ANNOTATIONS} except the annotations * do not need to be meta-annotated with {@link Inherited @Inherited}. * This strategy does not search implemented interfaces. * 查找当前类和父类的注解 */SUPERCLASS, /** * Perform a full search of the entire type hierarchy, including * superclasses and implemented interfaces. Superclass annotations do * not need to be meta-annotated with {@link Inherited @Inherited}. */TYPE_HIERARCHY, /** * Perform a full search of the entire type hierarchy on the source * <em>and</em> any enclosing classes. This strategy is similar to * {@link #TYPE_HIERARCHY} except that {@linkplain Class#getEnclosingClass() * enclosing classes} are also searched. Superclass annotations do not * need to be meta-annotated with {@link Inherited @Inherited}. When * searching a {@link Method} source, this strategy is identical to * {@link #TYPE_HIERARCHY}. */TYPE_HIERARCHY_AND_ENCLOSING_CLASSES }
  • org.springframework.core.annotation.TypeMappedAnnotations#get(java.lang.String, java.util.function.Predicate<? super org.springframework.core.annotation.MergedAnnotation<A>>, org.springframework.core.annotation.MergedAnnotationSelector<A>)
@Overridepublic <AextendsAnnotation> MergedAnnotation<A> get(StringannotationType, @NullablePredicate<? superMergedAnnotation<A>> predicate, @NullableMergedAnnotationSelector<A> selector) { // 匹配校验if (this.annotationFilter.matches(annotationType)) { returnMergedAnnotation.missing(); } MergedAnnotation<A> result = scan(annotationType, newMergedAnnotationFinder<>(annotationType, predicate, selector)); return (result != null ? result : MergedAnnotation.missing()); }

Scan

org.springframework.core.annotation.AnnotationsScanner#scan(C, java.lang.reflect.AnnotatedElement, org.springframework.core.annotation.MergedAnnotations.SearchStrategy, org.springframework.core.annotation.AnnotationsProcessor<C,R>, java.util.function.BiPredicate<C,java.lang.Class<?>>)

@Nullablestatic <C, R> Rscan(Ccontext, AnnotatedElementsource, SearchStrategysearchStrategy, AnnotationsProcessor<C, R> processor, @NullableBiPredicate<C, Class<?>> classFilter) { Rresult = process(context, source, searchStrategy, processor, classFilter); returnprocessor.finish(result); }

在这个里面重点关注PROCESS方法

@Nullableprivatestatic <C, R> Rprocess(Ccontext, AnnotatedElementsource, SearchStrategysearchStrategy, AnnotationsProcessor<C, R> processor, @NullableBiPredicate<C, Class<?>> classFilter) { if (sourceinstanceofClass) { returnprocessClass(context, (Class<?>) source, searchStrategy, processor, classFilter); } if (sourceinstanceofMethod) { returnprocessMethod(context, (Method) source, searchStrategy, processor, classFilter); } returnprocessElement(context, source, processor, classFilter); }

测试类

@Transactional("TxConfig") staticclassTxConfig { }

显然这是一个类他会走processClass方法

  • 根据扫描方式进行扫描
@Nullableprivatestatic <C, R> RprocessClass(Ccontext, Class<?> source, SearchStrategysearchStrategy, AnnotationsProcessor<C, R> processor, @NullableBiPredicate<C, Class<?>> classFilter) { switch (searchStrategy) { caseDIRECT: returnprocessElement(context, source, processor, classFilter); caseINHERITED_ANNOTATIONS: returnprocessClassInheritedAnnotations(context, source, searchStrategy, processor, classFilter); caseSUPERCLASS: returnprocessClassHierarchy(context, source, processor, classFilter, false, false); caseTYPE_HIERARCHY: returnprocessClassHierarchy(context, source, processor, classFilter, true, false); caseTYPE_HIERARCHY_AND_ENCLOSING_CLASSES: returnprocessClassHierarchy(context, source, processor, classFilter, true, true); } thrownewIllegalStateException("Unsupported search strategy " + searchStrategy); }
  • 扫描的形式就不贴出完整代码了

finish就包装一下返回.

  • 此时org.springframework.core.annotation.AnnotatedElementUtils#getMergedAnnotationAttributes(java.lang.reflect.AnnotatedElement, java.lang.String, boolean, boolean)这个方法走到了最后一步org.springframework.core.annotation.AnnotatedElementUtils#getAnnotationAttributes

  • 最后的组装 map 方法

    org.springframework.core.annotation.TypeMappedAnnotation#asMap(java.util.function.Function<org.springframework.core.annotation.MergedAnnotation<?>,T>, org.springframework.core.annotation.MergedAnnotation.Adapt...)

@OverridepublicAnnotationAttributesasAnnotationAttributes(Adapt... adaptations) { returnasMap(mergedAnnotation -> newAnnotationAttributes(mergedAnnotation.getType()), adaptations); }
@Overridepublic <TextendsMap<String, Object>> TasMap(Function<MergedAnnotation<?>, T> factory, Adapt... adaptations) { Tmap = factory.apply(this); Assert.state(map != null, "Factory used to create MergedAnnotation Map must not return null"); AttributeMethodsattributes = this.mapping.getAttributes(); for (inti = 0; i < attributes.size(); i++) { Methodattribute = attributes.get(i); Objectvalue = (isFiltered(attribute.getName()) ? null : getValue(i, getTypeForMapOptions(attribute, adaptations))); if (value != null) { map.put(attribute.getName(), adaptValueForMapOptions(attribute, value, map.getClass(), factory, adaptations)); } } returnmap; }
  • 获取属性列表,循环, 放入 map 返回.

    map

    ​ key: 注解的函数

    ​ value: 函数对应的值

@Transactional("TxConfig")
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) @Inherited @interface Transactional { Stringvalue() default""; Stringqualifier() default"transactionManager"; booleanreadOnly() defaultfalse; }

如果是上面这样的结构那么返回值为

value:TxConfigqulifiter:transactionManagerreadOnlay:false

image-20200824104529315

SimpleMetadataReader

  • 构造方法传递三个参数直接使用

    finalclassSimpleMetadataReaderimplementsMetadataReader { privatestaticfinalintPARSING_OPTIONS = ClassReader.SKIP_DEBUG | ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES; privatefinalResourceresource; privatefinalAnnotationMetadataannotationMetadata; SimpleMetadataReader(Resourceresource, @NullableClassLoaderclassLoader) throwsIOException { SimpleAnnotationMetadataReadingVisitorvisitor = newSimpleAnnotationMetadataReadingVisitor(classLoader); getClassReader(resource).accept(visitor, PARSING_OPTIONS); this.resource = resource; this.annotationMetadata = visitor.getMetadata(); } privatestaticClassReadergetClassReader(Resourceresource) throwsIOException { try (InputStreamis = newBufferedInputStream(resource.getInputStream())) { try { returnnewClassReader(is); } catch (IllegalArgumentExceptionex) { thrownewNestedIOException("ASM ClassReader failed to parse class file - " + "probably due to a new Java class file version that isn't supported yet: " + resource, ex); } } } @OverridepublicResourcegetResource() { returnthis.resource; } @OverridepublicClassMetadatagetClassMetadata() { returnthis.annotationMetadata; } @OverridepublicAnnotationMetadatagetAnnotationMetadata() { returnthis.annotationMetadata; } }

SimpleMetadataReaderFactory

  • 关注点为如何获取MetadataReader
    1. 通过资源直接 new 出来
    2. 通过 className 转换成资源地址,
    3. 将资源地址转换成Resource对象
    4. new 出来
@OverridepublicMetadataReadergetMetadataReader(StringclassName) throwsIOException { try { StringresourcePath = ResourceLoader.CLASSPATH_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(className) + ClassUtils.CLASS_FILE_SUFFIX; Resourceresource = this.resourceLoader.getResource(resourcePath); returngetMetadataReader(resource); } catch (FileNotFoundExceptionex) { // Maybe an inner class name using the dot name syntax? Need to use the dollar syntax here...// ClassUtils.forName has an equivalent check for resolution into Class references later on.intlastDotIndex = className.lastIndexOf('.'); if (lastDotIndex != -1) { StringinnerClassName = className.substring(0, lastDotIndex) + '$' + className.substring(lastDotIndex + 1); StringinnerClassResourcePath = ResourceLoader.CLASSPATH_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(innerClassName) + ClassUtils.CLASS_FILE_SUFFIX; ResourceinnerClassResource = this.resourceLoader.getResource(innerClassResourcePath); if (innerClassResource.exists()) { returngetMetadataReader(innerClassResource); } } throwex; } } @OverridepublicMetadataReadergetMetadataReader(Resourceresource) throwsIOException { returnnewSimpleMetadataReader(resource, this.resourceLoader.getClassLoader()); }
close