java 未调用Sping Boot AOP嵌套自定义注解[重复]

t3psigkw  于 2023-01-29  发布在  Java
关注(0)|答案(1)|浏览(117)
    • 此问题在此处已有答案**:

Why does self-invocation not work for Spring proxies (e.g. with AOP)?(2个答案)
17小时前关门了。
我在SpringBoot中创建了一个简单的自定义注解,它可以记录一些内容,并且它可以工作,但仅适用于第一个注解,嵌套的注解没有被调用

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 Traceable {

}

注解处理器(方面)

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class TraceableAspect {

    @Around("@annotation(Traceable)")
    public Object trace(ProceedingJoinPoint joinPoint) throws Throwable {

        System.out.println("Inside Aspect");
        
        Object result = joinPoint.proceed();

        System.out.println(result);
        return result;
    }
}

用于测试的控制器示例

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/test")
public class ControllerTest {

    @GetMapping("/get")
    @Traceable
    public String get(){

        test1();
        test2();

        return "Hi";
    }
    
    @Traceable
    public void test1(){
        String str = "1";
        System.out.println(str);
    }

    @Traceable
    public Object test2(){
        String str = "2";
        System.out.println(str);

        test1();
        return null;
    }

}

此处的控制台输出为:

Inside Aspect
1
2
1
Hi

但我认为它是坏的,它必须是这样的:

Inside Aspect
    Inside Aspect
    1
    Inside Aspect
    2
    Inside Aspect
    1
    Hi

好像只处理了第一个@Traceable,其他的都忽略了,怎么处理?谢谢

q0qdq0h2

q0qdq0h21#

要理解为什么会得到您所看到的结果,您必须了解Spring是如何实现对大多数行为注解的处理的:使用代理。这意味着只有通过代理的方法调用才能获得注解行为。这是一个对象调用它对另一个对象的引用时的典型场景;引用实际上是对代理的引用,代理拦截调用并将行为(在本例中是日志记录) Package 在它周围,但是,当调用同一示例中的方法时,没有代理在起作用(Spring不会/不能用对代理的引用替换this),因此没有注解行为。
有几种方法可以解决这个问题,this SO Q&A中讨论了一些想法。There are also some answers here包含解决代理限制的选项。

相关问题