From 61ef21737426eef0d16e2d6ca542d29ab2c42137 Mon Sep 17 00:00:00 2001 From: huifer Date: Mon, 28 Sep 2020 14:06:53 +0800 Subject: [PATCH] doc: BeanNameGenerator --- docs/Spring/clazz/Spring-BeanNameGenerator.md | 140 ++++++++++++++++++ images/spring/BeanNameGenerator.png | Bin 0 -> 15181 bytes 2 files changed, 140 insertions(+) create mode 100644 docs/Spring/clazz/Spring-BeanNameGenerator.md create mode 100644 images/spring/BeanNameGenerator.png diff --git a/docs/Spring/clazz/Spring-BeanNameGenerator.md b/docs/Spring/clazz/Spring-BeanNameGenerator.md new file mode 100644 index 0000000..c04649d --- /dev/null +++ b/docs/Spring/clazz/Spring-BeanNameGenerator.md @@ -0,0 +1,140 @@ +# Spring BeanNameGenerator +- Author: [HuiFer](https://github.com/huifer) +- 源码阅读仓库: [SourceHot-spring](https://github.com/SourceHot/spring-framework-read) + + +- `org.springframework.beans.factory.support.BeanNameGenerator` +- 方法用来生成 beanName + + +```java +public interface BeanNameGenerator { + + /** + * Generate a bean name for the given bean definition. + * 生成 beanName + * @param definition the bean definition to generate a name for + * @param registry the bean definition registry that the given definition + * is supposed to be registered with + * @return the generated bean name + */ + String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry); + +} +``` + + + +![](/images/spring/BeanNameGenerator.png) + + + + + +## DefaultBeanNameGenerator + +- `org.springframework.beans.factory.support.DefaultBeanNameGenerator` + + + +- 调用工具类方法进行生成 + +```JAVA +@Override +public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) { + return BeanDefinitionReaderUtils.generateBeanName(definition, registry); +} +``` + + + +1. ClassName + # + 十六进制字符 +2. parentName + $child + # + 十六进制字符 +3. factoryBeanName +$created+# + 十六进制字符 +4. beanName + # + 序号 + +```java +public static String generateBeanName( + BeanDefinition definition, BeanDefinitionRegistry registry, boolean isInnerBean) + throws BeanDefinitionStoreException { + + // 获取 bean class 的名称 + // Class.getName() + String generatedBeanName = definition.getBeanClassName(); + if (generatedBeanName == null) { + // 父类名称是否存在 + if (definition.getParentName() != null) { + generatedBeanName = definition.getParentName() + "$child"; + } + // 工厂 beanName 是否为空 + 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) { + // Inner bean: generate identity hashcode suffix. + // 组装名称 + // 生成名称 + # + 16 进制的一个字符串 + id = generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(definition); + } + else { + // Top-level bean: use plain class name with unique suffix if necessary. + // 唯一beanName设置 + // // beanName + # + 序号 + return uniqueBeanName(generatedBeanName, registry); + } + return id; +} +``` + + + + + +## AnnotationBeanNameGenerator + +1. 获取注解的value作为beanName +2. 类名首字母小写 + +```java +@Override +public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) { + if (definition instanceof AnnotatedBeanDefinition) { + // 从注解中获取 beanName + // 获取注解的value属性值 + String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition); + if (StringUtils.hasText(beanName)) { + // Explicit bean name found. + // 如果存在直接返回 + return beanName; + } + } + // Fallback: generate a unique default bean name. + // 默认beanName + // 类名,首字母小写 + return buildDefaultBeanName(definition, registry); +} +``` + + + + + +## FullyQualifiedAnnotationBeanNameGenerator + +- 全类名 + +```java +@Override +protected String buildDefaultBeanName(BeanDefinition definition) { + String beanClassName = definition.getBeanClassName(); + Assert.state(beanClassName != null, "No bean class name set"); + return beanClassName; +} +``` \ No newline at end of file diff --git a/images/spring/BeanNameGenerator.png b/images/spring/BeanNameGenerator.png new file mode 100644 index 0000000000000000000000000000000000000000..2592dfee99cdf77f43c80016ab549dba2bf36207 GIT binary patch literal 15181 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