Spring-Metadata
Spring 元信息
- Author: HuiFer
- 源码阅读仓库: SourceHot-Spring
ClassMetadata
|
|
AnnotatedTypeMetadata
|
|
AnnotationMetadata
|
|
MethodMetadata
|
|
MetadataReader
|
|
MetadataReaderFactory
- 用来创建 MetadataReader
|
|
- 接口解释的差不多了.接下来看一些实现
StandardClassMetadata
-
通过 JAVA 反射来获取类的元信息
-
这个类采用的方式是 Java class 的方法,通过构造方法来填写一个 Class 对象. 之后使用这个对象的方法
|
|
StandardMethodMetadata
- 通过 java 反射获取方法的元信息
- 构造方法传递一个 method
- 如果这个方法有注解,会进行注解的解析
|
|
StandardAnnotationMetadata
-
StandardAnnotationMetadata 是 StandardClassMetadata 的子类
-
还是一个基于 JAVA 反射做的一个类
-
获取注解属性 map
|
|
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
|
|
- 查看这个方法的源码借助测试类
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)
-
最终我们找到的代码如下
|
|
- 判断是否为空. 为空返回 None,不会为空构造出一个对象 org.springframework.core.annotation.TypeMappedAnnotations
MergedAnnotations
|
|
-
这个接口中还有两个方法
-
of
将多个MergedAnnotations
合并 -
from
将多个注解合并
-
SearchStrategy
|
|
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>)
|
|
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<?>>)
|
|
在这个里面重点关注PROCESS
方法
|
|
测试类
|
|
显然这是一个类他会走processClass
方法
- 根据扫描方式进行扫描
|
|
- 扫描的形式就不贴出完整代码了
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...)
|
|
|
|
-
获取属性列表,循环, 放入 map 返回.
map
key: 注解的函数
value: 函数对应的值
|
|
|
|
如果是上面这样的结构那么返回值为
|
|
SimpleMetadataReader
-
构造方法传递三个参数直接使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
final class SimpleMetadataReader implements MetadataReader { private static final int PARSING_OPTIONS = ClassReader.SKIP_DEBUG | ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES; private final Resource resource; private final AnnotationMetadata annotationMetadata; SimpleMetadataReader(Resource resource, @Nullable ClassLoader classLoader) throws IOException { SimpleAnnotationMetadataReadingVisitor visitor = new SimpleAnnotationMetadataReadingVisitor(classLoader); getClassReader(resource).accept(visitor, PARSING_OPTIONS); this.resource = resource; this.annotationMetadata = visitor.getMetadata(); } private static ClassReader getClassReader(Resource resource) throws IOException { try (InputStream is = new BufferedInputStream(resource.getInputStream())) { try { return new ClassReader(is); } catch (IllegalArgumentException ex) { throw new NestedIOException("ASM ClassReader failed to parse class file - " + "probably due to a new Java class file version that isn't supported yet: " + resource, ex); } } } @Override public Resource getResource() { return this.resource; } @Override public ClassMetadata getClassMetadata() { return this.annotationMetadata; } @Override public AnnotationMetadata getAnnotationMetadata() { return this.annotationMetadata; } }
SimpleMetadataReaderFactory
- 关注点为如何获取
MetadataReader
- 通过资源直接 new 出来
- 通过 className 转换成资源地址,
- 将资源地址转换成
Resource
对象 - new 出来
|
|
- 原文作者:知识铺
- 原文链接:https://geek.zshipu.com/post/code/docs/Spring/clazz/Spring-Metadata/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。
- 免责声明:本页面内容均来源于站内编辑发布,部分信息来源互联网,并不意味着本站赞同其观点或者证实其内容的真实性,如涉及版权等问题,请立即联系客服进行更改或删除,保证您的合法权益。转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。也可以邮件至 sblig@126.com