<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <alias name="resourceHolder" alias="resourceHolder1"/>
<alias name="resourceHolder" alias="resourceHolder2"/>
<alias name="resourceHolder" alias="resourceHolder3"/>
<bean id="resourceHolder" class="com.zk.demo1025.ResourceHolder">
<property name="resource" value="classpath:com/zk/demo1025/applicationContext.xml"></property>
</bean>
</beans>

DefaultBeanDefinitionDocumentReader类中的processAliasRegistration()方法:

    /**
* Process the given alias element, registering the alias with the registry.
   * 处理alias元素,并且注册到注册器中
*/
protected void processAliasRegistration(Element ele) {
String name = ele.getAttribute(NAME_ATTRIBUTE);得到name值
String alias = ele.getAttribute(ALIAS_ATTRIBUTE);得到 alias值
boolean valid = true;
if (!StringUtils.hasText(name)) {
getReaderContext().error("Name must not be empty", ele);
valid = false;
}
if (!StringUtils.hasText(alias)) {
getReaderContext().error("Alias must not be empty", ele);
valid = false;
}
if (valid) {
try {
getReaderContext().getRegistry().registerAlias(name, alias);//这里实际执行的是SimpleAliasRegistry中的registerAlias()方法
}
catch (Exception ex) {
getReaderContext().error("Failed to register alias '" + alias +
"' for bean with name '" + name + "'", ele, ex);
}
getReaderContext().fireAliasRegistered(name, alias, extractSource(ele));
}
}
SimpleAliasRegistry中的registerAlias()方法:最终放入HashMap中。
    private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);

    @Override
public void registerAlias(String name, String alias) {synchronized (this.aliasMap) {
if (alias.equals(name)) {
this.aliasMap.remove(alias); 如果别名与名字相同,则在Map中移除
}
else {
String registeredName = this.aliasMap.get(alias);
if (registeredName != null) {
if (registeredName.equals(name)) { 如果相同,则无动于衷
return;
}
}
checkForAliasCircle(name, alias);检查别名回环
this.aliasMap.put(alias, name);放入Map中,key是alias,value是name
}
}
}

接下来是取值:AbstractBeanFactory接口的getAlias()方法:

    @Override
public String[] getAliases(String name) {
String beanName = transformedBeanName(name);转换名字,这个方法与FactoryBean前缀,别名转换为真名有关
List<String> aliases = new ArrayList<>();
boolean factoryPrefix = name.startsWith(FACTORY_BEAN_PREFIX);是否是FactoryBean
String fullBeanName = beanName;
if (factoryPrefix) {
fullBeanName = FACTORY_BEAN_PREFIX + beanName;
}
if (!fullBeanName.equals(name)) {
aliases.add(fullBeanName);
}
String[] retrievedAliases = super.getAliases(beanName);去父类中aliasMap取值
for (String retrievedAlias : retrievedAliases) {
String alias = (factoryPrefix ? FACTORY_BEAN_PREFIX : "") + retrievedAlias;
if (!alias.equals(name)) {
aliases.add(alias);
}
}
if (!containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null) {
aliases.addAll(Arrays.asList(parentBeanFactory.getAliases(fullBeanName)));
}
}
return StringUtils.toStringArray(aliases);
}
 

