【AOP问题处理】:AopContext.currentProxy()方法非常处理:java.lang.Ille ...

打印 上一主题 下一主题

主题 863|帖子 863|积分 2589

原因是代理对象内部方法的调用不会触发AOP代理。
先看代码:
自界说了一个注解:
  1. import java.lang.annotation.ElementType;  
  2. import java.lang.annotation.Retention;  
  3. import java.lang.annotation.RetentionPolicy;  
  4. import java.lang.annotation.Target;  
  5.   
  6. // 使用元注解来指定注解的使用场景和生命周期  
  7. @Target({ElementType.METHOD}) // 可以用于方法
  8. @Retention(RetentionPolicy.RUNTIME) // 运行时保留,可以通过反射获取  
  9. public @interface Annotation1 {  
  10.       
  11.     // 定义一个名为value的注解属性
  12.     String value() default "";  
  13. }
复制代码
以及一个切面类,添加了注解@Annotation1的方法会触发AOP代理:
  1. @Aspect
  2. public class TestAspect {
  3.     @Around(value = "@annotation(annotation1)")
  4.     public Object around(ProceedingJoinPoint joinPoint, Annotation1 annotation1) throws Throwable {
  5.         // 前置逻辑
  6.         //......
  7.         // 方法执行
  8.         Object resultObject = joinPoint.proceed();
  9.         // 后置逻辑
  10.         //......
  11.         // 如果不需要阻止,则执行目标方法
  12.         return resultObject;
  13.     }
  14. }
复制代码
添加了注解@Annotation1的方法,以及报错的代码段:
  1. @Service  
  2. public class MyService {  
  3.     public void someInternalMethod() {  
  4.         // 获取当前代理对象  
  5.         MyService proxy = (MyService) AopContext.currentProxy();  
  6.         // 通过代理对象调用方法  
  7.         proxy.method1();  
  8.     }  
  9.     @Annotation1
  10.     public void method1() {  
  11.         // ...  
  12.     }  
  13. }
复制代码
本意是方法method1被调用时触发AOP代理,做一些逻辑处理,但是在Java中,默认情况下,方法内部的调用(即非通过代理的调用)是不会触发AOP(面向切面编程)代理的,所以选择利用this或AopContext.currentProxy()显式调用,这里利用的是AopContext.currentProxy(),如下:
  1.         /**
  2.          * Try to return the current AOP proxy. This method is usable only if the
  3.          * calling method has been invoked via AOP, and the AOP framework has been set
  4.          * to expose proxies. Otherwise, this method will throw an IllegalStateException.
  5.          * @return the current AOP proxy (never returns {@code null})
  6.          * @throws IllegalStateException if the proxy cannot be found, because the
  7.          * method was invoked outside an AOP invocation context, or because the
  8.          * AOP framework has not been configured to expose the proxy
  9.          */
  10.         public static Object currentProxy() throws IllegalStateException {
  11.                 Object proxy = currentProxy.get();
  12.                 if (proxy == null) {
  13.                         throw new IllegalStateException(
  14.                                         "Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.");
  15.                 }
  16.                 return proxy;
  17.         }
复制代码
看到这里的报错信息"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
  1. @EnableAspectJAutoProxy(exposeProxy = true)
复制代码
即:
  1. @EnableAspectJAutoProxy(exposeProxy = true)@Service  
  2. public class MyService {  
  3.     public void someInternalMethod() {  
  4.         // 获取当前代理对象  
  5.         MyService proxy = (MyService) AopContext.currentProxy();  
  6.         // 通过代理对象调用方法  
  7.         proxy.method1();  
  8.     }  
  9.     @Annotation1
  10.     public void method1() {  
  11.         // ...  
  12.     }  
  13. }
复制代码
运行调用就可以乐成获取MyService的代理对象,并且通过代理对象调用method1方法时,就会触发AOP代理乐成

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

小秦哥

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表