Ibotta / gradle-aspectj-pipeline-plugin

A Gradle plugin for Android projects which performs AspectJ weaving using Android's bytcode manipulation pipeline.
Apache License 2.0
76 stars 14 forks source link

using annotations #21

Closed schnaps1981 closed 2 years ago

schnaps1981 commented 2 years ago

Hello! can i use this plugin in annotations style?

eschlenz commented 2 years ago

I'm not 100% sure I understand what you mean. Can you elaborate on what it is you're trying to accomplish?

schnaps1981 commented 2 years ago

ok. Sorry for my English, so:

i try to create event tracker in my android app. Events which i need to track from my business logic appears in different methods (names of kotlin-functions). So i think good solution is just create annotation class and mark necessary function in business logic @Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.FUNCTION) annotation class Trigger

further in business logic module @Trigger fun myLogic() { //some business logic } further write tracker logic in @Aspect class like

@Aspect class KotlinAspect { @Before("**@annotation(Trigger**)") fun trackEvent() { // some tracker logic } }

i tried change example project from your repository but it's does not working

eschlenz commented 2 years ago

Oh! I understand. Yes, you can absolutely target methods with your own annotation. I'll give you an example that I have working locally.

Here is the annotation class code:

package com.ibotta.gradle.aop.kotlin

@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
@Target(
    AnnotationTarget.FUNCTION,
    AnnotationTarget.PROPERTY_GETTER,
    AnnotationTarget.PROPERTY_SETTER
)
annotation class Trigger()

Here is the aspect code:

package com.ibotta.gradle.aop.kotlin

import org.aspectj.lang.JoinPoint
import org.aspectj.lang.annotation.After
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before

@Aspect
class TriggerAspect {
    @Before("@annotation(Trigger) && execution(* *(..))")
    fun before(joinPoint: JoinPoint) {
        val messageListener = joinPoint.args[0] as MessageListener
        messageListener.onMessage("Kotlin AOP via Trigger annotation triggered.", CallerType.BEFORE_HOOK)
    }
}

I added these two classes to my local clone of the repo for testing inside the sample-kotlin module. I then modified the KotlinTargetExample class to look like this:

package com.ibotta.gradle.aop.kotlin

class KotlinTargetExample {
    @Trigger
    fun demonstrateKotlinAOP(messageListener: MessageListener) {
        messageListener.onMessage("Kotlin method with AOP attached is executed.", CallerType.TARGET)
    }
}

And when I run the sample-kotlin application in an emulator and hit the button to test, I get this (showing it works!):

Screen Shot 2022-05-17 at 12 18 37 PM

Note the output Kotlin AOP via Trigger annotation triggered showing that the new TriggerAspect logic ran as a result of using the @Trigger annotation.

Hopefully this helps you!

schnaps1981 commented 2 years ago

I writed @Before just @Before("@annotation(Trigger)") but need @Before("@annotation(Trigger) && execution( (..))")

thak you so much!

eschlenz commented 2 years ago

Great! Happy to help.