繁体   English   中英

如何在不使用 bean 或注释的情况下手动初始化 Spring Boot 存储库? (科特林)

[英]How do I manually initialize a Spring Boot repository without using beans or annotations? (Kotlin)

我想在 Spring Boot 中初始化repository对象,而不必使其成为 bean 或Autowired属性。

我只想在 Kotlin 中执行feedRepository = FeedRepository() 为什么 Spring Boot 不允许我这样做? 为什么它必须是自动装配的或 bean?

这是我的代码:

@Component
class UriParser() {
    @Autowired
    lateinit var uriRepository: UriRepository

    @Autowired
    lateinit var hostRepository: HostRepository

    @Autowired
    lateinit var feedRepository: FeedRepository

    fun parseUri(uri: String) : Feed {
        val urlRepository = UriRepository()
        val uri = URI(uri)

        val uriRecord = uriRepository.save(Uri(scheme = uri.scheme, host = uri.host, port = uri.port))
        hostRepository.save(Host(host = uri.host))

        return feedRepository.save(Feed(uriId = uriRecord.id))
    }
}

编辑:好的,所以这里有更好的背景说明为什么我不能自动装配东西。 基本上我在静态函数中执行此操作,因此我绝对无法访问 bean 或自动装配的属性:

@SpringBootApplication
class Application

fun main(args: Array<String>) {
    runApplication<Application>(*args)
     KafkaScheduler().init()
}

Kafka 调度程序基本上执行几个线程,这些线程都监听 kafka 主题:

class KafkaScheduler() {
    // this doesn't work....
    @Autowired
    lateinit var feedRepository: FeedRepository

    fun init() {
        val threads = arrayOf(
            {
                QueueListener().init()
            },
            {
                PrefetchListener().init()
            },
            {
                FetchListener().init()
            }
        )

        val service = Executors.newFixedThreadPool(threads.size)

        for (thread in threads) {
            service.submit(thread)
        }
    }
}

但是,我无法将 KafkaScheduler 类自动装配为静态方法中的 bean,因此据我所知,我无法真正将其作为组件或自动装配任何存储库。

好吧,我想通了。 一个简单的@PostConstruct注释解决了我需要的一切。 本质上,我只是将KafkaScheduler标记为@Component ,在其中自动装配我需要的一切,唯一的区别是我将@PostConstruct添加到 init 方法,以便我可以访问自动装配的属性。 然后,我可以自动装配存储库的地方,我需要他们(在中这种情况下QueueListener它采用UriParser

@Component
class KafkaScheduler() {
    @Autowired
    lateinit var queueListener: QueueListener

    @Autowired
    lateinit var prefetchListener: PrefetchListener

    @Autowired
    lateinit var fetchListener: FetchListener

    @PostConstruct
    fun init() {
        val threads = arrayOf(
            {
                queueListener.init()
            },
            {
                prefetchListener.init()
            },
            {
                fetchListener.init()
            }
        )

        val service = Executors.newFixedThreadPool(threads.size)

        for (thread in threads) {
            service.submit(thread)
        }
    }
}

没有人会阻止您在 spring 管理的组件内自行初始化对象。

但是,这些对象:

  • 不会由 spring 管理(例如,如果它们也有依赖项,你必须自己解决它们)
  • 在这种情况下使用@Autowired没有意义,因为它只适用于 spring bean。

例如,这是错误的,因为类 A 不是由 spring 管理的:


// not managed by spring
class A {
}

@Component
class B {
  @Autowired 
  A a;
}

所以我相信你的目标是这样的:

@Component 
class UriParser() { 

    // no autowired here, you manage everything by youself
    // also possible from constructor
    lateinit var uriRepository = UriRepository()
    ...
}

旁注,我没有学过 Kotlin,所以语法可能是错误的。

暂无
暂无

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

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