Spring 中的 MetaData 接口 (3)

SimpleMetadataReader 为MetadataReader的默认实现,在创建SimpleMetadataReader通过ASM字节码操控框架读取class读取class资源流生成classMetadata与annotationMetadata

MetadataReaderFactory

MetadataReaderFactory接口 ,MetadataReader的工厂接口。
允许缓存每个MetadataReader的元数据集。

类关系图

img

MetadataReaderFactory接口方法 public interface MetadataReaderFactory { /** * 根据class名称创建MetadataReader */ MetadataReader getMetadataReader(String className) throws IOException; /** * 根据class的Resource创建MetadataReader */ MetadataReader getMetadataReader(Resource resource) throws IOException; }

MetadataReaderFactory接口提供两个方法:

根据class名称生成MetadataReader

根据class的Resource生成MetadataReader

SimpleMetadataReaderFactory public class SimpleMetadataReaderFactory implements MetadataReaderFactory { // 资源加载器,此类根据路径将给定的path生成IO流资源 private final ResourceLoader resourceLoader; @Override public MetadataReader getMetadataReader(String className) throws IOException { try { //根据classname生成class对应的资源路径 String resourcePath = ResourceLoader.CLASSPATH_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(className) + ClassUtils.CLASS_FILE_SUFFIX; //获取classname的IO流资源 Resource resource = this.resourceLoader.getResource(resourcePath); //调用资源创建MetadataReader return getMetadataReader(resource); } catch (FileNotFoundException ex) { } } /** * 根据class资源创建MetadataReader 默认实现 */ @Override public MetadataReader getMetadataReader(Resource resource) throws IOException { return new SimpleMetadataReader(resource, this.resourceLoader.getClassLoader()); } }

SimpleMetadataReaderFactory类为MetadataReaderFactory的简单实现,默认实现了MetadataReaderFactory的两个方法

在getMetadataReader(String className) 方法中根据className创建class的Resource,然后调用getMetadataReader(Resource resource)

在getMetadataReader(Resource resource) 方法中默认创建了SimpleMetadataReader

CachingMetadataReaderFactory public class CachingMetadataReaderFactory extends SimpleMetadataReaderFactory { // 默认的缓存大小 public static final int DEFAULT_CACHE_LIMIT = 256; // 内存缓存列表,Resource-MetadataReader的映射缓存 @Nullable private Map<Resource, MetadataReader> metadataReaderCache; @Override public MetadataReader getMetadataReader(Resource resource) throws IOException { if (this.metadataReaderCache instanceof ConcurrentMap) { MetadataReader metadataReader = this.metadataReaderCache.get(resource); if (metadataReader == null) { metadataReader = super.getMetadataReader(resource); //缓存到本地缓存 this.metadataReaderCache.put(resource, metadataReader); } return metadataReader; } else if (this.metadataReaderCache != null) { synchronized (this.metadataReaderCache) { MetadataReader metadataReader = this.metadataReaderCache.get(resource); if (metadataReader == null) { metadataReader = super.getMetadataReader(resource); //缓存到本地缓存 this.metadataReaderCache.put(resource, metadataReader); } return metadataReader; } } else { return super.getMetadataReader(resource); } } }

CachingMetadataReaderFactory 类在SimpleMetadataReaderFactory的基础上增加了缓存功能,对Resource-MetadataReader的映射做了本地缓存

ConcurrentReferenceCachingMetadataReaderFactory

这个工厂和CachingMetadataReaderFactory 的功能一致,只是这个工厂内部的缓存支持并发。

一个简单的使用例子

讲了这么多,最后用一个简单的例子来结束这篇文章。

public static void main(String[] args) throws Exception { ResourceLoader resourceLoader = new DefaultResourceLoader(); CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory(resourceLoader); MetadataReader metadataReader = factory.getMetadataReader(SpringIOCTest.class.getName()); ClassMetadata classMetadata = metadataReader.getClassMetadata(); Method[] methods = ClassMetadata.class.getMethods(); for (Method method : methods) { System.out.println(method.getName() + ":" + method.invoke(classMetadata)); } } 参考

什么是元数据

Spring中的MetaData

【小家Spring】聊聊Spring中的那些【Metadata】,举例讲解:AnnotationMetadata、 MethodMetadata

spring之class读取生成元数据流程

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wssdys.html