【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代理成功
上一篇: 【C++】一篇文章带你深入了解stack、queue 和 priority_queue
下一篇: 使用 TensorRT C++ API 调用GPU加速部署 YOLOv10 实现 500FPS 推理速度——快到飞起!!
本文标签
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。