6.1-AliasRegistry

AliasRegistry

 1 //AliasRegistry
 2
 3
 4
 5 package org.springframework.core;
 6
 7 /**
 8  * Common interface for managing aliases. Serves as super-interface for
 9  * {@link org.springframework.beans.factory.support.BeanDefinitionRegistry}.
10  *
11  * @author Juergen Hoeller
12  * @since 2.5.2
13  */
14
15  /**
16
17         注册,移除,判断, 获取
18  **/
19
20
21 public interface AliasRegistry {
22
23     /**
24      * Given a name, register an alias for it.
25      * @param name the canonical name
26      * @param alias the alias to be registered
27      * @throws IllegalStateException if the alias is already in use
28      * and may not be overridden
29      */
30      //
31     void registerAlias(String name, String alias);
32
33     /**
34      * Remove the specified alias from this registry.
35      * @param alias the alias to remove
36      * @throws IllegalStateException if no such alias was found
37      */
38     void removeAlias(String alias);
39
40     /**
41      * Determine whether this given name is defines as an alias
42      * (as opposed to the name of an actually registered component).
43      * @param name the name to check
44      * @return whether the given name is an alias
45      */
46     boolean isAlias(String name);
47
48     /**
49      * Return the aliases for the given name, if defined.
50      * @param name the name to check for aliases
51      * @return the aliases, or an empty array if none
52      */
53     String[] getAliases(String name);
54
55 }

SimpleAliasRegistry

//SimpleAliasRegistry

package org.springframework.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.util.StringValueResolver;

/**
 * Simple implementation of the {@link AliasRegistry} interface.
 * Serves as base class for
 * {@link org.springframework.beans.factory.support.BeanDefinitionRegistry}
 * implementations.
 *
 * @author Juergen Hoeller
 * @since 2.5.2
 */

 /**
        实现了父接口中方法,并且增加了

 **/
public class SimpleAliasRegistry implements AliasRegistry {

//缓存别名和类名的地方
    /** Map from alias to canonical name */
    private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>(16);

    //注册的过程    检测-----》类名和别名是不是空的----->判断是否相等,,相等就移除--->否则使用别名获取实际名,存在---->直接结束
    @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);
        }
    }

    /**
     * Return whether alias overriding is allowed.
     * Default is {@code true}.
     */
    protected boolean allowAliasOverriding() {
        return true;
    }

    /**
     * Determine whether the given name has the given alias registered.
     * @param name the name to check
     * @param alias the alias to look for
     * @since 4.2.1
     */
    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;
    }

    @Override
    public void removeAlias(String alias) {
        String name = this.aliasMap.remove(alias);
        if (name == null) {
            throw new IllegalStateException("No alias ‘" + alias + "‘ registered");
        }
    }

    @Override
    public boolean isAlias(String name) {
        return this.aliasMap.containsKey(name);
    }

    @Override
    public String[] getAliases(String name) {
        List<String> result = new ArrayList<String>();
        synchronized (this.aliasMap) {
            retrieveAliases(name, result);
        }
        return StringUtils.toStringArray(result);
    }

    /**
     * Transitively retrieve all aliases for the given name.
     * @param name the target name to find aliases for
     * @param result the resulting aliases list
     */
    private void retrieveAliases(String name, List<String> result) {
        for (Map.Entry<String, String> entry : this.aliasMap.entrySet()) {
            String registeredName = entry.getValue();
            if (registeredName.equals(name)) {
                String alias = entry.getKey();
                result.add(alias);
                retrieveAliases(alias, result);
            }
        }
    }

    /**
     * Resolve all alias target names and aliases registered in this
     * factory, applying the given StringValueResolver to them.
     * <p>The value resolver may for example resolve placeholders
     * in target bean names and even in alias names.
     * @param valueResolver the StringValueResolver to apply
     */
     //批量检验别名
    public void resolveAliases(StringValueResolver valueResolver) {
        Assert.notNull(valueResolver, "StringValueResolver must not be null");
        synchronized (this.aliasMap) {
            Map<String, String> aliasCopy = new HashMap<String, String>(this.aliasMap);
            for (String alias : aliasCopy.keySet()) {
                String registeredName = aliasCopy.get(alias);
                String resolvedAlias = valueResolver.resolveStringValue(alias);
                String resolvedName = valueResolver.resolveStringValue(registeredName);
                if (resolvedAlias == null || resolvedName == null || resolvedAlias.equals(resolvedName)) {
                    this.aliasMap.remove(alias);
                }
                else if (!resolvedAlias.equals(alias)) {
                    String existingName = this.aliasMap.get(resolvedAlias);
                    if (existingName != null) {
                        if (existingName.equals(resolvedName)) {
                            // Pointing to existing alias - just remove placeholder
                            this.aliasMap.remove(alias);
                            break;
                        }
                        throw new IllegalStateException(
                                "Cannot register resolved alias ‘" + resolvedAlias + "‘ (original: ‘" + alias +
                                "‘) for name ‘" + resolvedName + "‘: It is already registered for name ‘" +
                                registeredName + "‘.");
                    }
                    checkForAliasCircle(resolvedName, resolvedAlias);
                    this.aliasMap.remove(alias);
                    this.aliasMap.put(resolvedAlias, resolvedName);
                }
                else if (!registeredName.equals(resolvedName)) {
                    this.aliasMap.put(alias, resolvedName);
                }
            }
        }
    }

    /**
     * Check whether the given name points back to the given alias as an alias
     * in the other direction already, catching a circular reference upfront
     * and throwing a corresponding IllegalStateException.
     * @param name the candidate name
     * @param alias the candidate alias
     * @see #registerAlias
     * @see #hasAlias
     */
     //检查别名是否存在
    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");
        }
    }

    /**
     * Determine the raw name, resolving aliases to canonical names.
     * @param name the user-specified name
     * @return the transformed name
     */
     //查找别名对呀的原始类名
    public String canonicalName(String name) {
        String canonicalName = name;
        // Handle aliasing...
        String resolvedName;
        do {
            resolvedName = this.aliasMap.get(canonicalName);
            if (resolvedName != null) {
                canonicalName = resolvedName;
            }
        }
        while (resolvedName != null);
        return canonicalName;
    }

}

