Spring 之类元数据封装—MetadataReader

在 Spring 中最喜欢干的事情就是将多个参数封装到一个对象,这里就挑选一个例子讲讲——MetadataReader,这个对象是将一个类封装成了三部分:File 文件本身,类元数据,注解元数据。

MetadataReader 元数据对象

先看下这个类的源代码,如下所示:

public interface MetadataReader {

	/**
	 * Return the resource reference for the class file.
	 */
	Resource getResource();

	/**
	 * Read basic class metadata for the underlying class.
	 */
	ClassMetadata getClassMetadata();

	/**
	 * Read full annotation metadata for the underlying class,
	 * including metadata for annotated methods.
	 */
	AnnotationMetadata getAnnotationMetadata();
}

专门提供了三个 API 来获取 File 文件本身,类元数据,注解元数据。Spring 中提供了他的两个子类实现 SimpleMetadataReaderFactory、CachingMetadataReaderFactory,如果想要使用这些对象,那么就得先拿到该对象,那么怎么拿呢?

要想获取到一个对象,最有可能就是通过一个工厂获取到,所以这里就可以通过工厂方法获取,Spring 提供了 CachingMetadataReaderFactory 来获取 MetadataReader 子类对象,用法如下:


@Component
public class MyMetaData implements ResourceLoaderAware {
	private ResourceLoader resourceLoader;

	@Override
	public void setResourceLoader(ResourceLoader resourceLoader) {
		this.resourceLoader = resourceLoader;
	}

	public void metaData() throws Exception {
		CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);

		MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(MyFactoryBean.class.getName());
		System.out.println("metadataReader = " + metadataReader);
	}
}

需要借助一个类加载器去读取到指定文件数据,这里可以通过 ResourceLoaderAware 接口获取到一个资源加载器 resourceLoader,如果不实现,CachingMetadataReaderFactory 工厂自己内部也有默认的类加载器 DefaultResourceLoader。

其实提到了类加载器了,应该就能够猜出要通过 IO 流去读取文件,然后封装数据,这个步骤就是在 getMetadataReader() 方法中做的,源码如下:

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

使用案例

定义一个类,如下所示:


@Component
@Import({MyImportSelector.class, AppleEntity.class})
public class MyFactoryBean {

	public String name = "张老三";

}

这个类所有的信息:文件本身,类信息,注解信息,通过 MetadataReader 获取,如下所示:


@Component
public class MyMetaData implements ResourceLoaderAware {
	private ResourceLoader resourceLoader;

	@Override
	public void setResourceLoader(ResourceLoader resourceLoader) {
		this.resourceLoader = resourceLoader;
	}

	public void metaData() throws Exception {
		CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();

		MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(MyFactoryBean.class.getName());
		System.out.println("metadataReader = " + metadataReader);

		/**
		 * 获取类 Xxx.class 本地资源文件
		 */
		Resource resource = metadataReader.getResource();
		File file = resource.getFile();
		System.out.println("length = " + file.length());

		/**
		 * 获取类元数据
		 */
		ClassMetadata classMetadata = metadataReader.getClassMetadata();
		System.out.println("classMetadata.getClassName() = " + classMetadata.getClassName());
		System.out.println("classMetadata.getEnclosingClassName() = " + classMetadata.getEnclosingClassName());
		Class<?> aClass = Class.forName(classMetadata.getClassName());
		Constructor<?> constructor = aClass.getConstructor();
		MyFactoryBean myFactoryBean = (MyFactoryBean)constructor.newInstance();
		System.out.println("myFactoryBean = " + myFactoryBean);

		/**
		 * 获取类上的所有注解元数据
		 */
		AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
		MergedAnnotations annotations = annotationMetadata.getAnnotations();
		MergedAnnotation<Import> importMergedAnnotation = annotations.get(Import.class);
		MergedAnnotation<Component> componentMergedAnnotation = annotations.get(Component.class);
		System.out.println("componentMergedAnnotation = " + componentMergedAnnotation);
		System.out.println("importMergedAnnotation = " + importMergedAnnotation);
		String[] values = importMergedAnnotation.getStringArray("value");
		Arrays.asList(values).forEach(System.out::println);
	}
}

Spring 中很多地方都可通过 MetadataReader 获取到类元数据,从而做更多的操作,这个元数据还是非常好用的。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值