原因是代理对象内部方法的调用不会触发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代理乐成
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |