Kotlin无法在编译时注入注释,例如现有库Lombok。有没有什么好的方法可以在运行时为spring框架注入注释?
答案 0 :(得分:1)
假设您正在尝试将注册器注释注入Spring应用程序。
这是注释类示例: Log.kt
package com.example.util
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD)
@MustBeDocumented
annotation class Log
此类在运行时注入注释: 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
}
}
然后,此类使用@Log
注释: 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"
}
}
为避免像logger?.info('...')
那样在null-safe中调用logger,此示例使用the late-initialized modifier标记属性。