5Spring 源码学习 ~ 默认标签 alias 标签的解析与注册

Posted 戴泽supp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5Spring 源码学习 ~ 默认标签 alias 标签的解析与注册相关的知识,希望对你有一定的参考价值。

alias 标签的解析

一、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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="testBean" class="com.luo.spring.guides.helloworld.common.TestBean"/>
    <alias name="testBean" alias="testBean,testBean2"/>
</beans>

使用场景说明:

组件 A 在 XML 配置文件中定义了一个名为 componentA 的 DataSource 类型的 bean,但组件 B 却想在其 XML 配置文件中以 componentB 来命名,最终容器加载 2 个 XML 文件来生成最终的 ApplicationContext。配置文件定义如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="componentA" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mengxi_blog?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=UTC"/>
        <property name="user" value="root"/>
        <property name="password" value="123456"/>
    </bean>

    <alias name="componentA" alias="componentB"/>
</beans>

二、alias 标签的解析与注册

源码入口:

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) 
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) 
        importBeanDefinitionResource(ele);
    
    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) 
        processAliasRegistration(ele);
    
    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) 
        processBeanDefinition(ele, delegate);
    
    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) 
        // recurse
        doRegisterBeanDefinitions(ele);
    

processAliasRegistration 函数的具体实现:

protected void processAliasRegistration(Element ele) 
    //获取 beanName
    String name = ele.getAttribute(NAME_ATTRIBUTE);
    //获取 alias
    String alias = ele.getAttribute(ALIAS_ATTRIBUTE);
    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 
            // 注册 alias
            getReaderContext().getRegistry().registerAlias(name, alias);
        
        catch (Exception ex) 
            getReaderContext().error("Failed to register alias '" + alias +
                                     "' for bean with name '" + name + "'", ele, ex);
        
        //别名注册后通知监听器做相应处理
        getReaderContext().fireAliasRegistered(name, alias, extractSource(ele));
    

可以看出跟之前 bean 标签的解析大同小异,最终是将别名与 beanName 组成一队注册至 registry(具体实现在 SimpleAliasRegistry 中) 当中。SimpleAliasRegistry 实现如下:

@Override
public void registerAlias(String name, String alias) 
    Assert.hasText(name, "'name' must not be empty");
    Assert.hasText(alias, "'alias' must not be empty");
    synchronized (this.aliasMap) 
        if (alias.equals(name)) 
            this.aliasMap.remove(alias);
            if (logger.isDebugEnabled()) 
                logger.debug("Alias definition '" + alias + "' ignored since it points to same name");
            
        
        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 define alias '" + alias + "' for name '" +
                                                    name + "': It is already registered for name '" + registeredName + "'.");
                
                if (logger.isDebugEnabled()) 
                    logger.debug("Overriding alias '" + alias + "' definition for registered name '" +
                                 registeredName + "' with new target name '" + name + "'");
                
            
            checkForAliasCircle(name, alias);
            this.aliasMap.put(alias, name);
            if (logger.isTraceEnabled()) 
                logger.trace("Alias definition '" + alias + "' registered for name '" + name + "'");
            
        
    

至此, alias 标签解析完成。

以上是关于5Spring 源码学习 ~ 默认标签 alias 标签的解析与注册的主要内容,如果未能解决你的问题,请参考以下文章

8Spring 源码学习 ~ 自定义标签的解析

3Spring 源码学习 ~ 默认标签的解析之 Bean 标签解析

Spring源码深度解析学习系列默认标签解析

4Spring 源码学习 ~ 默认标签的解析之 Bean 标签注册

7Spring 源码学习 ~ 默认标签的解析之嵌入式 beans 标签的解析

7Spring 源码学习 ~ 默认标签的解析之嵌入式 beans 标签的解析