我想在kotlin中使用aspectj aop,这是我的代码:
我在annotation.lazy_list中的注释:
Kotlin :
package anotation
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class lazy_list
我的aspectj aop类:
@Aspect
class ActiveListAop{
@Pointcut("execution(@annotation.lazy_list * *(..))")
fun profile() {
}
@Before("profile()")
fun testModeOnly(joinPoint: JoinPoint) {
println("123")
}
}
我的用法:
@lazy_list
fun all():List<T>{
return lazy_obj?.all() as List<T>
}
当我调用all()函数时,没有错误,但是不会打印“123”,为什么呢?
最佳答案
对于它的值(value),我们需要在我们的android项目中进行AspectJ编织,但确实想迁移到Kotlin,因此我们必须解决此问题。因此,该线程中使用spring或maven的解决方案对我们不起作用。这是android gradle项目的解决方案,但是,这将中断增量编译,因此会减慢您的构建时间和/或最终破坏某些内容。直到我可以重新考虑我们的体系结构并逐步淘汰AspectJ为止,或者(希望如此)Android开始支持它。
kapt可以解决此问题的一些答案和对OP的评论很困惑,但是kapt允许您进行编译时注释处理,而不是进行编织。也就是说,注释处理器允许您基于注释生成代码,但不允许您将逻辑注入(inject)现有代码中。
这是基于在将AspectJ添加到android上的此博客之上的:https://fernandocejas.com/2014/08/03/aspect-oriented-programming-in-android
您的kotlin类被编译为字节代码,而编译到另一个目录中。因此,此解决方案使用相同的过程来编织Java类,但在kotlin类文件上再次运行它
在App/build.gradle
的顶部添加:
buildscript {
ext.aspectjVersion = '1.9.1'
dependencies {
classpath "org.aspectj:aspectjtools:$aspectjVersion"
}
}
在您的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
}
}
}
}
关于kotlin - Aspectj无法与Kotlin一起使用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44364633/