实现类:

registerAlias(String name, String alias)  -----注册别名的方法,其实这个注册完的别名是放在了一个Map中

注册的过程:这个图是我从别的地方看到的,没画,其实可以看代码,很明了
方法:public String[] getAliases(String name) 

这个方法是获取别名的,其中使用了递归调用,使用了同步锁,
@Override
    public String[] getAliases(String name) {
        List<String> result = new ArrayList<String>();
        synchronized (this.aliasMap) {
            retrieveAliases(name, result);
        }
        return StringUtils.toStringArray(result);
    }

递归部分:

    private void retrieveAliases(String name, List<String> result) {
        for (Map.Entry<String, String> entry : this.aliasMap.entrySet()) {
            String registeredName = entry.getValue();
            if (registeredName.equals(name)) {
                String alias = entry.getKey();
                result.add(alias);
                retrieveAliases(alias, result);
            }
        }
    }

 
时间: 2024-09-29 02:17:39

6.1-AliasRegistry的相关文章

BeanDefinitionRegistry extends AliasRegistry

// 用该Registry注册一个新定义的bean,但是新的bean必须支持父的定义和子的定义void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException; // 给一个beanName移除掉BeanDefinitionvoid removeBeanDefinition(String beanName) throws NoSuchBean

SimpleAliasRegistry implements AliasRegistry

Spring - 4.2.3 // name,alias存储容器 ConcurrentHashMap <alias,name>private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>(16); // 注册alias别名public void registerAlias(String name, String alias)1. 检查 name,alias 是否含有内

Spring 源代码学习(一)

一 .Spring容器最基本的功能 1. 读取配置文件 2. 校验配置文件的正确性 3. 将配置文件信息加载到内存 4. 通过反射实例化bean对象 5. 构建系统  二 .核心类关系图 图1-1 DefaultListableBeanFactory类图 图1-2 XmlBeanDefinitionReader类图 三 .核心类介绍 1. DefaultListableBeanFactory   从上面类图可以看出来"主要"实现了 (1)AliasRegistry (2)Singlet

spring源码阅读(2)核心类介绍

AliasRegistry:定义对alias的简单增删改操作 SimpleAliasRegistry:主要使用map作为alias的缓存,并对接口AliasRegistry进行实现. SingletonBeanRegistry:定于对单例的注册及获取. BeanFactory:定义获取bean及bean的各种属性. DefaultSingletonBeanRegistry:对接口SingletonBeanRegistry各函数的实现. HierarchialBeanFactory:继承BeanF

深入剖析 Spring 框架的 BeanFactory

说到Spring框架,人们往往大谈特谈一些似乎高逼格的东西,比如依赖注入,控制反转,面向切面等等.但是却忘记了最基本的一点,Spring的本质是一个bean工厂(beanFactory)或者说bean容器,它按照我们的要求,生产我们需要的各个各样的bean,提供给我们使用.只是在生产bean的过程中,需要解决bean之间的依赖问题,才引入了依赖注入(DI)这种技术.也就是说依赖注入是beanFactory生产bean时为了解决bean之间的依赖的一种技术而已. 那么我们为什么需要Spring框架

Spring源码分析——BeanFactory体系之接口详细分析

Spring的BeanFactory的继承体系堪称经典.这是众所周知的!作为Java程序员,不能错过! 前面的博文分析了Spring的Resource资源类Resouce.今天开始分析Spring的IOC部分.众所周知,IOC是Spring框架最迷人的地方.它最重要的接口,就是BeanFactory了.BeanFactory有着庞大的继承.实现体系,有众多的子接口.实现类.本博文的目标就是抽丝剥茧,从源代码入手,分析Spring的实现和架构,从中进步. 在阅读的过程中,可以参照Spring文档来

Spring源码分析——BeanFactory体系之抽象类、类分析(一)

上一篇介绍了BeanFactory体系的所有接口——Spring源码分析——BeanFactory体系之接口详细分析,本篇就接着介绍BeanFactory体系的抽象类和接口. 一.BeanFactory的基本类体系结构(类为主): 上图可与 Spring源码分析——BeanFactory体系之接口详细分析 的图结合分析,一个以接口为主,一个以类为主(PS:Spring的体系结构要分析清楚,不得不曲线救国啊!不然27寸屏幕给我画估计都装不下.). 具体: 1.7层的类体系继承. 2.Abstrac

Spring源码之SimpleAliasRegistry解读(一)

Spring源码之SimpleAliasRegistry解读(一) 阅读spring源码中org.springframework.core.SimpleAliasRegistry类时发现该类主要是使用map作为alias的缓存,并对接口AliasRegistry进行实现. 在阅读该源码中对hasAlias(String name, String alias):方法产生了疑惑.源码注释中解释该方法的作用是:确定给定的名称是否已注册了给定的别名. 该方法源码如下: public boolean ha

Spring源码解读之XmlBeanFactory

首先感谢<Spring源码深度解析>郝佳.接下来的Spring源码解读系列,都是读了郝佳的书后的观后感.再次感谢他,带我走进了源码的世界. BeanFactory factory= new XmlBeanFactory (new ClassPathResource("D:\\Project\\Eclipse\\Spring_Maven\\src\\main\\resources\\spring_beans.xml" )); new ClassPathResource(Str