简体   繁体   English

Kotlin的弹簧注释注入

[英]Annotation Injection for Spring with Kotlin

Kotlin cannot inject annotation at compile time such as by existing library Lombok . Kotlin无法在编译时注入注解,例如现有的Lombok库。 Is there any decent way to inject annotation for spring framework at runtime? 有什么不错的方法在运行时为spring框架注入注解吗?

Assuming you are trying to inject logger annotation into Spring application. 假设您尝试将记录器注释注入到Spring应用程序中。

Here's annotation class example: Log.kt 这是注释类示例: Log.kt

package com.example.util
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD)
@MustBeDocumented
annotation class Log

This class injects annotation at runtime: LogInjector.kt 此类在运行时注入注释: 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 然后,此类使用@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"
  }
}

To avoid calling logger in null-safe like logger?.info('...') , this example marks the property with the late-initialized modifier . 为了避免以logger?.info('...')类的null-safe方式调用logger,此示例使用Late-initialized修饰符标记该属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM