利用反射获取任意包下所有类、方法、字段的自定义注解信息
场景:
通常情况下,我们已经明确了某个类,想要判断这个类拥有那个注解,直接使用clazz.getAnnotation()
即可,但是某些场景下,我们可能需要进行反向操作,获取存在某个注解的类、方法、字段;
获取类注解(伪代码):
Class<?> clazz = Class.forName(classname); // 1、判断类中是否存在ClassAnnotation注解,如果存在则打印 ClassAnnotation classAnnotation = clazz.getAnnotation(ClassAnnotation.class); if (classAnnotation != null) { // 获取属性 System.out.println("类中注解——code:" + classAnnotation.code() + ";name:" + classAnnotation.name()); }
获取方法注解(伪代码):
Method[] methods = clazz.getMethods(); for (Method method : methods) { MethodAnnotation methodAnnotation = method.getAnnotation(MethodAnnotation.class); if (methodAnnotation != null) { // 获取属性 System.out.println("方法中注解——code:" + methodAnnotation.code() + ";name:" + methodAnnotation.name()); } }
获取字段注解(伪代码):
Field[] fields = clazz.getFields(); for (Field field : fields) { FiledAnnotation filedAnnotation = field.getAnnotation(FiledAnnotation.class); if (filedAnnotation != null) { // 获取属性 System.out.println("字段中注解——code:" + filedAnnotation.code() + ";name:" + filedAnnotation.name()); } }
定义注解:
// 1、ClassAnnotationimport java.lang.annotation.*;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface ClassAnnotation { / * 定义注解需要的属性 * * @return */ String code(); String name();}// 2、MethodAnnotationimport java.lang.annotation.*;@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface MethodAnnotation { / * 定义注解需要的属性 * * @return */ String code(); String name();}// 3、FiledAnnotationimport java.lang.annotation.*;@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface FiledAnnotation { / * 定义注解需要的属性 * * @return */ String code(); String name();}
完整代码:
public class Main { public static void main(String[] args) throws Exception { //spring工具类,可以获取指定路径下的全部类 ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); // 监听的包 String basePackage = "com.lhz.wx.test"; String resourcePattern = "//*.class"; String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(basePackage) + resourcePattern; // 获取指定包路径下的类资源 Resource[] resources = resourcePatternResolver.getResources(pattern); //MetadataReader 的工厂类 MetadataReaderFactory readerfactory = new CachingMetadataReaderFactory(resourcePatternResolver); for (Resource resource : resources) { //用于读取类信息 MetadataReader reader = readerfactory.getMetadataReader(resource); //扫描到的class String classname = reader.getClassMetadata().getClassName(); Class<?> clazz = Class.forName(classname); // 1、判断类中是否存在ClassAnnotation注解,如果存在则打印 ClassAnnotation classAnnotation = clazz.getAnnotation(ClassAnnotation.class); if (classAnnotation != null) { // 获取属性 System.out.println("类中注解——code:" + classAnnotation.code() + ";name:" + classAnnotation.name()); } // 2、判断类中方法否存在MethodAnnotation注解,如果存在则打印 Method[] methods = clazz.getMethods(); for (Method method : methods) { MethodAnnotation methodAnnotation = method.getAnnotation(MethodAnnotation.class); if (methodAnnotation != null) { // 获取属性 System.out.println("方法中注解——code:" + methodAnnotation.code() + ";name:" + methodAnnotation.name()); } } // 3、判断类中字段否存在FiledAnnotation注解,如果存在则打印 Field[] fields = clazz.getFields(); for (Field field : fields) { FiledAnnotation filedAnnotation = field.getAnnotation(FiledAnnotation.class); if (filedAnnotation != null) { // 获取属性 System.out.println("字段中注解——code:" + filedAnnotation.code() + ";name:" + filedAnnotation.name()); } } } }}
效果: