【问题标题】:Spring AOP Capturing of logs inside a methodSpring AOP在方法内捕获日志
【发布时间】:2013-03-17 20:09:22
【问题描述】:

我是 Spring AOP 的新手。我确实了解它背后的概念,我也了解@Before 或@After 等用法的概念。我很困惑的仍然是Spring AOP的用法。想想下面的类方法。

public void test(int x) {
       :
       x++;
       logger.info("This is a test" + x);
       :
       try {
                   :
       } catch (Exception e) {
           throw new ...
       }
       :
}

捕获日志的旧方法如上所示。 这是我的问题:

  1. 如果我使用 Spring AOP 实现上述方法,该记录器将被删除,但 Spring AOP 是否能够捕获该日志消息? (据我所知,Spring AOP 不会查看方法内部)

  2. 如果对第 1) 条的回答是肯定的,那么它是如何完成的?

  3. 如果答案是否定的,那么使用 Spring AOP 的意义何在。除非您想在执行方法之前捕获参数等信息,否则 @Before 的使用是无用的。大多数情况下,我们希望在方法本身中捕获一些日志。

忘记 AspectJ。我确实知道 AspectJ 可以完成上述工作。 我只是想知道使用 Spring AOP 的意义何在,如果它不能完成在方法中捕获日志的最基本的事情。

感谢任何帮助。


补充说明:

我假设在实现 Spring AOP 之后上面的代码会是这样的。记录器调用不再在测试方法中,因为它将由方面类处理。这不就是 AOP 的目的吗?从对象中移除横切关注点(因为它与对象的实际服务无关)并由切面类处理?

public void test() {

       :
       try {
                   :
       } catch (Exception e) {
           throw new ...
       }
       :
}

如果 Spring AOP 不能做到这一点,那么拥有 AOP 的意义何在?

【问题讨论】:

  • 你有没有想过这个问题?

标签: spring spring-aop


【解决方案1】:

我很难理解您在这里的要求。一般来说,我不知道“在方法中捕获日志”是什么意思,但我认为无论如何我都可以提供一些帮助。

听起来你想在方法中任意插入代码到随机点,不一定在方法的开头或结尾。一般来说,Spring AOP 无法做到这一点,我不确定 AspectJ 是否能提供帮助,但我不太熟悉,无法给你一个明确的答案。

正如您所说,Spring AOP 可以在您的代码库中的各种 JoinPoints 之前/之后/周围注入。这些 JoinPoints 将成为方法,并且仅在 Spring 托管类中。

因此,如果您有类似以下的方法,则可以通过 @Around 方面在其周围添加日志记录(在本例中通过 System.out)。

代码:

public void test() {
    System.out.println("I am in a method now");
}

方面:

@Around("execution(public * *(..))")
public void publicMethods(ProceedingJoinPoint pjp) {
    System.out.println("before in an aspect");
    pjp.proceed();
    System.out.println("after in an aspect");
}

这实质上将初始方法变成了 this(以及将这些 System.out 添加到所有公共方法中):

public void test() {
    System.out.println("before in an aspect");
    System.out.println("I am in a method now");
    System.out.println("after in an aspect");
}

根据代码的布局,您可以通过在要插入的点创建方法来有效地任意插入。我不会推荐这个,但它肯定是可能的。

最后,以下是您问题的答案:

  1. 您可以将记录器替换为@Before 方面,假设记录行是方法中的第一个代码。如果您要这样做,那么您将能够从方法中删除日志记录。我不太清楚你对最后一句话的要求是什么,但是不,Spring AOP 并不看“内部”方法。
  2. Spring AOP 能够“捕获”它,因为 Spring 将代理该类。
  3. Spring AOP 的重点是能够“拦截”方法调用。您可能看不到它的真正用途,但它非常有用。最后一句话,我希望有所不同,当使用 Spring AOP 时,我希望能够检查我的方法中的内容,或者结果。

编辑:

您是对的,可以删除日志调用,并由方面进行处理。必须注意的是,方面调用日志方法的唯一机会是在实际方法调用之前或之后。

【讨论】:

  • AOP 的目的是消除代码中的横切关注点,并在代码之外完成。根据我上面的示例,我假设通过实现 AOP,logger.info("This is a test") 应该由方面类处理,因此从方法中删除。这就是 AOP 的全部目的。移除横切关注点并让它由方面类处理。根据您的示例,情况并非如此。因此,如果 logger.info("This is a test") 没有从代码中删除并由方面类处理,我仍然对 AOP 的整个目的感到困惑
  • 再看上面的代码。我做了一点改变。当没有变量 x 时,如何在方面类中捕获该日志?
  • @yapkm01 我明白你在追求什么,这是不可能的。可能的是我在回答中详细说明的内容。
  • 如果是这样,那么 Spring AOP 就违背了将横切关注点转移到切面类的核心目的。当我仍然需要将记录器放入方法中时,我看不到使用 AOP 的任何目的。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-30
  • 2011-08-12
  • 2018-04-13
  • 1970-01-01
  • 2013-07-02
  • 1970-01-01
  • 2021-08-16
相关资源
最近更新 更多