MetadataReaderClassMetadataAnnotationMetadata的简单使用

Posted 默辨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MetadataReaderClassMetadataAnnotationMetadata的简单使用相关的知识,希望对你有一定的参考价值。

在Spring源码中有很多场景会去解析类的信息,比如类名、类中的方法、类上的注解,这些都可以称之为类的元数据,在Spring中对类的元数据做了抽象,并提供了一些工具类。



MetadataReader表示类的元数据读取器,默认实现类为SimpleMetadataReader


测试代码如下:

// 自定义注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Pan
public @interface Qiu {
}


// 目标类
@JsonFormat
@Service
@Transactional(rollbackFor = Exception.class)
@Qiu
@Generated
public class MobianServiceImpl implements MobianService {

    ....
}

public class Test {
	public static void main(String[] args) throws IOException, IOException {

		SimpleMetadataReaderFactory readerFactory = new SimpleMetadataReaderFactory();
        
        // 使用工厂构建一个metadataReader读取器
		MetadataReader metadataReader = readerFactory.getMetadataReader("pers.mobian.testtransactional.service.MobianServiceImpl");
		
        
        System.out.println("-----获取类的基本信息----");
		ClassMetadata classMetadata = metadataReader.getClassMetadata();
		// 判断是否是接口
		System.out.println(classMetadata.isInterface());
		// 判断是否是抽象类
		System.out.println(classMetadata.isAbstract());
		// 获取类的名字
		System.out.println(classMetadata.getClassName());

		
        System.out.println("-----获取类的注解信息----");
		AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();

		// 类上注解的元注解是否含有对应的注解(即针对注解的父注解)
		System.out.println(annotationMetadata.hasMetaAnnotation(Pan.class.getName()));
		// 类上是否有对应的注解
		System.out.println(annotationMetadata.hasAnnotation(Pan.class.getName()));

		for (String annotationType : annotationMetadata.getAnnotationTypes()) {
			// 打印类上的注解
			System.out.println(annotationType);
		}

		
        System.out.println("-----获取类的资源信息----");
		Resource resource = metadataReader.getResource();
        // 打印类的名字
		System.out.println(resource.getFilename());
	}
}



打印结果:



注意:

1、hasMetaAnnotation可以理解为是用来判断注解的父注解信息,hasAnnotation是用来判断当前类的注解信息。上面的测试案例中,目标类没有@Pan这个注解,但是修饰类的@Qiu的注解被@Pan注解修饰,所以前者打印true,后者打印false

 // 使用元方法读取器读取注解信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();

// 
System.out.println(annotationMetadata.hasMetaAnnotation(Pan.class.getName()));
System.out.println(annotationMetadata.hasAnnotation(Pan.class.getName()));

2、在获取类上注解的时候,类上的注解需要被@Retention(RetentionPolicy.RUNTIME)注解修饰才能被扫描出来。我的理解是,由于该工具类的底层是使用ASM技术去获取类的class文件信息,继而完成信息的获取,如果我Retention设置为CLASS或者SOURCE,其底层在使用ASM技术去JVM中获取对应信息时,获取不到对应的class文件,以至于扫描不到对应的注解信息。

for (String annotationType : annotationMetadata.getAnnotationTypes()) {
    // 打印类上的注解
    System.out.println(annotationType);
}

以上是关于MetadataReaderClassMetadataAnnotationMetadata的简单使用的主要内容,如果未能解决你的问题,请参考以下文章