假设我有一个接口(interface)Yoyo和该接口(interface)的不同实现:

interface Yoyo {
    fun haha() {
        println("hello world")
    }
}

@Component class Yoyo1 : Yoyo
@Component class Yoyo2 : Yoyo
@Component class Yoyo3 : Yoyo
@Component class YoyoN : Yoyo

现在,我想实例化所有bean,并在上下文初始化后执行一些逻辑:
@SpringBootApplication
class YoyoApp

fun main(args: Array<String>) {
    SpringApplicationBuilder()
            .sources(YoyoApp::class.java)
            .initializers(beans {
               bean {
                   CommandLineRunner {
                       val y1 = ref<Yoyo1>()
                       val y2 = ref<Yoyo2>()
                       val y3 = ref<Yoyo3>()
                       val yN = ref<YoyoN>()
                       arrayOf(y1, y2, y3, yN).forEach { it.haha() }
                   }
               }
            })
            .run(*args)
}

我不想这样做,而是手动获取所有Bean的引用(这很繁琐),而是这样做:
val list = ref<List<Yoyo>>()
list.forEach { it.haha() }

但是我得到一个异常(exception):
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.util.List<?>' available

我知道我可以这样做,但是我想使用新的Kotlin DSL:
@Component
class Hoho : CommandLineRunner {
    @Autowired
    lateinit var list: List<Yoyo>

    override fun run(vararg args: String?) {
        list.forEach { it.haha() }
    }
}

可能吗?有任何想法吗?

附言这是gist

最佳答案

@ zsmb13在上一个答案中提到的contextleft internal,它支持provider<Any>()函数(从Spring 5.1.1开始)。因此,最终我得到以下结果:

interface Yoyo {
    fun haha() {
        println("hello world from: ${this.javaClass.canonicalName}")
    }
}

@Component class Yoyo1 : Yoyo
@Component class Yoyo2 : Yoyo
@Component class Yoyo3 : Yoyo
@Component class YoyoN : Yoyo


@SpringBootApplication
class YoyoApp

fun main(args: Array<String>) {
    SpringApplicationBuilder()
        .sources(YoyoApp::class.java)
        .initializers(beans {
            bean {
                CommandLineRunner {
                    val list = provider<Yoyo>().toList()
                    list.forEach { it.haha() }
                }
            }
        })
        .run(*args)
}

10-06 13:35