RestController 的父级 class 的切面方法不会触发通知逻辑

Aspect method of a parent class of a RestController does not trigger advice logic

我有一些我真的很想在其上使用方面的结构。我想让我的 RestController 继承自 class,它会产生特殊的日志记录方法

  1. 记录到标准的 logback 输出
  2. 向对日志进行处理的服务发出 http 请求 消息以及(由方面完成)

我创建了一个注释,用于标记我想要切面的方法,因此切入点无法过滤它。特殊情况是此方法在 RestController 的父级 class 中声明。

方面不是 运行 即使 IntelliJ 将方法标记为方面正在使用,这告诉我切入点必须工作?

请查看我的代码并检查我可能遗漏了什么以使其正常工作。

ApplicationClass

@SpringBootApplication
@ComponentScan("com.xetra.experimental")
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AopTryoutApplication {

    public static void main(String[] args) {
        SpringApplication.run(AopTryoutApplication.class, args);
    }
}

RestController

@RestController
public class Endpoint extends SimpleLogger {
  @GetMapping("/endpoint")
  public void doStuff(){
    log("foo");
  }
}

RestController 的父级 class

public class SimpleLogger implements EndpointLogger{
  @AspectAnnotation
  public void log(String msg) {
    System.out.println(msg);
  }
}

父接口class(听说方面方法需要接口)

public interface EndpointLogger {
  void log(String msg);
}

注解我的方面应该指向

@Inherited
public @interface AspectAnnotation {
}

Spring AOP方面

@Component
@Aspect
public class TestAspect {

  @Pointcut("@annotation(com.xetra.experimental.aoptryout.AspectAnnotation)")
  public void methods() {
  }

  @Before("methods()")
  public void beforeMethodExecution(JoinPoint jp) {
    System.out.println("Aspect ran!!!!");
  }

}

Due to the proxy-based nature of Spring’s AOP framework, calls within the target object are by definition not intercepted.

您可以找到更多 here

log 方法的调用未被拦截,因为它是从属于同一目标对象的 doStuff 方法发出的。

现在,任何对 log 方法的调用都将被拦截,只要它是从另一个对象(不是同一个目标对象)外部进行的。

问题

因此,如果我在端点内将 SimpleLogger 用作组件而不是父组件 class,它会工作吗?

是的,你是对的!

有什么方法可以让它正常工作吗?喜欢使用 AspectJ 而不是 Spring AOP?

您可以使用 AspectJ 的 source weaving 使其工作。 Here,是一个工作示例。