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