问题描述
我们正在使用 Application Insights 来监控应用程序中的不同服务调用。 Application Insights 的数据由许多不同的方法和类提供,但始终以相同的方式/由相同的代码片段提供:
public class MyClassA {
public void myMethodA() {
final Instant startTime = Instant.Now();
try {
callSomeServiceA();
} catch (final Exception e) {
sendExceptionDataToAppInsights(e);
throw e;
} finally {
sendDataToAppInsights(MyClass.getName(),myMethodA.getName(),startTime,Instant.Now());
}
}
}
public class MyClassB {
public String myMethodB() {
final Instant startTime = Instant.Now();
try {
return callSomeServiceB();
} catch (final Exception e) {
sendExceptionDataToAppInsights(e);
throw e;
} finally {
sendDataToAppInsights(MyClass.getName(),Instant.Now());
}
}
}
我如何能够将那些包装 try catch 片段提取到一个责任点?我查看了 dacorator 模式,但我想它不适合,因为方法签名不同。或者是吗?
或者有没有办法用AOP来实现?
解决方法
Aspect-Oriented Programming 是模块化横切关注点的范例,例如日志记录、监控和错误处理(您的特殊情况)。
在 Java 中实现此目的最流行的框架是 AspectJ,它可以通过 spring-boot-starter-aop
依赖项从任何 Spring 项目中使用。
Maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>${aop-version}</version>
</dependency>
摇篮
implementation `org.springframework.boot:spring-boot-starter-aop:${aop-version}`
实现您所要求的最简单方法是创建一个使用 @Aspect
的方面(使用 @Around
)。网上有很多这样的例子。您的执行 (ProceedingJoinPoint
:: proceed
) 将需要发生在与您的问题非常相似的 try-catch 块中:
@Around("execution(<aspectj-selector-here>)")
public void anyMethodName(ProceedingJoinPoint pjp) {
// try-catch blocks here...
}