如何从不同的方法中提取遥测代码?装饰模式? AOP? Maven摇篮

问题描述

我们正在使用 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...
}