Bean definition DSL generates unique bean names for bean classes

Issue: SPR-17242
This commit is contained in:
Juergen Hoeller 2018-09-12 14:59:10 +02:00
parent b83bc39ecd
commit b6d32ef55f
3 changed files with 30 additions and 24 deletions

View File

@ -124,13 +124,29 @@ public abstract class BeanDefinitionReaderUtils {
id = generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(definition);
}
else {
// Top-level bean: use plain class name.
// Increase counter until the id is unique.
int counter = -1;
while (counter == -1 || registry.containsBeanDefinition(id)) {
counter++;
id = generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + counter;
}
// Top-level bean: use plain class name with unique suffix if necessary.
return uniqueBeanName(generatedBeanName, registry);
}
return id;
}
/**
* Turn the given bean name into a unique bean name for the given bean factory,
* appending a unique counter as suffix if necessary.
* @param beanName the original bean name
* @param registry the bean factory that the definition is going to be
* registered with (to check for existing bean names)
* @return the unique bean name to use
* @since 5.1
*/
public static String uniqueBeanName(String beanName, BeanDefinitionRegistry registry) {
String id = beanName;
int counter = -1;
// Increase counter until the id is unique.
while (counter == -1 || registry.containsBeanDefinition(id)) {
counter++;
id = beanName + GENERATED_BEAN_NAME_SEPARATOR + counter;
}
return id;
}

View File

@ -18,6 +18,7 @@ package org.springframework.context.support
import org.springframework.beans.factory.config.BeanDefinitionCustomizer
import org.springframework.beans.factory.support.AbstractBeanDefinition
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils
import org.springframework.context.ApplicationContextInitializer
import org.springframework.core.env.ConfigurableEnvironment
import java.util.function.Supplier
@ -167,11 +168,8 @@ open class BeanDefinitionDsl(private val init: BeanDefinitionDsl.() -> Unit,
}
}
when (name) {
null -> context.registerBean(T::class.java, customizer)
else -> context.registerBean(name, T::class.java, customizer)
}
val beanName = name ?: BeanDefinitionReaderUtils.uniqueBeanName(T::class.java.name, context);
context.registerBean(beanName, T::class.java, customizer)
}
/**
@ -207,13 +205,8 @@ open class BeanDefinitionDsl(private val init: BeanDefinitionDsl.() -> Unit,
}
when (name) {
null -> context.registerBean(T::class.java,
Supplier { function.invoke() }, customizer)
else -> context.registerBean(name, T::class.java,
Supplier { function.invoke() }, customizer)
}
val beanName = name ?: BeanDefinitionReaderUtils.uniqueBeanName(T::class.java.name, context);
context.registerBean(beanName, T::class.java, Supplier { function.invoke() }, customizer)
}
/**

View File

@ -34,7 +34,6 @@ class BeanDefinitionDslTests {
val beans = beans {
bean<Foo>()
bean<Bar>("bar", scope = Scope.PROTOTYPE)
bean { Baz(ref()) }
bean { Baz(ref("bar")) }
}
@ -59,7 +58,6 @@ class BeanDefinitionDslTests {
}
}
profile("baz") {
bean { Baz(ref()) }
bean { Baz(ref("bar")) }
}
}
@ -89,7 +87,6 @@ class BeanDefinitionDslTests {
bean { FooFoo(env["name"]!!) }
}
environment( { activeProfiles.contains("baz") } ) {
bean { Baz(ref()) }
bean { Baz(ref("bar")) }
}
}
@ -133,8 +130,8 @@ class BeanDefinitionDslTests {
@Test // SPR-16269
fun `Provide access to the context for allowing calling advanced features like getBeansOfType`() {
val beans = beans {
bean<Foo>("foo1")
bean<Foo>("foo2")
bean<Foo>()
bean<Foo>()
bean { BarBar(context.getBeansOfType<Foo>().values) }
}