jun*_*unk 9 aop aspectj kotlin
我想在kotlin中使用aspectj aop,这是我的代码:
我在annotation.lazy_list中的注释:
科特林:
package anotation
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class lazy_list
Run Code Online (Sandbox Code Playgroud)
我的方面是一个类:
@Aspect
class ActiveListAop{
@Pointcut("execution(@annotation.lazy_list * *(..))")
fun profile() {
}
@Before("profile()")
fun testModeOnly(joinPoint: JoinPoint) {
println("123")
}
}
Run Code Online (Sandbox Code Playgroud)
我的用法:
@lazy_list
fun all():List<T>{
return lazy_obj?.all() as List<T>
}
Run Code Online (Sandbox Code Playgroud)
当我调用all()函数,没有错误,但不打印"123",为什么?
就其价值而言,我们需要在我们的 android 项目中使用 aspectJ,但我们真的很想迁移到 kotlin,所以我们必须解决这个问题。因此,该线程中使用 spring 或 maven 的解决方案对我们不起作用。这是 android gradle 项目的解决方案,然而,这将破坏增量编译,因此减慢您的构建时间和/或最终破坏某些东西。这让我们一直坚持到我可以重新思考我们的架构并逐步淘汰 aspectJ 或(希望)android 开始支持它。
对 kapt 解决此问题的 OP 的一些答案和评论存在混淆,但 kapt 可让您进行编译时注释处理,而不是编织。也就是说,注释处理器允许您根据注释生成代码,但不允许您将逻辑注入现有代码中。
这建立在这篇关于将 aspectJ 添加到 android 的博客之上:https ://fernandocejas.com/2014/08/03/aspect-orienting-programming-in-android
你的 kotlin 类被编译成字节码,只是到一个不同的目录中。所以这个解决方案使用相同的过程来编织 java 类,但在 kotlin 类文件上再次运行它
在您App/build.gradle添加的顶部:
buildscript {
ext.aspectjVersion = '1.9.1'
dependencies {
classpath "org.aspectj:aspectjtools:$aspectjVersion"
}
}
Run Code Online (Sandbox Code Playgroud)
在你的 App/build.gradle 底部添加:
android.applicationVariants.all { variant ->
// add the versionName & versionCode to the apk file name
variant.outputs.all { output ->
def newPath = outputFileName.replace(".apk", "-${variant.versionName}.${variant.versionCode}.apk")
outputFileName = new File(outputFileName, newPath)
def fullName = ""
output.name.tokenize('-').eachWithIndex { token, index ->
fullName = fullName + (index == 0 ? token : token.capitalize())
}
JavaCompile javaCompile = variant.javaCompiler
MessageHandler handler = new MessageHandler(true)
javaCompile.doLast {
String[] javaArgs = ["-showWeaveInfo",
"-1.8",
"-inpath", javaCompile.destinationDir.toString(),
"-aspectpath", javaCompile.classpath.asPath,
"-d", javaCompile.destinationDir.toString(),
"-classpath", javaCompile.classpath.asPath,
"-bootclasspath", project.android.bootClasspath.join(
File.pathSeparator)]
String[] kotlinArgs = ["-showWeaveInfo",
"-1.8",
"-inpath", project.buildDir.path + "/tmp/kotlin-classes/" + fullName,
"-aspectpath", javaCompile.classpath.asPath,
"-d", project.buildDir.path + "/tmp/kotlin-classes/" + fullName,
"-classpath", javaCompile.classpath.asPath,
"-bootclasspath", project.android.bootClasspath.join(
File.pathSeparator)]
new Main().run(javaArgs, handler)
new Main().run(kotlinArgs, handler)
def log = project.logger
for (IMessage message : handler.getMessages(null, true)) {
switch (message.getKind()) {
case IMessage.ABORT:
case IMessage.ERROR:
case IMessage.FAIL:
log.error message.message, message.thrown
break
case IMessage.WARNING:
case IMessage.INFO:
log.info message.message, message.thrown
break
case IMessage.DEBUG:
log.debug message.message, message.thrown
break
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
对于Kotlin中的注释过程,您必须启用并使用KAPT.如果没有通过Gradle或Maven插件添加,Kotlin代码中的注释处理将无法正常工作.
Kotlin插件支持Dagger或DBFlow等注释处理器.为了让他们使用Kotlin类,请应用kotlin-kapt插件.
也可以看看:
小智 5
spring + kotlin + AOP 工作得很好,只需访问http://start.spring.io/并生成一个支持 AOP 的项目,你可以在这里看到一段build.gradle ...
buildscript {
ext {
kotlinVersion = '1.2.30'
springBootVersion = '2.0.0.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}")
}
}
apply plugin: 'kotlin'
apply plugin: 'kotlin-spring'
apply plugin: 'org.springframework.boot'
...
dependencies {
compile('org.springframework.boot:spring-boot-starter-aop')
...
}
Run Code Online (Sandbox Code Playgroud)
插件kotlin-spring使所有类开放以允许 AOP
然后,只需按如下方式声明您的方面
@Aspect
@Component
class MyAspect {
...
Run Code Online (Sandbox Code Playgroud)
重要提示:使用@Aspect和@Component注释来注释您的方面类
小菜一碟!:)
| 归档时间: |
|
| 查看次数: |
4841 次 |
| 最近记录: |