1.概述
在本教程中,我们将在调用已配置类的方法时使用AspectJ编写跟踪日志记录输出。通过使用AOP建议来编写跟踪日志输出,我们将逻辑封装到单个编译单元中。
我们的示例扩展了AspectJ简介中提供的信息。
2.跟踪记录注释
我们将使用注解来配置类,以便可以跟踪其方法调用。使用注解为我们提供了一种简便的机制,可以将跟踪日志记录输出添加到新代码中,而不必直接添加日志记录语句。
让我们创建注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Trace {
}
3.创建我们的Aspect
我们将创建一个方面来定义pointcut
以匹配我们关心的连接点以及包含要执行的逻辑around
我们的方面将类似于以下内容:
public aspect TracingAspect {
private static final Log LOG = LogFactory.getLog(TracingAspect.class);
pointcut traceAnnotatedClasses(): within(@Trace *) && execution(* *(..));
Object around() : traceAnnotatedClasses() {
String signature = thisJoinPoint.getSignature().toShortString();
LOG.trace("Entering " + signature);
try {
return proceed();
} finally {
LOG.trace("Exiting " + signature);
}
}
}
在我们方面,我们定义了一个pointcut
命名traceAnnotatedClasses
相匹配的execution
方法within
我们注释类Trace
注释。**通过定义和命名pointcut,
我们可以像使用类中的方法一样重用它。**我们将使用这个命名的pointcut
来配置我们的around
建议。
**我们的around
pointcut
匹配的任何连接点执行,并返回一个Object
。**通过具有Object
返回类型,我们可以考虑具有任何返回类型(甚至void
建议方法。
我们检索匹配的连接点的签名,以创建String
表示形式,以将上下文添加到我们的跟踪消息中。结果,我们的日志输出将具有该类的名称和所执行的方法,这为我们提供了一些所需的上下文。
在两次跟踪输出调用之间,我们调用了一个名为proceed
的方法。**此方法可用于around
建议,以便继续执行匹配的连接点。**由于我们无法在编译时知道返回类型,因此返回类型将为Object
在将最终跟踪输出发送到日志之后,我们将把该值发送回调用方。
**我们将try
proceed()
调用包装在try / finally
块中,以确保写入退出消息。**如果我们想跟踪抛出的异常,我们可以添加after()
建议以在抛出异常时编写一条日志消息:
after() throwing (Exception e) : traceAnnotatedClasses() {
LOG.trace("Exception thrown from " + thisJoinPoint.getSignature().toShortString(), e);
}
4.在我们的代码使用注解
现在我们需要启用跟踪。让我们创建一个简单的类,并使用我们的自定义注释激活跟踪日志记录:
@Trace
@Component
public class MyTracedService {
public void performSomeLogic() {
...
}
public void performSomeAdditionalLogic() {
...
}
}
有了Trace
注释后,我们类中的方法将与我们定义pointcut
执行这些方法时,跟踪消息将被写入日志。
运行调用这些方法的代码后,我们的日志输出应包含类似于以下内容的内容:
22:37:58.867 [main] TRACE cbacTracingAspect - Entering MyTracedService.performSomeAdditionalLogic()
22:37:58.868 [main] INFO cbacMyTracedService - Inside performSomeAdditionalLogic...
22:37:58.868 [main] TRACE cbacTracingAspect - Exiting MyTracedService.performSomeAdditionalLogic()
22:37:58.869 [main] TRACE cbacTracingAspect - Entering MyTracedService.performSomeLogic()
22:37:58.869 [main] INFO cbacMyTracedService - Inside performSomeLogic...
22:37:58.869 [main] TRACE cbacTracingAspect - Exiting MyTracedService.performSomeLogic()
5.结论
在本文中,我们使用AspectJ截获了一个类的所有方法,并在该类上添加了一个注释。这样做使我们能够快速将跟踪日志记录功能添加到新代码中。
我们还将跟踪日志输出逻辑合并到一个编译单元中,以提高我们随着应用程序的发展修改跟踪日志输出的能力。
0 评论