上一篇介绍了BeanFactory体系的所有接口——Spring源码分析——BeanFactory体系之接口详细分析,本篇就接着介绍BeanFactory体系的抽象类和接口。
一、BeanFactory的基本类体系结构(类为主):
上图可与 的图结合分析,一个以接口为主,一个以类为主(PS:Spring的体系结构要分析清楚,不得不曲线救国啊!不然27寸屏幕给我画估计都装不下。)。
具体:
1、7层的类体系继承。
2、AbstractBeanFactory实现了最重要的ConfigurableBeanFactory接口,DefaultSingletonBeanRegistry实现了SingletonBeanRegistry单例类注册接口,SimpleAliasRegistry实现了AliasRegistry别名注册接口。
3、祖先类SimpleAliasRegistry、DefaultSingletonBeanRegistry和子孙类XmlBeanFactory、DefaultListableBeanFactory是完整的类,而中间的类FactoryBeanRegistrySupport、AbstractBeanFactory、AbstractAutowireCapableBeanFactory都是抽象类。
总结:
具体上来说,XmlBeanFactory光是父类就有6个了,加上自身,总共7层了。实际上分析接口结构就会看到,作为IOC类工厂而言,XmlBeanFactory的类体系结构实际是从祖先AbstractBeanFactory这个类开始的,因为是它实现了BeanFactory的子接口ConfigurableBeanFactory,虽然它继承自FactoryBeanRegistrySupport,但可以说这只是工厂功能的扩充,扩展了对工厂Bean以及工厂所产生的Bean的操作。
二、简单的别名注册器——SimpleAliasRegistry
上篇已经讲过AliasRegistry,非常简单的4个方法,体现了对别名注册的支持,而SimpleAliasRegistry就是它的简单实现。
源码:
public class SimpleAliasRegistry implements AliasRegistry { /* *用一个支持高并发的ConcurrentHashMap来放置所有的别名 */ private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>( 16); // AliasRegistry的接口方法,注册别名。不允许重复注册。 public void registerAlias(String name, String alias) { Assert.hasText(name, "'name' must not be empty"); Assert.hasText(alias, "'alias' must not be empty"); if (alias.equals(name)) { this.aliasMap.remove(alias); } else { if (!allowAliasOverriding()) { String registeredName = 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 + "'."); } } checkForAliasCircle(name, alias);//alias不能等于name在map中最后的对应(详见checkForAliasCircle方法) this.aliasMap.put(alias, name);//alias是key,name是value } } /** * 返回是否允许Alias重写,默认为允许 */ protected boolean allowAliasOverriding() { return true; } // AliasRegistry的接口方法,移除别名,如果别名未注册,则抛出异常 public void removeAlias(String alias) { String name = this.aliasMap.remove(alias); if (name == null) { throw new IllegalStateException("No alias '" + alias + "' registered"); } } // AliasRegistry的接口方法,给定名称判断是否为别名 public boolean isAlias(String name) { return this.aliasMap.containsKey(name); } // AliasRegistry的接口方法 public String[] getAliases(String name) { List<String> result = new ArrayList<String>(); synchronized (this.aliasMap) { retrieveAliases(name, result); } return StringUtils.toStringArray(result); } /* * 找出名字说对应的所有别名。 */ private void retrieveAliases(String name, List<String> result) { for (Map.Entry<String, String> entry : this.aliasMap.entrySet()) {//遍历aliasMap String registeredName = entry.getValue();//取aliasMap的每个value if (registeredName.equals(name)) {//如果value等于指定的这个name String alias = entry.getKey();//取value对应的key result.add(alias);//将alias加入 retrieveAliases(alias, result);//继续查看以alias为value的key } } } /* * 处理所有的别名,如果处理正确,把原来的用解析后的替换 */ public void resolveAliases(StringValueResolver valueResolver) { Assert.notNull(valueResolver, "StringValueResolver must not be null"); synchronized (this.aliasMap) { Map<String, String> aliasCopy = new HashMap<String, String>( this.aliasMap); for (String alias : aliasCopy.keySet()) { String registeredName = aliasCopy.get(alias);//取出key对应的value String resolvedAlias = valueResolver.resolveStringValue(alias);//解析后的key String resolvedName = valueResolver .resolveStringValue(registeredName);//解析后的value if (resolvedAlias.equals(resolvedName)) {//若解析后的key、name相等,就把它们从aliasMap中移除 this.aliasMap.remove(alias); } else if (!resolvedAlias.equals(alias)) {//若解析后的key不等于原来的Key String existingName = this.aliasMap.get(resolvedAlias);//取出解析后的key对应的value if (existingName != null//如果不为空且不等于解析后的value,就抛出异常 && !existingName.equals(resolvedName)) { throw new IllegalStateException( "Cannot register resolved alias '" + resolvedAlias + "' (original: '" + alias + "') for name '" + resolvedName + "': It is already registered for name '" + registeredName + "'."); } checkForAliasCircle(resolvedName, resolvedAlias); this.aliasMap.remove(alias); this.aliasMap.put(resolvedAlias, resolvedName); } else if (!registeredName.equals(resolvedName)) { this.aliasMap.put(alias, resolvedName); } } } } /* * 根据name这个Key,在aliasMap中不断循环的取对应的value,如果取得到,就继续根据这个value取值,不断循环继续。 * 直到取不到,就把这个在aliasMap中无对应值的key返回。 */ public String canonicalName(String name) { String canonicalName = name; //规范名 // Handle aliasing... String resolvedName;//已解析名 do { resolvedName = this.aliasMap.get(canonicalName);//aliasMap中规范名对应的值赋值给已解析名 if (resolvedName != null) {//如果已解析名存在(即规范名在aliasMap中有对应的值) canonicalName = resolvedName; // 这个已解析名赋值给标准名 } } while (resolvedName != null);//不断循环,直到已解析名不存在 return canonicalName; } /* * 如果别名alias等于canonicalName(name)就抛出异常 */ protected void checkForAliasCircle(String name, String alias) { if (alias.equals(canonicalName(name))) { throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" + name + "': Circular reference - '" + name + "' is a direct or indirect alias for '" + alias + "' already"); } } }