【问题标题】:How to use AOP annotation inside method not in method level如何在方法内部而不是在方法级别使用 AOP 注释
【发布时间】:2021-09-07 22:42:48
【问题描述】:

我正在使用 Spring AOP 记录 DB 执行时间,但它适用于整个方法执行时间。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TrackExecutionTime {

}

Is there any possibility that we can use this @TrackExecutionTime not in the method level but inside a method just above some statement like below - 

@TrackExecutionTime
List<Release> releaseList = releaseRepo.findByProductName(productName.toUpperCase());

这样我就可以只获取数据库执行时间,而不仅仅是整个方法执行时间,因为我的方法还包含其他业务逻辑,其中还包括我们是否在方法级别使用 AOP 注释。

【问题讨论】:

    标签: spring spring-boot aop spring-aop


    【解决方案1】:

    您的问题不是特定于 AOP 的,因为注释是 Java 语言功能。答案是:任意代码行上的注释不是 Java 语言概念的一部分,这对您来说意味着您也不能将它们用于 AOP 目的。这只是一个 Java 限制。 Spring AOP 和原生 AspectJ 都不能支持 Java 中不存在的特性。

    友情提示:请先多了解Java,再熟悉一些基本的软件设计和简洁的代码原则。最后,您将能够实现您想要的,尽管方式与您刚刚在这里梦想的方式不同。

    【讨论】:

      【解决方案2】:

      Spring AOP 默认配置使用代理来执行切面,因此只能注释方法。

      代理有点绕道。代理包装了目标方法,因此当您在其他地方调用方法时,Spring 确保调用代理上的方法,然后该调用包含在调用本身之前、之后、周围执行的方面代码(取决于方面)。可以有多个代理包装一个类。

      然后一个选项是将您的方面注释添加到存储库方法。

      如果我们只需要跟踪对该方法的子集调用的执行时间(这听起来有点奇怪的要求),那么我们可以添加一个包装器方法 - 比如说使用上述时间跟踪方法创建一个 Spring 管理的 Metrics 类接受一个 lambda 并用 @TrackExecutionTime 注释。原来的调用会是这样的

      metrics.executeTimed(() -> releaseRepo.findByProductName(productName.toUpperCase()));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-20
        • 1970-01-01
        • 1970-01-01
        • 2021-07-03
        相关资源
        最近更新 更多