Spring IOC BeanDefinitions加载(二)

#博学谷IT学习技术支持#


我们继续上一章节的BeanDefinitions加载

parseBeanDefinitions

上一章看到了parseBeanDefinitions方法,现在来具体看下方法的内部逻辑

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
		//如果根节点是默认的命名空间
		if (delegate.isDefaultNamespace(root)) {
			//获取子节点
			NodeList nl = root.getChildNodes();
			// 遍历子节点
			for (int i = 0; i < nl.getLength(); i++) {
				Node node = nl.item(i);
				if (node instanceof Element) {
					Element ele = (Element) node;
					//如果子节点是也是默认的命名空间
					if (delegate.isDefaultNamespace(ele)) {
						//执行默认的元素解析
						parseDefaultElement(ele, delegate);
					}
					else {
						//执行自定义的元素解析操作
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else { //如果根节点不是默认的命名空间,则直接执行自定义的元素解析
			delegate.parseCustomElement(root);
		}
	}

看完这个方法,大家已经看出来。这里的元素解析,主要就分为了两种:
1.默认的命名空间解析
2.自定义的命名空间解析

默认命名空间解析(parseDefaultElement)

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		//解析import标签
		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
			importBeanDefinitionResource(ele);
		}
		//解析alias标签
		else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
			processAliasRegistration(ele);
		}
		//解析bean标签
		else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
			processBeanDefinition(ele, delegate);
		}
		//解析嵌套的beans标签
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			doRegisterBeanDefinitions(ele);
		}
	}

因为解析操作都很相似,beans标签的解析其实就是一个递归的过程。所以我们主要看下bean标签的解析。

bean标签解析

processBeanDefinition

贴下代码,只保留下现在需要的核心逻辑

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		// 将具体的bean解析操作交给BeanDefinitionParserDelegate进行
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			// 对解析后的beanDefinition做一些,其实解释解析一下bean标签内部的一些自定义属性
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
		}
	}
parseBeanDefinitionElement解析默认标签
	BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
	跟进上述方法到parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean)方法内部
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
		// 解析bean标签的id属性
		String id = ele.getAttribute(ID_ATTRIBUTE);
		// 解析bean标签的name属性
		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
		// 定义别名列表
		List<String> aliases = new ArrayList<>();
		// 分割name属性,获取到name属性数组
		if (StringUtils.hasLength(nameAttr)) {
			String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
			// 将获取到的name数组添加到别名列表中
			aliases.addAll(Arrays.asList(nameArr));
		}

		// 设置beanName为id,这里的beanName,就是我们在使用getBean(String name)的时候,传入的那个name
		String beanName = id;
		// 或如beanName为空并且别名列表不为空时
		if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
			// 从别名列表中取第一个
			beanName = aliases.remove(0);
		}

		if (containingBean == null) {
			// 校验name,和别名是否唯一,并将beanName,和aliaes添加到this.usedNames属性中
			checkNameUniqueness(beanName, aliases, ele);
		}
		// 执行beanDefinition的解析操作
		AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
		if (beanDefinition != null) {
			// 如果beanDefinition不为null并且beanName为空时,会自动生成一个beanName
			if (!StringUtils.hasText(beanName)) {
				try {
					//暂时不看
					if (containingBean != null) {
						beanName = BeanDefinitionReaderUtils.generateBeanName(
								beanDefinition, this.readerContext.getRegistry(), true);
					}
					else {
					    // 内部使用beanNameGenerator获取初始化一个beanName
						beanName = this.readerContext.generateBeanName(beanDefinition);
						// 获取beanClassName
						String beanClassName = beanDefinition.getBeanClassName();
						// 判断是否需要将beanClassName添加到名别列表中
						if (beanClassName != null &&
								beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
								!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
							aliases.add(beanClassName);
						}
					}
				}
				catch (Exception ex) {
					error(ex.getMessage(), ele);
					return null;
				}
			}
			String[] aliasesArray = StringUtils.toStringArray(aliases);
			// 返回一个BeanDefinitionHolder对象
			return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
		}
		return null;
	}

跟进parseBeanDefinitionElement(ele, beanName, containingBean)方法

public AbstractBeanDefinition parseBeanDefinitionElement(
			Element ele, String beanName, @Nullable BeanDefinition containingBean) {
		// 标记解析状态
		this.parseState.push(new BeanEntry(beanName));

		String className = null;
		//获取class属性值
		if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
			className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
		}
		String parent = null;
		//获取parent属性值
		if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
			parent = ele.getAttribute(PARENT_ATTRIBUTE);
		}

		try {
			// 创建一个GenericBeanDefinition类型的对象,使用AbstractBeanDefinition来接收
			AbstractBeanDefinition bd = createBeanDefinition(className, parent);
			//解析bean标签的属性,存放到bd中
			parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
			// 解析description子标签
			bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
			
			//解析meta子标签
			parseMetaElements(ele, bd);
			// 解析lookup-method子标签
			parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
			// 解析replaced-method子标签
			parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
			// 解析constructor-arg子标签
			parseConstructorArgElements(ele, bd);
			// 解析property子标签
			parsePropertyElements(ele, bd);
			// 解析qualifier子标签
			parseQualifierElements(ele, bd);

			bd.setResource(this.readerContext.getResource());
			bd.setSource(extractSource(ele));

			return bd;
		} finally {
			this.parseState.pop();
		}

		return null;
	}

decorateBeanDefinitionIfRequired 解析自定义标签

public BeanDefinitionHolder decorateBeanDefinitionIfRequired(
			Element ele, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {

		BeanDefinitionHolder finalDefinition = originalDef;

		// 解析自定义的属性
		NamedNodeMap attributes = ele.getAttributes();
		for (int i = 0; i < attributes.getLength(); i++) {
			Node node = attributes.item(i);
			finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
		}
		//解析自定义的子标签
		NodeList children = ele.getChildNodes();
		for (int i = 0; i < children.getLength(); i++) {
			Node node = children.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
			}
		}
		return finalDefinition;
	}

解析自定义属性和自定义标签,调用的是相同的方法 decorateIfRequired(node, finalDefinition, containingBd)

decorateIfRequired
public BeanDefinitionHolder decorateIfRequired(
			Node node, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {
		//获取命名空间
		String namespaceUri = getNamespaceURI(node);
		//如果不是默认的命名空间,说明是自定义的,执行自定义逻辑
		if (namespaceUri != null && !isDefaultNamespace(namespaceUri)) {
		//首先根据自定义的命名空间,找到对应的命名空进处理器
			NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
			if (handler != null) {
				//如果处理器不为空,执行解析操作
				BeanDefinitionHolder decorated =
						handler.decorate(node, originalDef, new ParserContext(this.readerContext, this, containingBd));
				if (decorated != null) {
					return decorated;
				}
			}
			else if (namespaceUri.startsWith("http://www.springframework.org/schema/")) {
				error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", node);
			}
			else {
				// A custom namespace, not to be handled by Spring - maybe "xml:...".
				if (logger.isDebugEnabled()) {
					logger.debug("No Spring NamespaceHandler found for XML schema namespace [" + namespaceUri + "]");
				}
			}
		}
		return originalDef;
	}

registerBeanDefinition 注册beanDefinition

public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		//获取beanName,使用beanName注册BeanDefinition到beanFactory的beanDefinitionMap属性中
		String beanName = definitionHolder.getBeanName();
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// 将别名注册到beanFactory的aliasMap中
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}

这样,一个BeanDefinition的解析注册操作就完成了!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值