Spring BeanName 生成

Bean name 的生成定义这接口BeanNameGenerator里面

/**
 * Strategy interface for generating bean names for bean definitions.
 */
public interface BeanNameGenerator {
	String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry);
}

具体实现为:org.springframework.context.annotation.AnnotationBeanNameGenerator

org.springframework.context.annotation.AnnotationBeanNameGenerator#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);
}

protected String buildDefaultBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
    return buildDefaultBeanName(definition);
}

protected String buildDefaultBeanName(BeanDefinition definition) {
    String beanClassName = definition.getBeanClassName();
    Assert.state(beanClassName != null, "No bean class name set");
    String shortClassName = ClassUtils.getShortName(beanClassName);
    return Introspector.decapitalize(shortClassName);
}

java.beans.Introspector#decapitalize

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);
}

从上面的代码可以看出有两种情况:

  • 如果类名的长度大于1,且前两个字母都是大写,那么bean name就是 类名,
  • 否则就是bean name 将类名首字母变小写

上面解释了BeanName是怎么生成的,那么BeanName是在什么阶段生成的呢?

一句话概括就是在讲Bean封装成BeanDefinitionHolder,注册到容器的时候生成的。这里面可以大致分为两种情况:

  • 将一般的带有@Component及其衍生注解的Bean注册到容器

    org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan

  • 将特殊的做"基建"工作的Bean注册到容器

    例如:org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean

posted @ 2021-11-04 23:06  Jonathan1  阅读(231)  评论(0编辑  收藏  举报