With 6.1.0-RC1 (and likely prior), the following test of the BeanFactory.getBean extension fails, presumably due to erasure:

@SpringBootTest
internal class SpringGetBeanNestedGenericIT {

    @Configuration
    class TestConfig {

        @Bean
        fun listOfString(): List<String> =
            listOf("Testing")

        @Bean
        fun listOfListOfString(): List<List<String>> =
            listOf(listOf("Testing"))
    }

    @Test
    fun `test getBean with nested generic`(
        applicationContext: ApplicationContext
    ) {
        assertThatNoException().isThrownBy {

            applicationContext.getBean<List<String>>()
        }
    }
}

Error message showing the listOfString and listOfListOfString beans being seen as the same type after erasure:

java.lang.AssertionError: 
Expecting code not to raise a throwable but caught
  "org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'java.util.List' available: expected single matching bean but found 2: listOfString,listOfListOfString
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1310)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:484)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:339)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:332)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1192)
    at org.sdkotlin.springdemo.SpringGetBeanNestedGenericIT.test_getBean_with_nested_generic$lambda$0(SpringGetBeanNestedGenericIT.kt:37)
    at org.assertj.core.api.ThrowableAssert.catchThrowable(ThrowableAssert.java:63)
    at org.assertj.core.api.NotThrownAssert.isThrownBy(NotThrownAssert.java:43)
    at org.sdkotlin.springdemo.SpringGetBeanNestedGenericIT.test getBean with nested generic(SpringGetBeanNestedGenericIT.kt:30)

If I remove the listOfListOfString bean from the configuration, the test passes.

I can inject both beans just fine, i.e. the following passes:

@Test
fun `test listOfString is injected`(
    @Autowired
    listOfString: List<String>
) {
    assertThat(listOfString).isEqualTo(LIST_OF_STRING)
}

@Test
fun `test listOfListOfString is injected`(
    @Autowired
    listOfListOfString: List<List<String>>
) {
    assertThat(listOfListOfString).isEqualTo(LIST_OF_LIST_OF_STRING)
}

I notice the BeanFactory.getBeanProvider extension uses the super type token approach. Perhaps this could be used as well for getBean to address this issue:

inline fun <reified T : Any> BeanFactory.getBean(): T =
    getBeanProvider<T>(ResolvableType.forType((object : ParameterizedTypeReference<T>() {}).type)).`object`

If I import that version of the extension instead, the test passes with the listOfListOfString bean in the configuration.

Comment From: ianbrandt

Added #31444 to request ParameterizedTypeReference overloads to the Java BeanFactory.getBean methods, which would presumably streamline the implementation of the Kotlin extensions.

Comment From: sdeleuze

You can get the behavior you want with applicationContext.getBeanProvider<List<String>>().getObject() or getIfAvailable() since we are leveraging the underlying ResolvableType based capabilities. That said, we could maybe potentially leverage that instead of getBean(T::class.java) for the implementation of the inline fun <reified T : Any> BeanFactory.getBean(): T Kotlin extension. I will give it more thoughts and let you know.

Comment From: ianbrandt

Thanks for the fix, @sdeleuze!