java - 使用 Eclipse AspectJ 注入记录代码执行的上下文/元数据的记录器?
问题描述
我正在尝试定义一个方面来注入记录器。
我正在寻找类似的东西:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public aspect LogInjector {
private pointcut executionJoinPoints(): !within(LogInjector) && execution (* *.*(..));
before(): executionJoinPoints(){
// Get class name of the executed code
clazz = ...
final Logger logger = LogManager.getLogger(clazz);
// Get method name of the executed code
method = ...
// Get params name, type and values triplet or values at least if the previous is not possible, of the executed code
params = ...
// Get call stack of the executed code
stack = ...
logger.trace("{}.{}({}) - {}", clazz.name(), method.name(), params, stack);
}
after(): executionJoinPoints(){
// Get class name of the executed code
clazz = ...
final Logger logger = LogManager.getLogger(clazz);
// Get method name of the executed code
method = ...
// Get return value or exception of the executed code
result = ...
logger.trace("{}.{} = {}", clazz.name(), method.name(), result);
}
}
为此,我想检索执行元数据/上下文数据:
- 例外
- 返回值
如何获取此元数据/上下文数据?
解决方案
为了使您的方面保持高效,我建议以下内容:
- 将切入点限制在您真正希望调试的目标包和类。不要记录/跟踪整个世界。您还可以使用带有抽象切入点的抽象基本切面,并将切面扩展为带有具体切入点的具体子切面。如果您使用加载时编织,后者甚至可以通过 XML 配置提供。
- 使用
around()
建议而不是before()
/after()
对。然后,您只需要计算一些记录的值一次,并在通过proceed()
. - 只需记录
thisJoinPoint
而不是将默认情况下包含在其中的位拼凑在一起。这已经为您提供了连接点的类型、方法签名(包括参数类型和返回值)。 - 不要记录参数名称,这些信息不会增加任何实际价值。此外,参数名称需要重构,并且仅在使用调试信息编译您的代码时才存在。保持简单,只记录参数值。
- 在
around()
上面提到的建议中,您可以将proceed()
调用包含在try-catch-finally
并方便地处理和记录任何异常和堆栈跟踪和/或将检查的异常包装到 AspectJ 中SoftException
,或者简单RuntimeException
地重新抛出它们。任何适用于您的情况。 - 方法调用结果只是 的结果
proceed()
,这也是您需要从around()
建议中返回的结果。您也可以返回其他内容(但它必须具有正确的返回类型),或者proceed()
如果出于任何原因希望跳过目标方法执行,则完全跳过。
我刚才所说的所有内容都写在 AspectJ 手册或任何其他 AspectJ 教程中。下次在问这样的一般性问题之前,您可能想阅读其中的一些内容。
推荐阅读
- python - 通用工业协议,Python 脚本失败
- permissions - rabbitmq set_permission 命令如何使用我们的输入
- python - 如何从 sklearn 编码/缩放管道中获取 DF?
- reactjs - 单击弹出窗口时如何保持反应模式打开?
- sql - SQL JOIN 仅当
- python - Django创建超级用户错误:AttributeError:'ProfileManager'对象没有属性'create_superuser'
- database - 从 API 中提取数据并在处理后将其存储在数据库中
- android - 将 ListView 中的对象添加到 ArrayList 以添加到 SQLite
- python - Python:将变量另存为 HTML 文件
- c# - 用另一个用户设置值设置用户设置值