本文要看啥

之前我们看解析默认标签,从最核心的bean开始看的

1
2
3
4
5
6
7
8
9
10
11
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, "import")) {
this.importBeanDefinitionResource(ele);
} else if (delegate.nodeNameEquals(ele, "alias")) {
this.processAliasRegistration(ele);
} else if (delegate.nodeNameEquals(ele, "bean")) {
this.processBeanDefinition(ele, delegate);
} else if (delegate.nodeNameEquals(ele, "beans")) {
this.doRegisterBeanDefinitions(ele);
}
}

现在主要就剩下alias和import啦, beans其实就是迭代解析.

alias标签的解析

为bean定义别名,除了之前我们接触过的

1
<bean id="testBean" name="aliasTestBean" class="com.test"/>

还可以直接用alias标签

1
<alias name="testBean" alias="aliasTestBean"/>

解析步骤即使不看源码也知道很简单,因为之前我们已经深入研究过了SimpleAliasRegistry

  1. 校验 name alias 两个属性不能为空
  2. this.getReaderContext().getRegistry().registerAlias(name, alias);

这个getRegistry() 然后registerAlias() 果然就是我们之前学过的SimpleAliasRegistry 里面的注册别名的方法.

impory标签的解析

import标签和bean标签一样是我们最常见的标签,对于分模块管理配置文件很关键.

解析步骤

  1. 取出并校验resource 属性作为地址location

  2. 将地址中的系统属性 如 “${user.dir}”

  3. 判断location是绝对路径还是相对路径

    1. 如果是,则

      1
      importCount = this.getReaderContext().getReader().loadBeanDefinitions(location, actualResources);
    2. 否则

1
2
3
4
5
6
7
8
Resource relativeResource = this.getReaderContext().getResource().createRelative(location);
if (relativeResource.exists()) {
importCount = this.getReaderContext().getReader().loadBeanDefinitions(relativeResource);
actualResources.add(relativeResource);
} else {
String baseLocation = this.getReaderContext().getResource().getURL().toString();
importCount = this.getReaderContext().getReader().loadBeanDefinitions(StringUtils.applyRelativePath(baseLocation, location), actualResources);
}
  1. 还是预留给拓展监听事件的位置.

关键步骤

判断是否绝对路径
1
absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();

isUrl : 以 classpath*: 开头 或者 classpath: 开头 或者 可以new URL(resourceLocation); 而不报错

ResourceUtils.toURI(location): 替换路径中空格为%20 后 new URI ,然后拿absolute属性

加载bean

其实最后都是调用在第一篇博文中我们就看过的 loadBeanDefinitions 方法