AliasRegistry接口定义了alias的基本操作。

package org.springframework.core;
public interface AliasRegistry { //对指定的名称注册别名
void registerAlias(String name, String alias); //从当前容器移除指定别名
void removeAlias(String alias); //判断指定名称是否为别名
boolean isAlias(String beanName); //返回指定名称的所有别名
String[] getAliases(String name); }

SimpleAliasRegistry

SimpleAliasRegistry类对AliasRegistry进行了实现,其中使用了Map对alias进行缓存。

public class SimpleAliasRegistry implements AliasRegistry {

    /** Map from alias to canonical name,使用ConcurrentHashMap缓存别名与名称的映射关系key= 别名,value=beanName */
private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>(16);

registerAlias():

  为指定名称注册别名,有以下几步:

1、校验输入参数。

2、不允许别名与指定名称一致,且移除已注册列表中该别名(不管已注册列表中是否存在该别名)。

3、如别名已注册则不再重复注册,根据是否允许覆盖条件判断是否抛出异常。

4、递归检查指定名称与别名是否存在环形指向关联关系。

5、注册别名。

@Override
public void registerAlias(String name, String alias) {
Assert.hasText(name, "'name' must not be empty");
Assert.hasText(alias, "'alias' must not be empty");
//如果名称和别名相同,则移除别名
if (alias.equals(name)) {
this.aliasMap.remove(alias);
}
else {
String registeredName = this.aliasMap.get(alias);
if (registeredName != null) {
//如果别名已经存在,那么不用再注册,直接返回
if (registeredName.equals(name)) {
// An existing alias - no need to re-register
return;
}
//如果别名不允许被覆盖则抛异常,
if (!allowAliasOverriding()) {
throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" +
name + "': It is already registered for name '" + registeredName + "'.");
}
}
//递归检查别名
checkForAliasCircle(name, alias);
//注册别名
this.aliasMap.put(alias, name);
}
}
注册别名

因为SimpleAliasRegistry根据名称获取别名列表时,会将直接、间接关系的别名均列出来,所以注册别名时不允许名称与别名见存在环形指向关联关系。

    //检查给定的名称是否已经指向给定的别名作为另一个方向的别名,在前面捕获一个循环引用并引发相应的IllegalstateException。
protected void checkForAliasCircle(String name, String alias) {
if (hasAlias(alias, name)) {
throw new IllegalStateException("Cannot register alias '" + alias +
"' for name '" + name + "': Circular reference - '" +
name + "' is a direct or indirect alias for '" + alias + "' already");
}
} //遍历+递归
public boolean hasAlias(String name, String alias) {
for (Map.Entry<String, String> entry : this.aliasMap.entrySet()) {
String registeredName = entry.getValue();
if (registeredName.equals(name)) {
String registeredAlias = entry.getKey();
return (registeredAlias.equals(alias) || hasAlias(registeredAlias, alias));
}
}
return false;
}
递归检查别名关联关系

检查name是否直接或间接关联alias

移除别名、检查指定名称是被定义为别名。

根据指定名称获取所有别名,递归检索,其中包含直接指向的别名与间接指向的别名。

根据指定名称获取别名列表

转:https://www.jianshu.com/p/45c36ff80770

