Spring Bean Naming Conventions
In Spring, each bean has one or more identifiers that must be unique within the container where the bean resides. Typically, a bean has a single identifier, but aliases can be used to extend the identifiers if needed. In XML-based configuration, developers can specify bean identifiers using the
id
orname
attributes. Generally, identifiers are composed of letters and may include special characters. If aliases are used, they can be separated by commas,
or semicolons;
in thename
attribute. Theid
orname
attributes are not mandatory; if left empty, the container will automatically generate a unique name for the bean. Although there are no strict naming restrictions, the official recommendation is to follow camelCase conventions, which align with Java naming conventions.
Default Bean Name Generation in Spring
The Spring framework provides the BeanNameGenerator
interface to generate bean names by default. There are two main implementations: DefaultBeanNameGenerator
and AnnotationBeanNameGenerator
.
DefaultBeanNameGenerator
The DefaultBeanNameGenerator
is the standard implementation used to generate bean names. Here is the implementation in detail:
public class DefaultBeanNameGenerator implements BeanNameGenerator {
@Override
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
return BeanDefinitionReaderUtils.generateBeanName(definition, registry);
}
}
public class BeanDefinitionReaderUtils {
public static String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
return generateBeanName(beanDefinition, registry, false);
}
public static String generateBeanName(
BeanDefinition definition, BeanDefinitionRegistry registry, boolean isInnerBean)
throws BeanDefinitionStoreException {
String generatedBeanName = definition.getBeanClassName();
if (generatedBeanName == null) {
if (definition.getParentName() != null) {
generatedBeanName = definition.getParentName() + "$child";
} else if (definition.getFactoryBeanName() != null) {
generatedBeanName = definition.getFactoryBeanName() + "$created";
}
}
if (!StringUtils.hasText(generatedBeanName)) {
throw new BeanDefinitionStoreException("Unnamed bean definition specifies neither " +
"'class' nor 'parent' nor 'factory-bean' - can't generate bean name");
}
String id = generatedBeanName;
if (isInnerBean) {
id = generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(definition);
} else {
return uniqueBeanName(generatedBeanName, registry);
}
return id;
}
public static String uniqueBeanName(String beanName, BeanDefinitionRegistry registry) {
String id = beanName;
int counter = -1;
while (counter == -1 || registry.containsBeanDefinition(id)) {
counter++;
id = beanName + GENERATED_BEAN_NAME_SEPARATOR + counter;
}
return id;
}
}
AnnotationBeanNameGenerator for Annotation-Based Scanning
The AnnotationBeanNameGenerator
is used for generating bean names based on annotations. Here is its implementation:
public class AnnotationBeanNameGenerator implements BeanNameGenerator {
@Override
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
if (definition instanceof AnnotatedBeanDefinition) {
String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
if (StringUtils.hasText(beanName)) {
return beanName;
}
}
return buildDefaultBeanName(definition, registry);
}
}
For beans registered using @Bean
, if the name
attribute is not specified, the default bean name is the method name:
@Configuration
public class ConfigurationClassBeanDefinitionReader {
public void loadBeanDefinitionsForBeanMethod(...) {
// Key code
List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
String beanName = (!names.isEmpty() ? names.remove(0) : methodName);
}
}
Summary
This article provides a detailed explanation of Spring bean naming conventions and analyzes the related source code. I hope this information is helpful for your Spring development.