Spring IoC的细节--BeanDefinitionParserDelegate.parseBeanDefinitionElement(Element ele)

参考博客:https://blog.csdn.net/sunchen2012/article/details/82415656

    //解析Bean定义资源Document对象的普通元素
	protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
   

		//将Element元素--->BeanDefinition的过程在此
		//对Document对象中<Bean>元素的解析由BeanDefinitionParserDelegate实现
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);  //代码1

		if (bdHolder != null) {
   
			//修饰BeanDefinition
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
   
			
				//主线
				//向Spring IOC容器注册解析得到的Bean定义,这是Bean定义向IOC容器注册的入口
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			catch (BeanDefinitionStoreException ex) {
   
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			
			//在完成向Spring IOC容器注册解析得到的Bean定义之后,发送注册事件
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}

代码1为解析DOM元素为BeanDefinition,具体操作如下。

由BeanDefinitionParserDelegate提供parseBeanDefinitionElement方法的实现:

    public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
   
		return parseBeanDefinitionElement(ele, null);
	}
	
	public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
   
	    //获取id的值
		String id = ele.getAttribute(ID_ATTRIBUTE);
		//获取name的值,作为别名的
		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

		List<String> aliases = new ArrayList<>();
		if (StringUtils.hasLength(nameAttr)) {
   
		    //假如name字段有值,则进行解析操作,并添加到别名集合aliases中
		    //name的值可以用“,” “;” ",;" 分割,这里会解析为数组,当成多个别名使用
			String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
			aliases.addAll(Arrays.asList(nameArr));
		}

		//id作为bean的名称
		String beanName = id;
		if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
   
			//假如id为空,且别名不为空,则取首个别名作为beanName
			beanName = aliases.remove(0);
			if (logger.isDebugEnabled()) {
   
				logger.debug("No XML 'id' specified - using '" + beanName +
						"' as bean name and " + aliases + " as aliases");
			}
		}

		if (containingBean == null) {
   
			//判断在当前<beans>中 是否有相同的名称
			checkNameUniqueness(beanName, aliases, ele);
		}
		
		//调用重载方法 进行解析
		//主线
		AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); 
		if (beanDefinition != null) {
   
			//假如未声明别名和id的bean,则生成唯一的名称作为beanName
			if (!StringUtils.hasText(beanName)) {
   
				try {
   
					if (containingBean != null) {
   
						beanName = BeanDefinitionReaderUtils.generateBeanName(
								beanDefinition, this.readerContext.getRegistry(), true);
					}
					else {
   
						//生成一个“类名”+“#数字”的名称
						beanName = this.readerContext.generateBeanName(beanDefinition);
						//获取类名
						String beanClassName = beanDefinition.getBeanClassName();
						if (beanClassName != null &&
								beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
								!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
   
							//假如类名称未使用,则将类名作为当前bean的别名
							aliases.add(beanClassName);
						}
					}
					
				}
				catch (Exception ex) {
   
					error(ex.getMessage(), ele);
					return null;
				}
			}
			String[] aliasesArray = StringUtils.toStringArray(aliases);
			//将BeanDefinition封装至BeanDefinitionHolder中,并返回
			return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
		}

		return null;
	}

继续到重载方法,看DOM元素解析过程:

	public AbstractBeanDefinition parseBeanDefinitionElement(
			Element ele, String beanName, @Nullable BeanDefinition containingBean) {
   

		//将当前bean解析入栈,记录解析<bean>的过程,parseState可以通过toString来打印调用栈链
		//下面解析property的时候,也同样记录了
		this.parseState.push(new BeanEntry(beanName));

		String className = null;
		if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
   
			className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
		}
		String parent = null;
		if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
   
			parent = ele.getAttribute(PARENT_ATTRIBUTE);
		}

		try {
   
			//根据类名和父类名创建BeanDefinition
			AbstractBeanDefinition bd = createBeanDefinition(className, parent);   //代码1

			//解析DOM中的属性,并存入到AbstractBeanDefinition对象中
			parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);   //代码2
			//设置描述
			bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

			//对<Bean>元素的meta(元信息)属性解析
			parseMetaElements(ele, bd);
			//对<Bean>元素的lookup-method属性解析
			parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
			
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值