#spring #spring-boot #kotlin
Вопрос:
Мы можем получить доступ к управляемым компонентам spring из класса, который не является управляемым spring, с помощью метода getBean функции ниже. Я хочу сделать то же самое, но в Котлине. Как я могу перезаписать функцию getBeans в Котлине, чтобы она работала?
@Component
public class SpringContext implements ApplicationContextAware {
private static ApplicationContext context;
/**
* Returns the Spring managed bean instance of the given class type if it exists.
* Returns null otherwise.
* @param beanClass
* @return
*/
public static <T extends Object> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
// store ApplicationContext reference to access required beans later on
SpringContext.context = context;
}
}
Я пытался преобразовать его в kotlin, но получаю ошибку.
@Component
class SpringContext : ApplicationContextAware {
@Throws(BeansException::class)
override fun setApplicationContext(context: ApplicationContext) {
// store ApplicationContext reference to access required beans later on
SpringContext.Companion.context = context
}
companion object {
private var context: ApplicationContext? = null
fun <T : Any>getBean(beanClass: KClass<out T>): Any {
return context!!.getBean(beanClass)
}
}
}
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'java.lang.Object' available: more than one 'primary' bean found among candidates: [org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.annotation.internalPersistenceAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory....]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.determinePrimaryCandidate(DefaultListableBeanFactory.java:1591)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1188)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:420)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:350)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1133)
Каким-то образом переменная beanClass получает java.lang.Объект. Почему это происходит и как я могу это решить?
Ответ №1:
В моем приложении Kotlin создан компонент Spring класса под названием WhiskyCrawler
.
У меня есть контекст Spring только в моем main
методе, поэтому я могу вызывать getBean
только там.
Но поскольку в вашем коде есть контекст Spring, вы можете сосредоточиться на последней строке в следующем фрагменте кода:
@SpringBootApplication
class WhiskyApplication
fun main(args: Array<String>) {
val context = runApplication<WhiskyApplication>(*args)
val crawler = context.getBean(WhiskyCrawler::class.java)