簡體   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