Bean的命名规则,定义在BeanNameGenerator接口的实现类
1.通过注解扫描Bean的命名规则
实现类:AnnotationBeanNameGenerator继承了BeanNameGenerator
先看generateBeanName方法,这是入口
@Override
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
if (definition instanceof AnnotatedBeanDefinition) {
String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
if (StringUtils.hasText(beanName)) {
// Explicit bean name found.
return beanName;
}
}
// Fallback: generate a unique default bean name.
return buildDefaultBeanName(definition, registry);
}
这里判断是否为注解类型的Bean,是的话通过注解内容确定Bean名字;如果确认不了,使用默认方法生成Bean名字。
先看下怎么通过注解来判断Bean名字,逻辑在determineBeanNameFromAnnotation方法里。
protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) {
AnnotationMetadata amd = annotatedDef.getMetadata();
Set<String> types = amd.getAnnotationTypes();
String beanName = null;
for (String type : types) {
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type);
if (isStereotypeWithNameValue(type, amd.getMetaAnnotationTypes(type), attributes)) {
Object value = attributes.get("value");
if (value instanceof String) {
String strVal = (String) value;
if (StringUtils.hasLength(strVal)) {
if (beanName != null && !strVal.equals(beanName)) {
throw new IllegalStateException("Stereotype annotations suggest inconsistent " +
"component names: '" + beanName + "' versus '" + strVal + "'");
}
beanName = strVal;
}
}
}
}
return beanName;
}
取到Bean的原信息里的注解信息,遍历每个注解,确定注解是否符合条件的注解,取注解里的value值为Bean名字。
(符合条件:注解为@Component或者包含@Component或javax.annotation.ManagedBean或javax.inject.Named,且注解包含value属性)
如果通过注解信息不能确认Bean名字,那么就执行默认生成策略。
protected String buildDefaultBeanName(BeanDefinition definition) {
String shortClassName = ClassUtils.getShortName(definition.getBeanClassName());
return Introspector.decapitalize(shortClassName);
}
通过截取类的名字,变转为符合Java变量名格式的字符串,作为Bean名字。下面是标准变量名的规则,变量名以小写字母开头,或者两个大写字母开头。
public static String decapitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
Character.isUpperCase(name.charAt(0))){
return name;
}
char chars[] = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}
流程图