Kotlin cannot inject annotation at compile time such as by existing library Lombok. Is there any decent way to inject annotation for spring framework at runtime?
Asked
Active
Viewed 957 times
1 Answers
1
Assuming you are trying to inject logger annotation into Spring application.
Here's annotation class example: Log.kt
package com.example.util
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD)
@MustBeDocumented
annotation class Log
This class injects annotation at runtime: LogInjector.kt
package com.example.util
import org.slf4j.LoggerFactory
import org.springframework.beans.BeansException
import org.springframework.beans.factory.config.BeanPostProcessor
import org.springframework.stereotype.Component
import org.springframework.util.ReflectionUtils
import java.lang.reflect.Field
@Component
class LogInjector: BeanPostProcessor {
@Throws(BeansException::class)
override fun postProcessAfterInitialization(bean: Any, beanName: String): Any {
return bean
}
@Throws(BeansException::class)
override fun postProcessBeforeInitialization(bean: Any, name: String): Any {
ReflectionUtils.doWithFields(bean.javaClass,
@Throws(IllegalArgumentException::class, IllegalAccessException::class) { field: Field ->
// SAM conversion for Java interface
ReflectionUtils.makeAccessible(field)
if (field.getAnnotation(Log::class.java) != null) {
val log = LoggerFactory.getLogger(bean.javaClass)
field.set(bean, log)
}
}
)
return bean
}
}
Then, this class uses @Log
annotation: GreetingController.kt
package com.example.web
import org.slf4j.Logger
import org.springframework.web.bind.annotation.*
@RestController
class GreetingController {
@Log lateinit private var logger: Logger
@RequestMapping("/greeting")
fun greeting(): String {
logger.info("Greeting endpoint was called")
return "Hello"
}
}
To avoid calling logger in null-safe like logger?.info('...')
, this example marks the property with the late-initialized modifier.

ymkjp
- 91
- 1
- 11