Kotlin 的 AOP

标签 aop kotlin

我在 Java 中经常使用 AOP。看起来传统的 java 方法可以很容易地与 Kotlin 一起重用。鉴于 Kotlin 强调不变性,JDK 代理似乎是 Kotlin 中最可行的解决方案,前提是您遵循相同的接口(interface)优先(最好是 Kotlin 中的特征优先)编程风格,例如:

trait MyService {
 fun add(a: Int, b: Int): Int
}

class MyServiceImpl: MyService {...}

所以现在可以轻松地在 Spring/AOP 中编写一个切面并将其应用到 MyServiceImpl 的实例中。应该提到的是,基于 Java 接口(interface)的生成代理可能更受 Kotlin 开发人员的青睐,因为 cglib 需要摆脱 final(即诉诸 Kotlin 中的开放类)并为每个应该由 AOP 代理包装的类使用无参数的公共(public)构造函数.

与此同时,不幸的是,基于 Java 接口(interface)的生成代理会带来显着的性能损失,所以我想知道在某些情况下,AOP 编程是否可以更直观地或原生地对 Kotlin 进行。

因此,当我想将 AOP 用于以下示例时,请考虑以下示例:

  • 记录从服务公开的每个方法的参数和返回结果。
  • 在函数调用之前启动事务并在函数调用完成后关闭它(提交/回滚取决于在进行特定服务调用时是否引发了异常)。

在上述使用 MyService/MyServiceImpl 的示例中,最有效但不幸的是最冗长的蛮力解决方案可能如下所示:

class MyServiceLoggingWrapper(val delegate: MyService): MyService {
  val logger = LoggerFactory.getLogger(this.javaClass)

  override fun add(a: Int, b: Int): Int {
    val result = delegate.add(a, b);
    logger.info("MyService.add({}, {}) = {}", a, b, result);
    return result;
  }
} 

class MyServiceTxWrapper(val delegate: MyService, val txManager: TransactionManager): MyService {
 // similar lengthy implementation
}

该方法的 LoC 复杂度为 O(N*K),其中 N 是方法的数量,K 是我想要应用的多个方面。

所以我正在寻找的是一种可能有效(在性能和 LoC 方面)的解决方案,用于 Kotlin 中的各个方面,最好不要求助于 cglib 生成的代理,因为它们施加了太多限制,比如告别最终类并且没有无参数的公共(public)构造函数。

最佳答案

我不是 Kotlin 用户,但鉴于它针对的是 JVM,我建议尝试成熟的 AspectJ,而不是像 Spring AOP 这样的基于代理的“AOP lite”方法。 AspectJ 不需要/使用动态代理,它会在编译时或编译后(二进制编织)甚至在类加载(加载时编织)期间生成字节码。

关于Kotlin 的 AOP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28356317/

相关文章:

java - RxJava : Specifying maximum concurrency for a list of Completables

spring-boot - 来自 kubernetes yaml 的变量导致 : Could not resolve placeholder 'ACTUATOR_PASSWORD' in value "${ACTUATOR_PASSWORD}"

debugging - 如何记录 ColdFusion 应用程序中用于调试的所有方法调用

java - AspectJ、Spring AOP 与 JBoss AOP 的异常处理

java - 如果围绕操作类创建代理建议,Spring Web 应用程序上下文不会返回 Struts2 操作方法

unit-testing - 我怎样才能只开课来测试课?

java - 是否可以编写测试事务代码的事务单元测试?

java spring aop:java.lang.IllegalArgumentException:错误在::0找不到引用的切入点LoginMethod

android - logcat android studio 中的随机消息

java - 是否可以在 Android Room 中使用 String 作为 PrimaryKey