AspectJ 切入点不适用于带有 Element.TYPE 的注释,例如 @Component

AspectJ Pointcut doesn't work on Annotations with Element.TYPE like @Component

我正在使用 AspectJ 并尝试在 @Component 注释上切入点。

@Pointcut("@annotation(org.springframework.stereotype.Component)")
   public void bean() {
}

@Before("bean()")
public void beforeBeanCreation(JoinPoint jp) {
    System.out.println("Works!");
}

我的配置如下所示:

@Configuration
@ComponentScan({"com.app.pl"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableLoadTimeWeaving(aspectjWeaving = AspectJWeaving.ENABLED)
public class AppConfiguration{

}

当我想切入带有 ElementType.METHOD 的注释或具有特定名称的 bean 时,一切正常。但是使用 ElementType.TYPE 注释的切入点不起作用。我推测这是一个与注释相关的问题,它们在 AspectJ 代理站起来之前就被读取了。

知道如何解决这个问题吗?

可能您使用的不是 AspectJ,而是 Spring AOP。所以有几点需要考虑:

  • 通常 Spring AOP 方面无论如何都在 @Component 上工作,而不是在 non-Spring 上工作。为此,您确实需要 AspectJ。因此,在某种程度上,您的 Spring AOP 方面无论如何都会寻找该注释。
  • Spring AOP 切面也应该是 @Component,但会自动从切面编织中排除。在 AspectJ 中,您需要采取特殊的预防措施来排除一个方面编织另一个带有与正常应用程序代码相同的注释的方面。在将 Spring AOP 与完整的 AspectJ 相结合的情况下,您需要考虑这一点。

现在关于您的 AOP 问题,正如您已经注意到的那样,您无法通过 @annotation() 切入点拦截带注释的 class 中的连接点。您需要使用 @within() 代替,例如:

@within(org.springframework.stereotype.Component)

请注意,这将拦截注释 classes 中的所有连接点,即在 Spring AOP 的情况下,所有方法执行。它不会拦截 bean 创建,如果您的日志消息表明这是您的目标。