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); }
作者:欲戴王冠.必承其重
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。