我想在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/

10-12 03:20