AOP与Kotlin

Ale*_*lex 7 aop kotlin

我在Java上使用AOP很多.看起来传统的Java方法可以很容易地与Kotlin一起使用.考虑到Kotlin强调不变性,JDK代理似乎是Kotlin中最可行的解决方案,前提是你遵循相同的接口 - 首先(更好地说Kotlin中的trait-first)编程风格,例如:

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

class MyServiceImpl: MyService {...}
Run Code Online (Sandbox Code Playgroud)

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

同时,基于Java接口的生成代理不幸会造成严重的性能损失,因此我想知道在某些情况下是否可以更直观地或本地地对Kotlin进行AOP编程.

因此,请考虑以下示例,当我想使用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
}
Run Code Online (Sandbox Code Playgroud)

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

所以我正在寻找的是Kotlin方面可能有效(在性能和LoC方面)的解决方案,而不是诉诸于cglib生成的代理,因为它们施加了太多的限制,例如告别最终类而没有无参数的公共构造函数.

kri*_*aex 1

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