今天写maven插件,需要实现扫描自定义注解,但是死活通过Class.getAnnotation(Annotation.class)拿不到注解,一直返回空,网上都说是注解没有加上@Retention(RetentionPolicy.RUNTIME),但其实我是有的,通过在被扫描类里写main方法,一样的代码是可以拿到注解的。

通过调试,发现getAnnotation方法内部其实把Class对象的所有Annotation都放到了一个Map中,最后通过传入了注解class对象作为Key去找是否存在。最后发现,main方法中的ket存在,而插件中的key不存在。说明两个Annotation.class并不是同一个对象。

那么为什么插件中就不是一个对象呢?

插件中的需求是根据目标输出jar读取扫描jar中类是否包含指定注解,但是插件本身classpath并没有目标jar,这个时候就要自己使用classload加载jar了,实际上classLoad加载了目标class和注解类,代码贴上:

private void ResolveClass(String className) {try {Class<?> clazz = classLoader.loadClass(className);Class<?> aClass = classLoader.loadClass(MyApi.class.getName());System.out.println(clazz.getName());MyApi annotation = clazz.getAnnotation(MyApi.class);if(annotation != null) {System.out.println(((MyApi) annotation).name() + ((MyApi) annotation).desc());}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();}}

每个类的Class对象的创建跟随classLoader,所以这个写法中的MyApi.class对象实际上对应当前线程上下文classload对象,所以二者并不是同一个对象。

正确的写法如下:

private void ResolveClass(String className) {try {Class<?> clazz = classLoader.loadClass(className);Class aClass = classLoader.loadClass(MyApi.class.getName());System.out.println(clazz.getName());Annotation annotation = clazz.getAnnotation(aClass);if( annotation != null) {System.out.println(annotation.getClass().getMethod("name").invoke(annotation));}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}

getAnnotation(Class.class) 为空问题相关推荐

  1. @Aspect中@Pointcut 12种用法

    本文主要内容:掌握@Pointcut的12种用法. Aop相关阅读 阅读本文之前,需要先掌握下面3篇文章内容,不然会比较吃力. Spring系列第15篇:代理详解(java动态代理&CGLIB ...

  2. @Aspect注解用法

    本文继续AOP,目前手动Aop中三种方式已经介绍2种了,本文将介绍另外一种:AspectJProxyFactory,可能大家对这个比较陌生,但是@Aspect这个注解大家应该很熟悉吧,通过这个注解在s ...

  3. EasyExcel合并单元格,通过注解方式实现自定义合并策略

    EasyExcel合并单元格,通过注解方式实现自定义合并策略 简介 今天博主探讨如何实现EasyExcel自定义实现单元格合并策略,考虑需要抽象代码.适用于更多的业务场景,提供了两个工具类,参考过很多 ...

  4. @Pointcut 的 12 种用法,你知道几种?

    知识搬运,尊重原著,原著地址:@Pointcut 的 12 种用法,你知道几种? - 知乎 本文继续AOP,目前手动Aop中三种方式已经介绍2种了,本文将介绍另外一种:AspectJProxyFact ...

  5. Spring系列之@Aspect中@Pointcut 12种用法

    先了解几个概念 文中会涉及几个概念,先了解一下. target 用来表示目标对象,即需要通过aop来增强的对象. proxy 代理对象,target通过aop增强之后生成的代理对象. AspectJ ...

  6. SpringAOP专题之6、Spring AOP中@Pointcut 12种用法

    本文主要内容:掌握@Pointcut的12种用法. Aop相关阅读 阅读本文之前,需要先掌握下面几篇篇文章内容,不然会比较吃力. 代理详解(java动态代理&CGLIB代理) jdk动态代理和 ...

  7. @Pointcut 的常用方式:execution,within,this,target,args,@within,@target,@args,@annotation等介绍

    @Pointcut 的常用方式 先了解几个概念 文中会涉及几个概念,先了解一下. target 用来表示目标对象,即需要通过aop来增强的对象. proxy 代理对象,target通过aop增强之后生 ...

  8. 优雅参数判空_java 方法参数怎么优雅校验?

    不邀自来.这个问题,我之前也考虑过,包括异常处理,都是很繁琐的,不是核心的业务逻辑,但是充斥在代码的各个角落,很繁琐. 我的解决方案,是通过aop+注解的方式,无侵入式的解决. 1.第一步声明自定义注 ...

  9. java注解判断字段是否存在_使用注解和反射判断指定的字段不能为空

    我们在写项目的时候,如何类比较少.判别指定对象的属性值是否为空,那确实可以,但是随着类的增多,判别对象的属性是否为空就非常的繁琐,所以可以使用自定义注解和反射来判定指定的字段是否为空. 第一步:创建一 ...

最新文章

  1. 巴塞罗那自治大学3D视觉课件
  2. Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)
  3. 实现查询菜品信息考试题
  4. “AS3.0高级动画编程”学习:第二章转向行为(下)
  5. ndarray python 映射_在Matlab的delsq演示中,用numpy方法对向量映射进行ndarray处理?...
  6. 输入和用户界面——总结
  7. 关于PHP SESSION
  8. Elasticsearch(待学习)
  9. 3.2 企业关于自动驾驶汽车的安全保证和测试方法(第三章 自动驾驶汽车的安全保障)
  10. java drawline_JAVA drawLine()方法怎么用?
  11. 项目启东异常Failed to read candidate component class
  12. kali linux 64bit 2019.1a下启动bbqsql:No module named coros
  13. deepin php7,deepin安装php7
  14. 集成学习中boosting、bagging、随机森林算法的介绍
  15. 原生JS实现图片跑马灯特效
  16. java查看附近门店_微信公众号获取用户地理位置并列出附近的门店的示例代码...
  17. 刷脸支付有助商户自主营销计划节省开支
  18. 数据库查询_同时选修了两门课的学生姓名、学号
  19. 如何用阿里云服务器建站(新手全流程)
  20. 又是一年高考季,转眼间已经过去12年了

热门文章

  1. win怎么在计算机里按日期搜索文件,Win8系统如何按指定修改日期搜索文件
  2. python 抽奖器_如何基于python实现年会抽奖工具
  3. 《别看了,你学不会的》——Redis原理与实战(一)
  4. js 和 min.js 有什么区别
  5. vuedraggable拖拽插件使用
  6. 基于Layui自定义内容轮播插件
  7. URL缩短器:详细说明
  8. 局域网IP不足解决方法
  9. 微信铃声设置教程,怎么设置微信铃声?
  10. 量子计算机:一场改变世界的开发竞赛