概要

Spring提供的BeanNameGenerator接口有3个实现:

org.springframework.beans.factory.support.BeanNameGenerator 无beanName的注解类实现: org.springframework.context.annotation.AnnotationBeanNameGenerator 无beanName的XML配置实现: org.springframework.beans.factory.support.DefaultBeanNameGenerator

DefaultBeanNameGenerator

BeanClass+#+0

  1. public static String generateBeanName(
  2. BeanDefinition definition, BeanDefinitionRegistry registry, boolean isInnerBean)
  3. throws BeanDefinitionStoreException {
  4. String generatedBeanName = definition.getBeanClassName();
  5. if (generatedBeanName == null) {
  6. if (definition.getParentName() != null) {
  7. generatedBeanName = definition.getParentName() + "$child";
  8. }
  9. else if (definition.getFactoryBeanName() != null) {
  10. generatedBeanName = definition.getFactoryBeanName() + "$created";
  11. }
  12. }
  13. if (!StringUtils.hasText(generatedBeanName)) {
  14. throw new BeanDefinitionStoreException("Unnamed bean definition specifies neither " +
  15. "'class' nor 'parent' nor 'factory-bean' - can't generate bean name");
  16. }
  17. if (isInnerBean) {
  18. // Inner bean: generate identity hashcode suffix.
  19. return generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(definition);
  20. }
  21. // Top-level bean: use plain class name with unique suffix if necessary.
  22. return uniqueBeanName(generatedBeanName, registry);
  23. }
  24. public static String uniqueBeanName(String beanName, BeanDefinitionRegistry registry) {
  25. String id = beanName;
  26. int counter = -1;
  27. // Increase counter until the id is unique.
  28. String prefix = beanName + GENERATED_BEAN_NAME_SEPARATOR; // 这个常量表示#
  29. while (counter == -1 || registry.containsBeanDefinition(id)) {
  30. counter++;
  31. id = prefix + counter;
  32. }
  33. return id;
  34. }

举个栗子

com.example.start.springdemo.spring.HelloWorldBeanPostProcessor#0

AnnotationBeanNameGenerator

当前类的短名称首字母小写

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