如何将AOP与AspectJ一起使用进行日志记录?

2022-09-01 08:19:19

我想将“跟踪”消息添加到我的所有公共方法中,如下所示:

public void foo(s:String, n:int) { // log is a log4j logger or any other library
  log.trace(String.format("Enter foo with s: %s, n: %d", s, n))
  ...
  log.trace("Exit foo") 
}

现在我想使用AOP(和字节码检测)自动将所有这些添加到我的方法中。我正在考虑.这有意义吗?你知道任何开源吗,正是哪个是这样做的?log.traceAspectJ


答案 1

我创建了一个简单的方面来捕获公共方法的执行。这个AspectJ代码的核心是切入点的定义:

pointcut publicMethodExecuted(): execution(public * *(..));

在这里,我们捕获具有任何返回类型,任何包和任何类上具有任意数量参数的所有公共方法。

建议执行可以在下面的代码片段上可视化:

after(): publicMethodExecuted() {
    System.out.printf("Enters on method: %s. \n", thisJoinPoint.getSignature());

    Object[] arguments = thisJoinPoint.getArgs();
    for (int i =0; i < arguments.length; i++){
        Object argument = arguments[i];
        if (argument != null){
            System.out.printf("With argument of type %s and value %s. \n", argument.getClass().toString(), argument);
        }
    }

    System.out.printf("Exits method: %s. \n", thisJoinPoint.getSignature());
}

此建议使用此JoinPoint获取方法签名和参数。就是这样。下面是方面代码:

public aspect LogAspect {

pointcut publicMethodExecuted(): execution(public * *(..));

after(): publicMethodExecuted() {
    System.out.printf("Enters on method: %s. \n", thisJoinPoint.getSignature());

    Object[] arguments = thisJoinPoint.getArgs();
    for (int i =0; i < arguments.length; i++){
        Object argument = arguments[i];
        if (argument != null){
            System.out.printf("With argument of type %s and value %s. \n", argument.getClass().toString(), argument);
        }
    }
    System.out.printf("Exits method: %s. \n", thisJoinPoint.getSignature());
}

对于更复杂的例子,我会推荐AspectJ:In Action一书。


答案 2

@Loggable注释和来自jcabi方面的AspectJ方面对你来说是一个现成的机制(我是一个开发人员):

@Loggable(Loggable.DEBUG)
public String load(URL url) {
  return url.openConnection().getContent();
}

要根据问题的要求同时记录进入和退出,请执行以下操作:

@Loggable(Loggable.DEBUG, prepend=true)
public String load(URL url) {
  return url.openConnection().getContent();
}

所有日志都转到 SLF4J。查看此帖子以获取更多详细信息。


推荐