使用AspectJ记录局部变量值

问题描述 投票:0回答:2

我听说AOP如何帮助模块化日志记录等很多很棒的东西,但现在我正在努力实现这一点,我发现AspectJ非常有限。

不仅有时不可能将记录添加到正确的行,而且访问局部变量值似乎非常困难。您必须确保变量由方法返回或用作方法的参数。

日志记录超出了记录代码范围的简单事实是一个严重的限制。

是否有更好的方法来访问本地变量值以进行记录?

例如,我有一些维护计数器的代码,我想记录该计数器的值。原始代码看起来像这样:

int totalMoves = 0;

while(canMove()) {
    // ...
    totalMoves++;
}

Logger.log(totalMoves);

我找不到一种干净的方法来将此日志记录代码移动到某个方面。根本没有办法访问totalMoves。看来我的选择是:

  1. 使totalMoves成为一个可公开访问的领域(与信息隐藏和封装相对立)
  2. 创建一个虚拟函数,除了允许AspectJ的“钩子”之外什么都不做(没有比直接记录更好)
  3. 使totalMoves成为一个私有字段,但使用反射来访问它(看起来像一个糟糕的代码气味;创建一个不必要的字段并使访问变量复杂化)

说实话,我想在调查AOP时我期待的是逐字插入代码以消除交叉问题。这些限制让我怀疑AspectJ是否值得在当前环境中使用。

反正这个问题呢?或者我是以错误的方式接近这个?在这种情况下,我如何干净地记录局部变量?

TL; DR:使用AspectJ记录局部变量值是一个烂摊子,我怎样才能让它变得更好?

logging aspectj aop
2个回答
2
投票

之前已经多次询问过这个问题。答案是不。 AspectJ不能拦截局部变量的读/写操作,只能拦截成员。此外,在某些情况下,JVM可能会优化掉一些处理局部变量的源代码,但这是另一个主题。

滥用这样的AOP框架无论如何都不是一个好主意,即使它是可能的。它们用于装饰具有附加功能的类或拦截一些可从外部访问的操作,而不是用于攻击本地状态。如果某个方面需要知道局部变量名称,它对您的应用程序设计有什么看法?

至于你提到的三个选项,它们并不是你唯一拥有的选项。您还可以将totalMoves设为私有字段,并在有意义的情况下提供getter和/或setter。此外,即使您决定不使用getter / setter,您仍然可以使用能够与privileged aspect组合访问私有或受保护字段的get|set() pointcuts

阅读提供的链接后,请随时询问您是否理解此答案。


0
投票

另一种选择是重构代码块并从中提取方法并添加记录其返回值的方面:

@Log
private int totalMoves() {
    int totalMoves = 0;

    while(canMove()) {
        // ...
        totalMoves++;
    }

    return totalMoves;
}
© www.soinside.com 2019 - 2024. All rights reserved.