i want to use aspectj aop in kotlin,here is my code:
my annotation in annotation.lazy_list:
Kotlin:
package anotation
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class lazy_list
my aspectj aop class:
@Aspect
class ActiveListAop{
@Pointcut("execution(@annotation.lazy_list * *(..))")
fun profile() {
}
@Before("profile()")
fun testModeOnly(joinPoint: JoinPoint) {
println("123")
}
}
my usage:
@lazy_list
fun all():List<T>{
return lazy_obj?.all() as List<T>
}
when i call all() function , no error,but wont't print "123", why?
To enable @AspectJ, spring AOP provides @EnableAspectJAutoProxy annotation which will be annotated in java configuration. To work with spring AOP and @AspectJ support, we need to create a class annotated with @Aspect annotation.
In Spring AOP, aspects are implemented using regular classes (the schema-based approach) or regular classes annotated with the @Aspect annotation (the @AspectJ style). Join point: a point during the execution of a program, such as the execution of a method or the handling of an exception.
AspectJ is very widely used in a lot of Java frameworks (like Spring), but still most developers do not know AspectJ. Developers often think that AspectJ is difficult to learn or it makes your code complex, and they decide not to learn this very powerful and useful technology.
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
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.
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.
This builds on top of this blog on adding aspectJ to android: https://fernandocejas.com/2014/08/03/aspect-oriented-programming-in-android
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
at the top of your App/build.gradle
add:
buildscript {
ext.aspectjVersion = '1.9.1'
dependencies {
classpath "org.aspectj:aspectjtools:$aspectjVersion"
}
}
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
}
}
}
}
For annotation process in Kotlin, you must enable and use KAPT. Without this being added via Gradle or Maven plugin, nothing is going to work for annotation processing in Kotlin code.
The Kotlin plugin supports annotation processors like Dagger or DBFlow. In order for them to work with Kotlin classes, apply the kotlin-kapt plugin.
See also:
spring + kotlin + AOP work nice, just go to http://start.spring.io/ and generate a project with AOP support, you can see a piece of build.gradle here...
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')
...
}
plugin kotlin-spring makes all classes open to allow AOP
Then, just declare your aspect as follows
@Aspect
@Component
class MyAspect {
...
Important: annotate your aspect class with @Aspect and @Component annotations
Piece of cake! :)
You can use freefair gradle plugin
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "io.freefair.gradle:aspectj-plugin:5.2.1"
}
}
apply plugin: "io.freefair.aspectj.post-compile-weaving"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With