AopContext.currentProxy()使用报exposeProxy错误

【饿了么、美团】外卖红包领取地址 >> 能省一点是一点

在Spring中,可以通过@Transactional或者@Cacheable注解,通过代理的形式快速的为某个方法实现事务或者缓存。但是当在类中,存在自己调用自己的带事务的方法时,会由于调用的是原始类而非代理类从而导致注解失效。这个时候我们可以使用AopContext.currentProxy()方法直接获取当前对象的代理类对象的办法来解决这个问题。

在使用AopContext.currentProxy()时,最常出现的问题是会报如下错误:

Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.

原因可以查看源码:

public static Object currentProxy() throws IllegalStateException {
    Object proxy = currentProxy.get();
    if (proxy == null) {
        throw new IllegalStateException("Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.");
    } else {
        return proxy;
    }
}

可以发现,当获取不到代理对象时,就会抛出这个异常。解决办法也很简单,百度上的解决办法无非就2种:

1、使用SpringBoot的话,在启动类上添加注解:

@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)

2、使用xml配置的话,在xml配置文件上添加:

<aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true"/>

两种办法含义是一样的,其中
proxyTargetClass这个参数与Spring使用jdk进行代理还是cglib进行代理有关,这里暂不展开。
exposeProxy这个参数为true时,相当于一个开关,允许AopContext.currentProxy()的使用形式。

通过上述的配置,即可解决这个问题,但是我碰到了另外一种情况:
在老的代码上,使用了@Cacheable注解和AopContext.currentProxy(),在一次代码改动中,将方法上的@Cacheable注解去掉了,使用其他的形式实现,但是AopContext.currentProxy()没有去掉,导致一直在报错,但是expose-proxy明明已经配置了。

经过排查,其实问题就出现在,去掉了@Cacheable注解上,在@Cacheable注解还在的时候,会有代理类的存在的,但是我们把@Cacheable注解去掉之后,刚好这个类就不需要被代理了。所以我们通过AopContext.currentProxy()是肯定拿不到代理类的,而且由于会被异常信息中的提示给带偏,导致排查方向走偏,所以在这个方法发生异常报错的时候,也可以先排查下,这个类是否真的有代理类的存在


觉得内容还不错?打赏个钢镚鼓励鼓励!!👍

3M 反光马甲反光服反光衣骑行交通施工环卫反光背心马甲荧光衣二杠二竖反光衣(魔术贴款)荧光黄 L
¥32.30
金隆兴 【1440枚37*25mm】不干胶标签贴纸姓名贴自粘性口取纸标贴 24枚/张 8297红色
¥8.60
Daisy Leaf 日本多功能纸巾盒 抽纸盒桌面收纳盒餐巾纸盒 简约白
¥33.90
火岩熊 多功能电煮锅学生宿舍锅寝室多用途锅不易沾家用电炒锅电火锅神器迷你电饭锅电蒸锅煮面小锅1-2人 黄色+不沾内胆丨7礼丨pp蒸笼+刀具【可煎可炒煮】
¥42.90
OKF韩国进口 库拉索芦荟饮料500ml*4瓶 0糖0脂0卡 含芦荟颗粒清爽补水解渴无糖
¥49.00
倍思 iPhoneXS Max/11 Pro Max防窥钢化膜 苹果手机钢化膜 全屏9D曲面高清玻璃贴膜6.5英寸黑色
¥34.00
CROSSING DAYS crossingdays搓澡巾男女搓澡神器强力搓泥澡巾去角质手套洗澡巾 灰色(粗砂 男士)+粉色(细砂 女士)
¥15.20
汉状元 素描纸8k马克笔专用纸速写纸学生铅笔画画纸美术专用手绘纸儿童铅画彩铅绘画用纸 8k马克纸【50张/160g】
¥19.90