Quick Start
This guide walks you through creating your first aspect in under 5 minutes.
Step 1: Define a Target Annotation
Aspects intercept functions by matching annotations. Create a marker annotation:
// Marks functions whose execution should be logged
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.BINARY)
annotation class Logged
Tip
Use AnnotationRetention.BINARY — AspectK reads annotations at compile time only,
so RUNTIME retention is not required.
Step 2: Create an Aspect
An aspect is a class or object annotated with @Aspect. Inside it, define one or more
advice methods annotated with @Before:
import io.github.molelabs.aspectk.runtime.Aspect
import io.github.molelabs.aspectk.runtime.Before
import io.github.molelabs.aspectk.runtime.JoinPoint
@Aspect
object LoggingAspect {
@Before(target = [Logged::class])
fun log(joinPoint: JoinPoint) {
val name = joinPoint.signature.methodName
val args = joinPoint.args.joinToString(", ")
println("[$name] called with: $args")
}
}
Rules:
- The advice function must have exactly one parameter of type JoinPoint.
- The return type must be Unit.
- Use object to avoid per-call instantiation (recommended).
Step 3: Annotate Your Functions
Apply your target annotation to any function you want to intercept:
@Logged
fun placeOrder(userId: String, productId: Long) {
// AspectK injects LoggingAspect.log() here at compile time
println("Order placed by $userId for product $productId")
}
@Logged
fun cancelOrder(orderId: String) {
println("Order $orderId cancelled")
}
Step 4: Build and Run
AspectK injects the advice during compilation. The output when calling placeOrder would be:
Inspecting the JoinPoint
JoinPoint gives you full context about the intercepted call:
@Aspect
object DiagnosticAspect {
@Before(target = [Logged::class])
fun inspect(joinPoint: JoinPoint) {
val sig = joinPoint.signature
println("Method : ${sig.methodName}")
println("Returns : ${sig.returnTypeName}")
println("Receiver: ${joinPoint.target}")
sig.parameter.forEachIndexed { i, param ->
println(" arg[$i] ${param.name}: ${param.typeName} = ${joinPoint.args[i]}")
}
}
}