<?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()方法:spring
/** * 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()方法:app
@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); }