Spring系列之Alias标签的解析与使用的更多相关文章

  1. 深入理解Spring系列之二:BeanDefinition解析

    转载 https://mp.weixin.qq.com/s?__biz=MzI0NjUxNTY5Nw==&mid=2247483814&idx=1&sn=ddf49931d55 ...

  2. spring xml 配置文件中标签的解析

    一个springmvc配置文件的例子为: <?xml version="1.0" encoding="UTF-8"?> <beans xmln ...

  3. 【Spring源码深度解析学习系列】复杂标签属性解析(四)

    一.创建用于属性承载的BeanDefinition BeanDefiniton是一个接口,在Spring中存在三种实现:RootBeanDefinition.ChildBeanDefinition.G ...

  4. Spring 系列教程之默认标签的解析

    Spring 系列教程之默认标签的解析 之前提到过 Spring 中的标签包括默认标签和自定义标签两种,而两种标签的用法以及解析方式存在着很大的不同,本章节重点带领读者详细分析默认标签的解析过程. 默 ...

  5. Spring 系列教程之自定义标签的解析

    Spring 系列教程之自定义标签的解析 在之前的章节中,我们提到了在 Spring 中存在默认标签与自定义标签两种,而在上一章节中我们分析了 Spring 中对默认标签的解析过程,相信大家一定已经有 ...

  6. spring源码学习之默认标签的解析(二)

    这个是接着上一篇来写,主要是这章内容比较多,还是分开来写吧! 一.AbstractBeanDefinition属性介绍 XML中的所有的属性都可以在GenericBeanDefinition中找到对应 ...

  7. 【Spring源码深度解析学习系列】默认标签解析(三)

    Spring的标签包括默认标签和自定义标签两种 默认标签的解析方法: ###DefaultBeanDefinitionDocumentReader.java### private void parse ...

  8. 【spring源码系列】之【xml解析】

    1. 读源码的方法 java程序员都知道读源码的重要性,尤其是spring的源码,代码设计不仅优雅,而且功能越来越强大,几乎可以与很多开源框架整合,让应用更易于专注业务领域开发.但是能把spring的 ...

  9. Spring源码学习-容器BeanFactory(四) BeanDefinition的创建-自定义标签的解析.md

    写在前面 上文Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签对Spring默认标签的解析做了详解,在xml元素的解析中,Spri ...

随机推荐

  1. “全栈2019”Java第八十二章:嵌套接口能否访问外部类中的成员?

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  2. Java面向对象之异常(自定义异常)

    一.基础概念 在自定义的程序中,如果有了问题.也可以像java中的异常一样,对问题进行描述. 注意:1.继承RuntimeException的异常,不需要进行处理.在执行过程中有异常会直接抛出. 2. ...

  3. Oracle中对多行查询结果进行拼接

    to_char(wmsys.wm_concat(to_char( st.col_name))) as new_name to_char: 将当前值转换成字符串类型; wmsys.wm_concat:拼 ...

  4. js实现抛物线

    这个是很简单的一种方式,利用了css3的transition属性 <!DOCTYPE html> <html lang="en" style="widt ...

  5. c++11 enable_shared_from_this

    本质的原因:raw data和引用计数的管理块,可能是分开的 使用场景: 需要在对象中得到shared ptr,  错误的代码:直接构造新的shared_ptr<A>对象,两个shared ...

  6. vue关闭令人抓狂的ESlint 语法检测配置方法

    随便改个vue 一堆报错 其实我并不反对这些语法检测,但是像许多反个人意愿的那就真的不得不吐槽了,比如vue-cli脚手架创建的默认eslint规则: 代码末尾不能加分号 ; 代码中不能存在多行空行 ...

  7. Pycharm快捷键配置

    1.主题 毫无疑问Pycharm是一个具有强大快捷键系统的IDE,这就意味着你在Pycharm中的任何操作,例如打开一个文件.切换编辑区域等,都可以通过快捷键来实现.使用快捷键不仅能提高操作速度,看起 ...

  8. Pycharm与github的秘密

    GIT介绍 GIT文章请看老男孩教育-银角大王的博客: http://www.cnblogs.com/wupeiqi/articles/7295372.html Git 是一个开源的分布式版本控制软件 ...

  9. 命令提示符下的WQL

    WQL就是英文WMI Query Language的缩写,就是说wmic这个命令支持简单的一些SQL查询,我们以实例来讲解他的部分用法,这个命令过于强大,因此以下只是该命令的冰山一角. 列出本地连接的 ...

  10. squid的简单介绍

    squid的简单介绍 squid的概念 squid是一种用来缓存Internet数据的软件.接受来自人们需要下载的目标(object)的请求并适当的处理这些请求.也就是说,如果一个人想下载一web界面 ...