如何在AOP代理的情况下获取注解所在的全限定类名

如何在AOP代理的情况下获取注解所在的全限定类名

在通过AOP切片来使用redis缓存加速的时候,势必会涉及key的取值,能够想到比较好的方法便是自定义注解+方法名称+参数+全限定类名。但是在获取全限定类名的时候出了一点问题记录下来

直接上最终代码

 @Around("@annotation(com.ava.ww.common.cache.RedisCache)")
    public Object redisAspectMethod(ProceedingJoinPoint point) {
        //  先获取缓存key
        MethodSignature signature = (MethodSignature) point.getSignature();
        //获取Method对象
        Method method = signature.getMethod();
        RedisCache annotation = method.getAnnotation(RedisCache.class);
        // 拼接缓存key 注解+方法名+参数+全限定类名
        String redisKey =
                annotation.prefix() + method.getName() + "_" + Arrays.toString(point.getArgs()) +"_"+ point.getTarget().getClass().getName();
                
        //此处省略分布式锁访问过程
        ...

        return dataFromDatabase;
    }

正确获取被代理对象的全限定类型的方法为:

point.getTarget().getClass().getName()

为什么不能够通过以下方式获取全限定类名?

MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
Class declaringClass = method.getDeclaringClass();
String fqcn = declaringClass.getName();

原因是在Spring AOP代理的情况下,JoinPoint获取到的签名对象是JDK动态代理生成的一个内部类,并不是原始类的方法签名。

Spring AOP是基于动态代理实现的,当目标对象被代理时,实际调用的是动态生成的代理类的方法,所以该方法的签名是代理类的内部方法签名,而不是原始类的方法签名

具体来看,在Spring AOP中,ProceedingJoinPoint的getSignature()获取的是MethodSignature,而这个MethodSignature的实际类型是:

org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint$MethodSignatureImpl

这是一个JDK动态代理内部生成的类,用于描述当前被调用方法的信息,但不代表原始类本身。
所以通过getSignature()获得的签名表示的是代理类的内部方法调用,而不是原始类的方法调用,自然无法获取到原始类的全限定类名。

总结

要获取原始类的全限定类名,可以通过以下方式:
通过ProceedingJoinPointgetTarget()获取被代理的原始对象,在通过originalObject.getClass().getName()获取原始类全限定类名这种方式可以跳过代理,直接获取到目标对象的实际类型,从而获得原始类的全限定类名。

所以Spring AOP代理会影响JoinPoint获取到的方法签名,需要特殊处理才能获取到原始类信息。这是由其动态代理机制决定的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值