216°

Spring IOC 之解析Bean:解析 import 标签

  • 如果根节点或者子节点采用默认命名空间的话,则调用 parseDefaultElement() 进行默认标签解析
  • 否则调用 delegate.parseCustomElement() 方法进行自定义解析

默认标签解析过程,源码如下:

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)) {
			// recurse
			doRegisterBeanDefinitions(ele);
		}
	}
  • 分别是对四种不同的标签进行解析,分别是 import、alias、bean、beans

import 标签的处理

  •  Spring 提供了一个分模块的思路,利用 import 标签,例如我们可以构造一个这样的 spring.xml

  • Spring 利用 importBeanDefinitionResource() 方法完成对 import 标签的解析

解析 import 过程较为清晰,整个过程如下:

  1. 获取 source 属性的值,该值表示资源的路径
  2. 解析路径中的系统属性,如"${user.dir}"
  3. 判断资源路径 location 是绝对路径还是相对路径
  4. 如果是绝对路径,则调递归调用 Bean 的解析过程,进行另一次的解析
  5. 如果是相对路径,则先计算出绝对路径得到 Resource,然后进行解析
  6. 通知监听器,完成解析

判断绝对路径的规则如下:

  • 以 classpath*: 或者 classpath: 开头为绝对路径
  • 能够通过该 location 构建出 java.net.URL为绝对路径
  • 根据 location 构造 java.net.URI 判断调用 isAbsolute() 判断是否为绝对路径

如果 location 为绝对路径则调用 loadBeanDefinitions(),该方法在 AbstractBeanDefinitionReader 中定义

如果是相对路径则会根据相应的 Resource 计算出相应的绝对路径,

  • 然后根据该路径构造一个 Resource
  • 若该 Resource 存在,则调用 XmlBeanDefinitionReader.loadBeanDefinitions() 进行 BeanDefinition 加载
  • 否则构造一个绝对 location ,调用 AbstractBeanDefinitionReader.loadBeanDefinitions() 方法,与绝对路径过程一样

整个过程比较清晰明了:

  • 获取 source 属性值,得到正确的资源路径,然后调用 loadBeanDefinitions()方法进行递归的 BeanDefinition 加载

本文由【职业搬砖20年】发布于开源中国,原文链接:https://my.oschina.net/u/3847203/blog/2250586

全部评论: 0

    我有话说: