前言

开发程序的时候使用了aop去代理对象,然后其他地方会获取到这个代理对象并获取上面的方法注解和参数注解,运行时却发现无法获取注解,最终折腾一番终于解决。

原因

使用了AOP去进行代理,由于代理的对象不是接口,因此springboot会使用cglib去进行代理。

debug的时候可以看到,代理对象是由cglib代理的。



然后遍历bean这个类的方法,依次获取方法上的MessageMapping注解,获取到就将其添加到map中

这里获取注解的方法是AnnotatedElementUtils.getMergedAnnotation()

但是,发现本应能获取到注解的方法,此时却无法获取到注解

通过debug继续查看下去,发现方法上的注解全部为空

获取方法上的注解

其实解决办法非常简单,只需要将上面获取注解的代码AnnotatedElementUtils.getMergedAnnotation()改为AnnotatedElementUtils.findMergedAnnotation()就能轻松解决

可以看到,通过这种方式可以成功获取到方法上的注解,并且进入了if判断

获取方法参数上的注解

随后需要获取方法参数上的注解,同样也是获取为null

这个问题是比较棘手,试过SpringBoot内置的工具类,目前没找到能正常获取注解的方式。

因此决定换个思路,直接获取cglib代理类的原始对象,获取原始对象上的参数注解就可以了

直接上代码

private Parameter getProxySourceMethodParameter(Class<?> clazz, Method method, Integer parameterIndex) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException {
boolean isCglibProxyClass = clazz.getName().contains("$$");
if (!isCglibProxyClass) {
return ArrayUtil.get(method.getParameters(), parameterIndex);
}
Class<?> sourceClass = clazz.getSuperclass();
String methodName = method.getName();
Class<?>[] methodParameterTypes = method.getParameterTypes();
Method sourceMethod = sourceClass.getDeclaredMethod(methodName, methodParameterTypes);
return ArrayUtil.get(sourceMethod.getParameters(), parameterIndex);
}

通过获取原始类的方法参数,然后再获取参数上的注解就可以解决了。

Parameter parameter = getProxySourceMethodParameter(clazz, method, paramIndex);
Ref ref = AnnotatedElementUtils.findMergedAnnotation(parameter, Ref.class);

无法获取cglib代理对象上的注解的解决办法的更多相关文章

  1. 获取JDK动态代理/CGLIB代理对象代理的目标对象。

    问题描述:: 我现在遇到个棘手的问题,要通过spring托管的service类保存对象,这个类是通过反射拿到的,经过实验发现这个类只能反射取得sservice实现了接口的方法,而extends类的方法 ...

  2. AOP之proceedingjoinpoint和joinpoint区别(获取各对象备忘)、动态代理机制及获取原理代理对象、获取Mybatis Mapper接口原始对象

    现在AOP的场景越来越多,所以我们有必要理解下和AOP相关的一些概念和机制. import org.aspectj.lang.reflect.SourceLocation; public interf ...

  3. Mybatis-简单基于源码了解获取动态代理对象

    这是我们要测试的代码 OderDao就是我们要需要获取的对象. 首先我们根据传入的参数,进入SqlSessionFactoryBuilder 中的对应的build 方法,第一步创键XMLConfigB ...

  4. ProceedingJoinPoint获取实现类接口上的注解

    使用aspectj处理拦截aop,需要获取实现类接口上的注解 public Object around(ProceedingJoinPoint pjp) throws Throwable{ long ...

  5. jquery获取不到append出来的新元素的解决办法

    jquery获取不到append出来的新元素的解决办法 $('body').on("click","property",function(){}) jq1.7+ ...

  6. 阿里云vps上mysql挂掉的解决办法

    阿里云vps上mysql挂掉的解决办法 4条回复 用阿里云的vps用作blog服务器,系统很稳定,已经100多天一直运行正常,大概从上个月开始发现blog的mysql会有时挂掉,会收到短信通知.之前没 ...

  7. Chrome不能在网易网盘中上传文件的解决办法

    Chrome不能在网易网盘中上传文件的解决办法1. 安装 Adobe Flash Player PPAPI,设置flash插件 chrome://settings/content/flash,许可[* ...

  8. (转载,但不知道谁原创)获取SPRING 代理对象的真实实例,可以反射私有方法,便于测试

    /** * 获取 目标对象 * @param proxy 代理对象 * @return * @throws Exception */ public static Object getTarget(Ob ...

  9. android 5.1 WIFI图标上的感叹号及其解决办法

    转自:http://blog.csdn.net/w6980112/article/details/45843129 第一次调试android5.1的 WIFI更改小功能 Wifi 源码的相关路径目录  ...

  10. ASP: Response 对象 错误 'ASP 0251 : 80004005' 解决办法

    Response 对象 错误 'ASP 0251 : 80004005' 超过响应缓冲区限制 这种情况一般是因为需要输出的网页内容太大了,由于asp在输入内容到客户的浏览器上之前,会把需要输出的全部内 ...

随机推荐

  1. WIN10 由于找不到mfc140u.dll,无法继续执行代码

    最近遇到win10提示mfc140u.dll找不到,总是弹窗的问题. 网上一番百度搜索后发现给的方法都不能很好的解决,DLL修复工具需登录且收费 去下载mfc140u.dll 根本不可能找到,都是垃圾 ...

  2. 关于:js使用$.parseJSON字符串转json对象报错Uncaught SyntaxError- Unexpected token o in JSON at position 1

    今天使用js使用$.parseJSON字符串转json对象报错Uncaught SyntaxError- Unexpected token o in JSON at position 1,一直找不到原 ...

  3. scrcpy - Android手机投屏操作神器

    推荐一个Genymotion推出的投屏工具,跨平台,自定义码率,最重要的是开源,简直良心. Github:https://github.com/Genymobile/scrcpy 下载地址: http ...

  4. 从零开始的PHP原生反序列化漏洞

    1.写在前面 OK 兄弟们,这几天一直在面试,发现很多 HR 喜欢问反序列化相关的内容,今天咱们就从最简单的 PHP 原生反序列化入手,带大家入门反序列化 2.PHP 序列化 在 PHP 中,有反序列 ...

  5. FHQ treap(无旋treap)

    平衡树 平衡树作为一种中级数据结构,有着广泛的使用场景.其平衡性的维护方式灵活多变,而其中的无旋treap更以简单著称 P3369 [模板]普通平衡树 题意: 需维护以下操作: 插入一个数 x. 删除 ...

  6. TensorFlow 基础 (03)

    项目再忙碌, 还是要抽出时间来学习的. 最近到整一些数据清洗小工具, 数据导入数据库工具等... 有种感觉是, 之前我做分析师的时候, 啥工具都没有, 全部我自己造, 数据表整理, 业务整理, 建库建 ...

  7. 剖析 Vue:最适合小白入手的前端框架

    @charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...

  8. linux与docker知识积累

    0.在CentOS中,启动docker : sudo systemctl start docker 1.在 CentOS 中,要删除一个文件夹及其内容,可以使用 rm 命令的 -r 或 --recur ...

  9. pandas.read_csv() 报错 OSError: Initializing from file failed

    pandas.read_csv() 报错 OSError: Initializing from file failed,一般由两种情况引起:一种是函数参数为路径而非文件名称,另一种是函数参数带有中文. ...

  10. MySQL设置字符集、排序规则和区分字母大小

    摘要:在MySQL中,设置字符集和排序规则,在查询时区分字母大小写,utf8mb4支持emoji表情,而utf8不支持. 问题综述   在工作中,设置的一些唯一标志字符串和登录密码都是区分大小写的,但 ...