简体   繁体   中英

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

I want to initialize a repository object in Spring Boot without having to make it a bean or an Autowired property.

I just want to do feedRepository = FeedRepository() in Kotlin. Why won't Spring Boot allow me to do this? Why does it have to be autowired or a bean?

here's my code:

@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))
    }
}

Edit: ok so here's better context as to why I can't autowire things. Basically I'm doing this within a static function so I have absolutely no access to beans or autowired properties:

@SpringBootApplication
class Application

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

The Kafka scheduler basically executes several threads which all listen to kafka topics:

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)
        }
    }
}

however, I can't autowire the KafkaScheduler class as a bean within a static method so I can't really make that a component or autowire any repositories, as far as I know.

Well I figured it out. A simple @PostConstruct annotation solves everything I need for this. Essentially, I just mark KafkaScheduler as a @Component , autowire everything I need within it, the only difference is I added @PostConstruct to the init method so I have access to the autowired properties. Then I can autowire the repositories wherever I need them (in this case within QueueListener which uses 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)
        }
    }
}

Noone stops you from initializing objects by yourself inside the spring managed component.

However, these objects:

  • won't be managed by spring (eg if they also have dependencies you'll have to resolve them by yourself)
  • It doesn't make sense to use @Autowired in this case because it works only between spring beans.

For example, this is wrong because class A is not managed by spring:


// not managed by spring
class A {
}

@Component
class B {
  @Autowired 
  A a;
}

So I believe you aim for something like this:

@Component 
class UriParser() { 

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

Side note, I haven't learnt Kotlin, so the syntax might be wrong.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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