Spring之28:AliasRegistry&SimpleAliasRegistry的更多相关文章

  1. Spring源码之SimpleAliasRegistry解读(一)

    Spring源码之SimpleAliasRegistry解读(一) 阅读spring源码中org.springframework.core.SimpleAliasRegistry类时发现该类主要是使用 ...

  2. 【Spring】28、Spring中基于Java的配置@Configuration和@Bean用法.代替xml配置文件

    Spring中为了减少xml中配置,可以生命一个配置类(例如SpringConfig)来对bean进行配置. 一.首先,需要xml中进行少量的配置来启动Java配置: <?xml version ...

  3. Spring Boot (28) actuator与spring-boot-admin

    在上一篇中,通过restful api的方式查看信息过于繁琐,也不直观,效率低下.当服务过多的时候看起来就过于麻烦,每个服务都需要调用不同的接口来查看监控信息. SBA SBA全称spring boo ...

  4. Spring系列28:@Transactional事务源码分析

    本文内容 @Transactional事务使用 @EnableTransactionManagement 详解 @Transactional事务属性的解析 TransactionInterceptor ...

  5. Spring IoC容器与应用上下文的设计与实现

    一.前言 写这篇博文的主要目的如下: 通过相关类和接口分析IoC容器到底长什么样. 阐述笔者对Spring上下文和容器的理解. 介绍重要的类辅助理解SpringBoot的启动流程. 二.Spring ...

  6. SimpleAliasRegistry

    SimpleAliasRegistry :主要使用map最为alias的缓存,并对接口AliasRegister进行实现. ==============================插曲====== ...

  7. 从Spring中学到的【1】--读懂继承链

    最近看了一些 Spring 源码,发现源码分析的文章很多,而底层思想分析的文章比较少,这个系列文章准备总结一下Spring中给我的启示,包括设计模式思想.SOLID设计原则等,涉及一些编程的基本原则, ...

  8. 【Spring】6、注解大全

    一.@interface Java用  @interface Annotation{ } 定义一个注解 @Annotation,一个注解是一个类. 二.@Override,@Deprecated,@S ...

  9. Spring框架文档与API(4.3.6版本)

    http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/ Table of Contents I ...

随机推荐

  1. 我为什么选择Vim

    总看到一些飞快敲击键盘而不用鼠标的时候你可以很羡慕和佩服,其实这完全没有必要.就像一个吉他手熟练地弹吉他有必要羡慕吗?一个瓦匠熟练地砌砖有必要羡慕吗?这些都是他们赖以生存的工具而已,熟练地运用工具是理 ...

  2. 小福bbs-冲刺日志(第三天)

    [小福bbs-冲刺日志(第三天)] 这个作业属于哪个课程 班级链接 这个作业要求在哪里 作业要求的链接 团队名称 小福bbs 这个作业的目标 前端交付部分页面给后端 ,后端开始完成部分功能 作业的正文 ...

  3. C字符贪吃蛇

    算法参照Perl字符贪吃蛇,源码: #include <stdio.h> #include <windows.h> #define WIDTH 12 // 宽 #define ...

  4. NGINX实现咏南跨平台中间件集群

    NGINX实现咏南跨平台中间件集群 首先要开启咏南LINUX中间件. 1)编辑usr/local/nginx/conf/nginx.conf #user  nobody;worker_processe ...

  5. DELPHI开发LINUX包

    DELPHI开发LINUX包 我们知道,有了包的存在,开发插件架构的程序,才成为可能 . DELPHI在WINDOWS里面的包的扩展名是.bpl. 在LINUX里面的包的扩展名是.so. 怎样在LIN ...

  6. Check if List<Int32> values are consecutive

    Check if List<Int32> values are consecutive One-liner, only iterates until the first non-conse ...

  7. Java_jdbc 基础笔记之一 数据库连接

    方式一: 1.创建一个Driver实现类的对象 2.准备连接数据库的基本信息:url,user,password 3.调用Driver接口的connect(url,info)获取数据库连接 * Dri ...

  8. gogs 实现webhook钩子(php接口形式)

    1.概要流程 2.准备工作 gogs服务器 linux网站服务器(宝塔) 本地客户端 3.编写钩子访问的接口 在public下新建githook.php文件,代码如下: <?php $cmd = ...

  9. Comparison and difference for Default geodatabase,Current workspace,Scratch workspace,Home Folder

    Comparison and difference for Default geodatabase,Current workspace,Scratch workspace,Home Folder 商务 ...

  10. Quartz Configuration Reference

    Quartz Configuration Reference Choose a topic: Main Configuration (configuration of primary schedule ...