BeanNameGenerator

在这里插入图片描述

BeanNameGenerator

public interface BeanNameGenerator {

	String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry);

}

参数为BeanDefinition 和 BeanDefinitionRegistry 类型,此处可以反映出spring需要的bean 是BeanDefinition。definition 是被生成名字的BeanDefinition实例;registry 生成名字后注册进的BeanDefinitionRegistry。

有两个实现版本,DefaultBeanNameGenerator和AnnotationBeanNameGenerator。其中DefaultBeanNameGenerator是给资源文件加载bean时使用(BeanDefinitionReader中使用);AnnotationBeanNameGenerator是为了处理注解生成bean name的情况。

AnnotationBeanNameGenerator

DefaultBeanNameGenerator

public class DefaultBeanNameGenerator implements BeanNameGenerator {
	
	public static final DefaultBeanNameGenerator INSTANCE = new DefaultBeanNameGenerator();

	@Override
	public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
		return BeanDefinitionReaderUtils.generateBeanName(definition, registry);
	}

}

显然DefaultBeanNameGenerator类将具体的处理方式委托给了,BeanDefinitionReaderUtils 中的generateBeanName(BeanDefinition, BeanDefinitionRegistry)方法处理。

	//org.springframework.beans.factory.support.BeanDefinitionReaderUtils
	public static String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {
		
		return generateBeanName(beanDefinition, registry, false);
	}
	//多指定了一个boolean型参数,是为了区分内部bean(innerBean)和顶级bean(top-level bean).
	public static String generateBeanName(
			BeanDefinition definition, BeanDefinitionRegistry registry, boolean isInnerBean)
			throws BeanDefinitionStoreException {
		//generatedBeanName定义为类前缀,读取bean的className,不一定是运行时的实际类型。
		String generatedBeanName = definition.getBeanClassName();
		//如果类名称为空
		if (generatedBeanName == null) { 
			if (definition.getParentName() != null) {
				//读取bean的parent bean name
				generatedBeanName = definition.getParentName() + "$child";
			}
			else if (definition.getFactoryBeanName() != null) {
				//读取生成该bean的factoryBean name名称做前缀
				generatedBeanName = definition.getFactoryBeanName() + "$created";
			}
		}
		//generatedBeanName为空字符串,抛出异常
		if (!StringUtils.hasText(generatedBeanName)) {
			throw new BeanDefinitionStoreException("Unnamed bean definition specifies neither " +
					"'class' nor 'parent' nor 'factory-bean' - can't generate bean name");
		}
		//当为内部bean时,调用系统底层的object唯一标识码生成
		if (isInnerBean) {
			// Inner bean: generate identity hashcode suffix.
			return generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(definition);
		}
		//否则即为顶级bean,生成策略是前缀+循环数字,直到找到没有被注册的id作为后缀
		// Top-level bean: use plain class name with unique suffix if necessary.
		return uniqueBeanName(generatedBeanName, registry);
	}
	/**
	将给定bean名称转换为给定bean工厂的惟一bean名称,必要时附加惟一计数器作为后缀。
	*/
	public static String uniqueBeanName(String beanName, BeanDefinitionRegistry registry) {
		String id = beanName;
		int counter = -1;

		// Increase counter until the id is unique.
		String prefix = beanName + GENERATED_BEAN_NAME_SEPARATOR;
		while (counter == -1 || registry.containsBeanDefinition(id)) {
			counter++;
			id = prefix + counter;
		}
		return id;
	}

重新整理下流程:

  1. 生成流程分为前后两部分,前面生成的叫前缀,后面生成的叫后缀。
  2. 读取待生成name实例的类名称,未必是运行时的实际类型。
  3. 如果类型为空,则判断是否存在parent bean,如果存在,读取parent bean的name+"$child"
  4. 如果parent bean 为空,那么判断是否存在factory bean ,如存在,factory bean name + “$created”.前缀生成完毕。
  5. 如果前缀为空,直接抛出异常,没有可以定义这个bean的任何依据。
  6. 前缀存在,判断是否为内部bean(innerBean,此处默认为false),如果是,最终为前缀+分隔符+十六进制的hashcode码。
  7. 如果是顶级bean(top-level bean ),则判断前缀+数字的bean是否已存在,循环查询,知道查询到没有使用的id为止。处理完成。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值