带有 AspectJ 的日志控制器

Log controller with AspectJ

我有一个 Spring 引导应用程序,我想记录一些信息,当调用控制器方法 ID 时发生了什么。

出于某种原因,我的方面不工作。

这是我用@Aspect 注释的@Component class:

@Pointcut("within(@org.springframework.stereotype.Controller *)")
public void controller() {
}

@Pointcut("execution(* *.*(..))")
protected void allMethod() {
}

@Before("controller()&& allMethod()")
public void logBefore(JoinPoint joinPoint) {
}

当使用 REST 调用任何控制器方法时,不会调用 logBefore 方法。

重要提示:正如您所说的那样,您正在使用 Spring 启动设置,我的假设是您已经实现了 Spring AOP 模块而不是 "actual" AspectJ 库.区别是显着的,因为 AOP 的实现在它们之间是不同的。 Spring 使用 AspectJ 注释来应用 proxying, while AspectJ "weaves" the code into your application. In short, Spring AOP might be easier to implement, while AspectJ offers more fine-grained functionality (such as compile-time weaving). A comparison can be found here.

我已经尝试了您在 post 中提供的代码片段中的配置。在我添加了几个注释后调用了该建议:

@SpringBootApplication
// Be sure to add EnableAspectJAutoProxy and set proxyTargetClass to true
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class DemoApplication {
  ...
}
// Be sure to add @Aspect and @Component
@Component
@Aspect
public class DemoAop {

  private static Logger logger = LoggerFactory.getLogger(DemoAop.class);

  @Pointcut("within(@org.springframework.stereotype.Controller *)")
  public void controller() {
  }

  @Pointcut("execution(* *.*(..))")
  protected void allMethod() {
  }

  @Before("controller()&& allMethod()")
  public void logBefore(JoinPoint joinPoint) {
    logger.info("TEST");
  }

}

在运行时,您的控制器使用@RestController 注释,但不是 @Controller。

只需将切入点更改为 RestController 即可:

 @Pointcut("within(@org.springframework.web.bind.annotation.RestController *)")
 public void controller() {
 }