spring中底层运用到了asm技术,这种技术是不创建Class类对象直接读取class 文件就可以获取Class的信息。那么我们在公司很有可能都会开发自己公司的一套框架,通常来说,就是把现在流行的技术二次开发封装,方便自己公司开发项目,二次开发时很有可能你会自己设计一些注解,这些注解是做什么用的,用在什么地方,比如类上面或者属性或者方法等等,此时你很有可能就会用到ASM技术,在不初始化Class的情况下获取class文件中的描述。本人从项目中抽取这段代码,方便大家参考。 code:
import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.tree.*; public class SchedulerUtil { private final static SchedulerFactory schedulerfactory = new StdSchedulerFactory(); private final static Map<String,Class> taskClazz = new HashMap<String,Class>(); static { try { scheduler = schedulerfactory.getScheduler();//这是单例的; String path = SchedulerUtil.class.getResource("/").getPath();//获取classpath路径 List<File> list = getAllClassFile(new File( path ));//此方法为获取classpath路径下所有的class文件(所有包) for(File f: list) {//便利每一个class文件 //getClassName(f); ClassReader reader = new ClassReader(new FileInputStream(f)); ClassNode cn = new ClassNode();//创建ClassNode,读取的信息会封装到这个类里面 reader.accept(cn, 0);//开始读取 List<AnnotationNode> annotations = cn.visibleAnnotations;//获取声明的所有注解 if(annotations!=null) {//便利注解 for(AnnotationNode an: annotations) { //获取注解的描述信息 String anno = an.desc.replaceAll("/", "."); String annoName = anno.substring(1, anno.length()-1); if("com.mh.base.quartz.annotation.BaseQuartz".equals(annoName)) { String className = cn.name.replaceAll("/", "."); //获取注解的属性名对应的值,(values是一个集合,它将注解的属性和属性值都放在了values中,通常奇数为值偶数为属性名) String valu = an.values.get(1).toString(); System.out.println(className); System.out.println(valu); taskClazz.put(valu, Class.forName(className));//根据匹配的注解,将其封装给具体的业务使用 } } } } } catch (Exception e) { e.printStackTrace(); } }