经常这么使用得到注解里面所有的属性值:
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(annoMetadata, annType);
方法的元数据接口
public interface MethodMetadata extends AnnotatedTypeMetadata { String getMethodName(); // Return the fully-qualified name of the class that declares this method. String getDeclaringClassName(); // Return the fully-qualified name of this method's declared return type. String getReturnTypeName(); boolean isAbstract(); boolean isStatic(); boolean isFinal(); boolean isOverridable(); }这个接口有两个实现:
StandardMethodMetadata:基于反射的标准实现;
MethodMetadataReadingVisitor:基于ASM的实现的,继承自ASM``的org.springframework.asm.MethodVisitor采用Visitor的方式读取到元数据。
元数据,是框架设计中必须的一个概念,所有的流行框架里都能看到它的影子,包括且不限于Spring、SpringBoot、SpringCloud、MyBatis、Hibernate等。它能模糊掉具体的类型,能让数据输出变得统一,能解决Java抽象解决不了的问题,比如运用得最广的便是注解,因为它不能继承无法抽象,所以用元数据方式就可以完美行成统一的向上抽取让它变得与类型无关,也就是常说的模糊效果,这便是框架的核心设计思想。
不管是ClassMetadata还是AnnotatedTypeMetadata都会有基于反射和基于ASM的两种解决方案,他们能使用于不同的场景:
标准反射:它依赖于Class,优点是实现简单,缺点是使用时必须把Class加载进来。
ASM:无需提前加载Class入JVM,所有特别特别适用于形如Spring应用扫描的场景(扫描所有资源,但并不是加载所有进JVM/容器~)
MetadataReaderspring 对MetadataReader的描述为:Simple facade for accessing class metadata,as read by an ASM.大意是通过ASM读取class IO流资源组装访问元数据的门面接口
类关系图 MetadataReader接口方法 public interface MetadataReader { /** * 返回class文件的IO资源引用 */ Resource getResource(); /** * 为基础class读取基本类元数据,返回基础类的元数据。 */ ClassMetadata getClassMetadata(); /** *为基础类读取完整的注释元数据,包括注释方法的元数据。返回基础类的完整注释元数据 */ AnnotationMetadata getAnnotationMetadata(); }MetadataReader接口提供三个方法:
返回class文件的IO资源引用
返回基础类的元数据
返回基础类的完整注释元数据
SimpleMetadataReader final class SimpleMetadataReader implements MetadataReader { //class类IO流资源引用 private final Resource resource; //class类元数据 private final ClassMetadata classMetadata; //class类完整注释元数据 private final AnnotationMetadata annotationMetadata; /** * 构建函数,用于通过过ASM字节码操控框架读取class读取class资源流 */ SimpleMetadataReader(Resource resource, @Nullable ClassLoader classLoader) throws IOException { // 获取class类IO流 InputStream is = new BufferedInputStream(resource.getInputStream()); ClassReader classReader; try { //通过ASM字节码操控框架读取class classReader = new ClassReader(is); } catch (IllegalArgumentException ex) { } finally { is.close(); } //注解元数据读取访问者读取注解元数据 AnnotationMetadataReadingVisitor visitor = new AnnotationMetadataReadingVisitor(classLoader); classReader.accept(visitor,ClassReader.SKIP_DEBUG); //注解元数据 this.annotationMetadata = visitor; //class元数据 this.classMetadata = visitor; this.resource = resource; } @Override public Resource getResource() { return this.resource; } @Override public ClassMetadata getClassMetadata() { //返回当前类元数据 return this.classMetadata; } @Override public AnnotationMetadata getAnnotationMetadata() { //返回当前类的注解元数据 return this.annotationMetadata; } }