Is it possible to use Spring AOP (AspectJ) with Kotlin properties? Specifically due to how Kotlin compiles properties to Java:
- a getter method, with the name calculated by prepending the get prefix
- a setter method, with the name calculated by prepending the set prefix (only for var properties)
- a private field, with the same name as the property name (only for properties with backing fields)
Consider the following minimal reproducible example:
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION)
annotation class TestAnnotation
...
@Aspect
class TestAspect {
@Around("@annotation(annotation)")
fun throwingAround(joinPoint: ProceedingJoinPoint, annotation: TestAnnotation): Any? {
throw RuntimeException()
}
}
...
internal class MinimalReproducibleExample {
open class TestProperties {
@TestAnnotation
val sampleProperty: String = "sample property"
@TestAnnotation
fun sampleFunction(): String = "sample function"
}
private lateinit var testProperties: TestProperties
@BeforeEach
fun setUp() {
val aspectJProxyFactory = AspectJProxyFactory(TestProperties())
aspectJProxyFactory.addAspect(TestAspect())
val aopProxyFactory = DefaultAopProxyFactory()
val aopProxy = aopProxyFactory.createAopProxy(aspectJProxyFactory)
testProperties = aopProxy.proxy as TestProperties
}
@Test
fun test() {
println(testProperties.sampleProperty)
println(testProperties.sampleFunction())
}
}
Running the test yields:
null
sample function
When debugging I can see that the generated proxy is a cglib-backed proxy, which should be able to proxy to a concrete class, but it does not seem to invoke the configured aspect. Is there something wrong with my @Around
definition, or is this a limitation of Kotlin properties and/or proxying concrete classes?