【AOP问题处理】:AopContext.currentProxy()方法异常处理:java.lang.IllegalStateException: Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.

满哥大人 2024-06-20 16:39:00 阅读 94

原因是代理对象内部方法的调用不会触发AOP代理。

先看代码:

自定义了一个注解:

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

// 使用元注解来指定注解的使用场景和生命周期

@Target({ElementType.METHOD}) // 可以用于方法

@Retention(RetentionPolicy.RUNTIME) // 运行时保留,可以通过反射获取

public @interface Annotation1 {

// 定义一个名为value的注解属性

String value() default "";

}

以及一个切面类,添加了注解@Annotation1的方法会触发AOP代理:

@Aspect

public class TestAspect {

@Around(value = "@annotation(annotation1)")

public Object around(ProceedingJoinPoint joinPoint, Annotation1 annotation1) throws Throwable {

// 前置逻辑

//......

// 方法执行

Object resultObject = joinPoint.proceed();

// 后置逻辑

//......

// 如果不需要阻止,则执行目标方法

return resultObject;

}

}

添加了注解@Annotation1的方法,以及报错的代码段:

@Service

public class MyService {

public void someInternalMethod() {

// 获取当前代理对象

MyService proxy = (MyService) AopContext.currentProxy();

// 通过代理对象调用方法

proxy.method1();

}

@Annotation1

public void method1() {

// ...

}

}

本意是方法method1被调用时触发AOP代理,做一些逻辑处理,但是在Java中,默认情况下,方法内部的调用(即非通过代理的调用)是不会触发AOP(面向切面编程)代理的,所以选择使用this或AopContext.currentProxy()显式调用,这里使用的是AopContext.currentProxy(),如下:

/**

* Try to return the current AOP proxy. This method is usable only if the

* calling method has been invoked via AOP, and the AOP framework has been set

* to expose proxies. Otherwise, this method will throw an IllegalStateException.

* @return the current AOP proxy (never returns {@code null})

* @throws IllegalStateException if the proxy cannot be found, because the

* method was invoked outside an AOP invocation context, or because the

* AOP framework has not been configured to expose the proxy

*/

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.");

}

return proxy;

}

看到这里的报错信息"Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available."就是未访问到当前线程的代理对象proxy,它提示我们将Advised对象(Advised对象:已经被Spring AOP代理包装的对象)的exposeProxy属性设置为true以使其可被访问。(exposeProxy属性表示是否暴露生成的代理类,暴露就是可手动调用

所以只要将需要代理的对象类添加注解来设置属性exposeProxy = true

@EnableAspectJAutoProxy(exposeProxy = true)

即:

@EnableAspectJAutoProxy(exposeProxy = true)

@Service

public class MyService {

public void someInternalMethod() {

// 获取当前代理对象

MyService proxy = (MyService) AopContext.currentProxy();

// 通过代理对象调用方法

proxy.method1();

}

@Annotation1

public void method1() {

// ...

}

}

运行调用就可以成功获取MyService的代理对象,并且通过代理对象调用method1方法时,就会触发AOP代理成功



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。