杀死Spring - BeanFactory系列中的bean别名alias机制
Spring主要是通过SimpleAliasRegistry来完成别名功能的,它的类图继承关系如下:
那么它是怎么完成的呢?
一:域
/*存储别名
*若jdk >=1.5,返回java.util.concurrent.ConcurrentHashMap,否则
*加载并返回edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap,否则
*返回SynchronizedMap
*/
private final Map aliasMap = CollectionFactory.createConcurrentMapIfPossible(16);
二:方法
2.1:registerAlias
//注册别名
public void registerAlias(String name, String alias) {
Assert.hasText(name, "'name' must not be empty");
Assert.hasText(alias, "'alias' must not be empty");
//若别名和bean名一样则删除
if (alias.equals(name)) {
this.aliasMap.remove(alias);
}
//否则加入 别名 —> bean名
else {
if (!this.allowAliasOverriding()) {
String registeredName = (String)this.aliasMap.get(alias);
if (registeredName != null && !registeredName.equals(name)) {
throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" + name + "': It is already registered for name '" + registeredName + "'.");
}
}
this.aliasMap.put(alias, name);
}
}
protected boolean allowAliasOverriding() { return true; }
2.2:getAliases
//
public String[] getAliases(String name) {
List aliases = new ArrayList();
//获取aliasMap的锁
synchronized(this.aliasMap) {
Iterator it = this.aliasMap.entrySet().iterator();
//遍历aliasMap,若bean名(value)跟name相等则将别名(key)加入aliases
while(it.hasNext()) {
Entry entry = (Entry)it.next();
String registeredName = (String)entry.getValue();
if (registeredName.equals(name)) {
aliases.add(entry.getKey());
}
}
//返回aliases的数组形式
return StringUtils.toStringArray(aliases);
}
}
2.3:isAlias
//aliasMap中key值集合是否有name
public boolean isAlias(String name) { return this.aliasMap.containsKey(name); }
2.4:canonicalName
//简单名字canonical:最简单,经典的,规范的
public String canonicalName(String name) {
String canonicalName = name;
String resolvedName = null;
//我怎么感觉下面这个循环有毛病啊,要是aliasMap中存了 a->b,b->a那不死循环了
do {
resolvedName = (String)this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
} while(resolvedName != null);
return canonicalName;
}
2.5:resolveAliases
//
public void resolveAliases(StringValueResolver valueResolver) {
Assert.notNull(valueResolver, "StringValueResolver must not be null");
//获取aliasMap的锁
synchronized(this.aliasMap) {
Map aliasCopy = new HashMap(this.aliasMap);
Iterator it = aliasCopy.keySet().iterator();
while(it.hasNext()) {
String alias = (String)it.next();
String registeredName = (String)aliasCopy.get(alias);
String resolvedAlias = valueResolver.resolveStringValue(alias);
String resolvedName = valueResolver.resolveStringValue(registeredName);
if (!resolvedAlias.equals(alias)) {
String existingName = (String)this.aliasMap.get(resolvedAlias);
if (existingName != null && !existingName.equals(resolvedName)) {
throw new IllegalStateException("Cannot register resolved alias '" + resolvedAlias + "' (original: '" + alias + "') for name '" + resolvedName + "': It is already registered for name '" + registeredName + "'.");
}
this.aliasMap.put(resolvedAlias, resolvedName);
this.aliasMap.remove(alias);
} else if (!registeredName.equals(resolvedName)) {
this.aliasMap.put(alias, resolvedName);
}
}
}
}
PropertyPlaceholderConfigurer
public class PropertyPlaceholderConfigurer extends PropertyResourceConfigurer implements BeanNameAware, BeanFactoryAware {
//获取${(${})*}中最后一个}的索引
private int findPlaceholderEndIndex(CharSequence buf, int startIndex) {
int index = startIndex + this.placeholderPrefix.length();
int withinNestedPlaceholder = 0;
while(index < buf.length()) {
if (StringUtils.substringMatch(buf, index, this.placeholderSuffix)) {
if (withinNestedPlaceholder <= 0) {
return index;
}
//嵌套减一层
--withinNestedPlaceholder;
index += this.placeholderSuffix.length();
} else if (StringUtils.substringMatch(buf, index, this.placeholderPrefix)) {
//嵌套加一层
++withinNestedPlaceholder;
index += this.placeholderPrefix.length();
} else {
++index;
}
}
return -1;
}
//
protected String resolvePlaceholder(String placeholder, Properties props, int systemPropertiesMode) {
String propVal = null;
//如果systemPropertiesMode==2从System中获取placeholder的值
if (systemPropertiesMode == 2) {propVal = this.resolveSystemProperty(placeholder);}
//再从props中获取placeholder的值
if (propVal == null) { propVal = this.resolvePlaceholder(placeholder, props);}
//如果systemPropertiesMode==1从System中获取placeholder的值
if (propVal == null && systemPropertiesMode == 1) {propVal = this.resolveSystemProperty(placeholder);}
return propVal;
}
//返回props中placeholder的值
protected String resolvePlaceholder(String placeholder, Properties props) {
return props.getProperty(placeholder);
}
//返回System.getProperty(key)或者System.getenv(key);
protected String resolveSystemProperty(String key) {
try {
String value = System.getProperty(key);
if (value == null && this.searchSystemEnvironment) { value = System.getenv(key); }
return value;
} catch (Throwable var3) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Could not access system property '" + key + "': " + var3);
}
return null;
}
}
//将strVal中是${(${)*\w+(})*}格式且\w+的key存在在props替换成对应的值
protected String parseStringValue(String strVal, Properties props, Set visitedPlaceholders) throws BeanDefinitionStoreException {
StringBuffer buf = new StringBuffer(strVal);
int startIndex = strVal.indexOf(this.placeholderPrefix);
while(startIndex != -1) {
int endIndex = this.findPlaceholderEndIndex(buf, startIndex);
if (endIndex != -1) {
String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex);
if (!visitedPlaceholders.add(placeholder)) {
throw new BeanDefinitionStoreException("Circular placeholder reference '" + placeholder + "' in property definitions");
}
placeholder = this.parseStringValue(placeholder, props, visitedPlaceholders);
String propVal = this.resolvePlaceholder(placeholder, props, this.systemPropertiesMode);
if (propVal != null) {
propVal = this.parseStringValue(propVal, props, visitedPlaceholders);
buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Resolved placeholder '" + placeholder + "'");
}
startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length());
} else {
if (!this.ignoreUnresolvablePlaceholders) {
throw new BeanDefinitionStoreException("Could not resolve placeholder '" + placeholder + "'");
}
startIndex = buf.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
}
visitedPlaceholders.remove(placeholder);
} else {
startIndex = -1;
}
}
return buf.toString();
}
private class PlaceholderResolvingStringValueResolver implements StringValueResolver {
private final Properties props;
public PlaceholderResolvingStringValueResolver(Properties props) { this.props = props; }
//
public String resolveStringValue(String strVal) throws BeansException {
//
String value = PropertyPlaceholderConfigurer.this.parseStringValue(strVal, this.props, new HashSet());
//
return value.equals(PropertyPlaceholderConfigurer.this.nullValue) ? null : value;
}
}
}