本篇记录MetadataReader的设计和实现,如下图圈出的部分:
MetadataReader定义与实现
前面介绍了这么多,都是为了MetadataReader做铺垫,因为MetadataReader间接或直接使用了上面介绍的所有类
元数据读取定义 - MetadataReader
package cn.zhanghongyang.core.type.classreader;
import cn.zhanghongyang.core.io.Resource;
import cn.zhanghongyang.core.type.AnnotationMetadata;
import cn.zhanghongyang.core.type.ClassMetadata;
public interface MetadataReader {
Resource getResource();
ClassMetadata getClassMetadata();
AnnotationMetadata getAnnotationMetadata();
}
元数据读取实现 - SimpleMetadataReader
package cn.zhanghongyang.core.type.classreader;
import cn.zhanghongyang.core.io.Resource;
import cn.zhanghongyang.core.type.AnnotationMetadata;
import cn.zhanghongyang.core.type.ClassMetadata;
import org.objectweb.asm.ClassReader;
import java.io.IOException;
import java.io.InputStream;
public class SimpleMetadataReader implements MetadataReader{
private static final int PARSING_OPTIONS = ClassReader.SKIP_DEBUG | ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES;
private Resource resource;
private AnnotationMetadata annotationMetadata;
public SimpleMetadataReader(Resource resource) throws IOException {
this.resource = resource;
SimpleAnnotationMetadataReadingVisitor visitor = new SimpleAnnotationMetadataReadingVisitor();
getClassReader(resource).accept(visitor, PARSING_OPTIONS);
this.annotationMetadata = visitor.getMetadata();
}
private ClassReader getClassReader(Resource resource) throws IOException{
try (InputStream is = resource.getInputStream()){
return new ClassReader(is);
} catch (IOException e) {
throw new IOException("");
}
}
@Override
public Resource getResource() {
return this.resource;
}
@Override
public ClassMetadata getClassMetadata() {
return this.annotationMetadata;
}
@Override
public AnnotationMetadata getAnnotationMetadata() {
return this.annotationMetadata;
}
}
结果演示
对ConfigForScanning类进行读取
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface Config {
}
@Config
public class ConfigForScanning {
public void test(){
}
}
读取结果:
总结
MetadataReader使用里ASM框架对类进行读取,运用了访问者的设计模式。
|