建议未针对在方法级别使用的自定义注释执行,并且 poincut 似乎有问题,有什么建议吗?

Advice is not executing for custom annotation used at method level and it seems problem with poincut , any suggestions?

我在以下方面的建议没有得到执行:

package com.xxxx.logging.core.config;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogingAspectHandler {

    @Autowired
    CustomAppender lCustomAppender;

    //@Pointcut("execution(@com.xxxx.logging.core.config.CustomLogged * *(..))")
    @Pointcut("@annotation(com.xxxx.logging.core.config.CustomLogged)")
    public void customAnnotated() {}

    @Around("customAnnotated()")
    public void customLogger(ProceedingJoinPoint lProceedingJointPoint) {
        System.out.println("Get it "+lProceedingJointPoint.getSignature().getName());
        lCustomAppender.logEntryLevelInfo(lProceedingJointPoint);
          
    }
}

我用 Target(ElementType.METHOD) 创建了一个名为 CustomLogged 的自定义注解,并在包 com.xxxx.logging.core.config 中的 class 方法级别使用它。现在我想要一个切入点,用于所有那些用 @CustomLogged.

注释的方法

请找源码link
https://github.com/ssnarvariya/July_Projects.git

感谢 GitHub 上的 MCVE。您的应用程序中有很多问题,如果没有完整的项目,我将永远无法找出它的问题所在。除其他事项外,您还有以下问题:

  • 您的方面没有一个,而是两个@Around建议。 None 其中继续使用原始方法。这会导致只有第一个通知被触发(Spring AOP 首先找到),但不会触发第二个通知。而且,您的原始方法永远不会被调用。因此,这两个建议都需要调用 lJoinPoint.proceed()。在 @Before@After 建议中,这不是必需的,但在 @Around 中是必需的,因此参数类型 ProceedingJoinPoint (不是简单的 JoinPoint其他建议类型)。

  • Spring AOP 仅适用于 Spring 管理的组件或 bean,但您可以通过简单地在控件外部调用静态工厂方法来实例化您的 EVMLogger 实例Spring。因此,Spring AOP 永远无法为此 class 创建 AOP 代理,也永远不会拦截对其的任何方法调用。方法 public void debug(Object lMsg) 上的 @CustomLogged 注释无效。

  • 同样在 EVMLogger 中,您将 Logger 实例保存在静态变量中,但实际上如果您想要每个 class 不同的 Logger ] 使用 EVMLogger,您无法覆盖此静态字段。您必须将其设为实例字段并在创建 EVMLogger 实例时设置它。

  • 您需要多个 EVMLogger 实例,这也意味着您不能使用单例 bean,而应该使用原型 bean。有几种动态 instantiate a parametrised prototype bean 的方法。我正在向您展示如何将应用程序上下文自动连接到需要 EVMLogger 的目标 class 构造函数中,然后从上下文中获取 bean 实例。这适用于您示例中的两个不同 classes。

另一件对我来说很奇怪的事情是,你的方面记录了 EVMLogger 所做的事情,即一个记录器记录关于另一个记录器的信息。但也许您的方面实际上做了其他事情,而日志记录只是为了 MCVE。我假设是这样。

为了方便起见,我创建了一个 pull request。关键提交是:

调用 curl http://127.0.0.1:8080/getreq 时的控制台日志如下所示:

Inside logEntryLevelInfo for method ::showSampleData
Inside logEntryLevelInfo for method ::tryService
{"@timestamp":"2021-07-02T19:49:54.879+07:00","@version":"1","message":"Debug Msg...","logger_name":"org.ssn.app.config.CustomLogService","thread_name":"http-nio-8080-exec-1","level":"DEBUG","level_value":10000,"app_msg":{"mthd_name":"tryService","mtd_args":["Message1"]}}
Inside logCustomAnnotatedInfo for annotated method ::debug
{"@timestamp":"2021-07-02T19:49:54.879+07:00","@version":"1","message":"Custom Debug Msg...","logger_name":"org.ssn.app.controller.TestController1","thread_name":"http-nio-8080-exec-1","level":"DEBUG","level_value":10000,"app_msg":From Controller---}
{"@timestamp":"2021-07-02T19:49:54.879+07:00","@version":"1","message":"Debug Msg...","logger_name":"org.ssn.app.config.CustomLogService","thread_name":"http-nio-8080-exec-1","level":"DEBUG","level_value":10000,"app_msg":{"mthd_name":"showSampleData","mtd_args":[]}}

你看到了

  • 有两个不同的记录器名称 CustomLogServiceTestController1 以及
  • 两个方面的建议现在都会触发。