Aspectj 不适用于 kotlin [英] Aspectj doesn't work with kotlin

查看:28
本文介绍了Aspectj 不适用于 kotlin的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 kotlin 中使用 aspectj aop,这是我的代码:

i want to use aspectj aop in kotlin,here is my code:

我在 annotation.lazy_list 中的注释:

my annotation in annotation.lazy_list:

科特林:

 package anotation

@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class lazy_list

我的aspectj aop类:

my aspectj aop class:

@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",为什么?

when i call all() function , no error,but wont't print "123", why?

推荐答案

EDIT 9-2021 - 有一个很好的 android 更新插件,可以很好地替代我在下面的 2018 年原始答案:https://github.com/Ibotta/gradle-aspectj-pipeline-plugin

EDIT 9-2021 - there is a nice updated plugin for android that works well as an alternate to my original 2018 answer below: https://github.com/Ibotta/gradle-aspectj-pipeline-plugin

就其价值而言,我们需要在我们的 android 项目中使用 aspectJ 编织,但真的想转向 kotlin,所以我们必须解决这个问题.因此,该线程中使用 spring 或 maven 的解决方案对我们不起作用.这是 android gradle 项目的解决方案,然而,这将破坏增量编译,因此减慢您的构建时间和/或最终破坏某些东西.这让我们一直坚持到我可以重新思考我们的架构并逐步淘汰 aspectJ 或(希望)android 开始支持它.

For what it's worth, we needed aspectJ weaving in our android project but really wanted to move to kotlin so we had to solve this problem. So the solutions in this thread using spring or maven didn't work for us. This is the solution for android gradle projects however, this WILL break incremental compilation and therefor slow down your build times and/or break something eventually. This gets us by until I can re-think our architecture and phase out aspectJ or (hopefully) android starts supporting it.

OP 的一些答案和评论中存在混淆,kapt 解决了这个问题,但是 kapt 可以让您进行编译时注释处理,而不是编织.也就是说,注释处理器允许您根据注释生成代码,但不允许您将逻辑注入现有代码中.

There is confusion in some of the answers and comments to the OP that kapt solves this, but kapt lets you do compile time annotation processing, not weaving. That is, annotation processors let you generate code based on annotations but do not let you inject logic into existing code.

这建立在这篇关于将 aspectJ 添加到 android 的博客之上:https://ferndocejas.com/2014/08/03/aspect-oriented-programming-in-android

This builds on top of this blog on adding aspectJ to android: https://fernandocejas.com/2014/08/03/aspect-oriented-programming-in-android

你的 kotlin 类被编译成字节码,只是到一个不同的目录中.所以这个解决方案使用相同的过程来编织 java 类,但在 kotlin 类文件上再次运行它

Your kotlin classes get compiled into byte code, just into a different directory. So this solution using the same process to weave the java classes but runs it again on the kotlin class files

App/build.gradle 的顶部添加:

buildscript {
    ext.aspectjVersion = '1.9.1'
    dependencies {
        classpath "org.aspectj:aspectjtools:$aspectjVersion"
    }
}

在你的 App/build.gradle 底部添加:

At the bottom of your App/build.gradle add:

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
            }
        }
    }
}

这篇关于Aspectj 不适用于 kotlin的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