Spring系列之Alias标签的解析与使用

<?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);
    }

 

 

 

posted @ 2018-11-04 20:14  欲戴王冠.必承其重  阅读(4910)  评论(0编辑  收藏  举报