MetadataReader、ClassMetadata、AnnotationMetadata的简单使用

在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);
}
Spring 应用程序中使用 CachingMetadataReaderFactory 很简单。我们可以通过以下步骤来使用: 1. 首先,在 Spring 的配置文件中配置 CachingMetadataReaderFactoryBean,例如: ```xml <bean id="metadataReaderFactory" class="org.springframework.context.annotation.AnnotationConfigApplicationContext"> <property name="metadataReaderFactory" ref="cachingMetadataReaderFactory"/> </bean> <bean id="cachingMetadataReaderFactory" class="org.springframework.context.annotation.CachingMetadataReaderFactoryBean"/> ``` 2. 然后,在需要使用类元数据的地方,我们可以通过 CachingMetadataReaderFactory 来获取类的元数据,例如: ```java @Autowired private CachingMetadataReaderFactory metadataReaderFactory; public void processClassMetadata(Class<?> clazz) { // 使用 CachingMetadataReaderFactory 获取类的元数据 MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(clazz.getName()); // 处理类的元数据... } ``` 在这个例子中,我们通过注入 CachingMetadataReaderFactory 来获取类的元数据。然后,我们可以使用 getMetadataReader 方法来获取指定类的元数据。获取到元数据后,我们可以根据需要来处理它。 需要注意的是,CachingMetadataReaderFactory 会缓存类元数据,所以在应用程序运行期间,如果类的元数据发生了变化,那么需要清除缓存,否则会导致应用程序出现问题。我们可以通过调用 CachingMetadataReaderFactory 的 clearCache 方法来清除缓存。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

默辨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值