BeanFactory的基本类体系结构(类为主):
上图可与 Spring源码分析——BeanFactory体系之接口详细分析 的图结合分析,一个以接口为主,一个以类为主
具体:
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就是它的简单实现。
源码:
1 public class SimpleAliasRegistry implements AliasRegistry { 2 3 /* 4 *用一个支持高并发的ConcurrentHashMap来放置所有的别名 5 */ 6 private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>( 7 16); 8 9 // AliasRegistry的接口方法,注册别名。不允许重复注册。 10 public void registerAlias(String name, String alias) { 11 Assert.hasText(name, "'name' must not be empty"); 12 Assert.hasText(alias, "'alias' must not be empty"); 13 if (alias.equals(name)) { 14 this.aliasMap.remove(alias); 15 } else { 16 if (!allowAliasOverriding()) { 17 String registeredName = this.aliasMap.get(alias); 18 if (registeredName != null && !registeredName.equals(name)) { 19 throw new IllegalStateException("Cannot register alias '" 20 + alias + "' for name '" + name 21 + "': It is already registered for name '" 22 + registeredName + "'."); 23 } 24 } 25 checkForAliasCircle(name, alias);//alias不能等于name在map中最后的对应(详见checkForAliasCircle方法) 26 this.aliasMap.put(alias, name);//alias是key,name是value 27 } 28 } 29 30 /** 31 * 返回是否允许Alias重写,默认为允许 32 */ 33 protected boolean allowAliasOverriding() { 34 return true; 35 } 36 37 // AliasRegistry的接口方法,移除别名,如果别名未注册,则抛出异常 38 public void removeAlias(String alias) { 39 String name = this.aliasMap.remove(alias); 40 if (name == null) { 41 throw new IllegalStateException("No alias '" + alias 42 + "' registered"); 43 } 44 } 45 46 // AliasRegistry的接口方法,给定名称判断是否为别名 47 public boolean isAlias(String name) { 48 return this.aliasMap.containsKey(name); 49 } 50 51 // AliasRegistry的接口方法 52 public String[] getAliases(String name) { 53 List<String> result = new ArrayList<String>(); 54 synchronized (this.aliasMap) { 55 retrieveAliases(name, result); 56 } 57 return StringUtils.toStringArray(result); 58 } 59 60 /* 61 * 找出名字说对应的所有别名。 62 */ 63 private void retrieveAliases(String name, List<String> result) { 64 for (Map.Entry<String, String> entry : this.aliasMap.entrySet()) {//遍历aliasMap 65 String registeredName = entry.getValue();//取aliasMap的每个value 66 if (registeredName.equals(name)) {//如果value等于指定的这个name 67 String alias = entry.getKey();//取value对应的key 68 result.add(alias);//将alias加入 69 retrieveAliases(alias, result);//继续查看以alias为value的key 70 } 71 } 72 } 73 74 /* 75 * 处理所有的别名,如果处理正确,把原来的用解析后的替换 76 */ 77 public void resolveAliases(StringValueResolver valueResolver) { 78 Assert.notNull(valueResolver, "StringValueResolver must not be null"); 79 synchronized (this.aliasMap) { 80 Map<String, String> aliasCopy = new HashMap<String, String>( 81 this.aliasMap); 82 for (String alias : aliasCopy.keySet()) { 83 String registeredName = aliasCopy.get(alias);//取出key对应的value 84 String resolvedAlias = valueResolver.resolveStringValue(alias);//解析后的key 85 String resolvedName = valueResolver 86 .resolveStringValue(registeredName);//解析后的value 87 if (resolvedAlias.equals(resolvedName)) {//若解析后的key、name相等,就把它们从aliasMap中移除 88 this.aliasMap.remove(alias); 89 } else if (!resolvedAlias.equals(alias)) {//若解析后的key不等于原来的Key 90 String existingName = this.aliasMap.get(resolvedAlias);//取出解析后的key对应的value 91 if (existingName != null//如果不为空且不等于解析后的value,就抛出异常 92 && !existingName.equals(resolvedName)) { 93 throw new IllegalStateException( 94 "Cannot register resolved alias '" 95 + resolvedAlias 96 + "' (original: '" 97 + alias 98 + "') for name '" 99 + resolvedName 100 + "': It is already registered for name '" 101 + registeredName + "'."); 102 } 103 checkForAliasCircle(resolvedName, resolvedAlias); 104 this.aliasMap.remove(alias); 105 this.aliasMap.put(resolvedAlias, resolvedName); 106 } else if (!registeredName.equals(resolvedName)) { 107 this.aliasMap.put(alias, resolvedName); 108 } 109 } 110 } 111 } 112 113 /* 114 * 根据name这个Key,在aliasMap中不断循环的取对应的value,如果取得到,就继续根据这个value取值,不断循环继续。 115 * 直到取不到,就把这个在aliasMap中无对应值的key返回。 116 */ 117 public String canonicalName(String name) { 118 String canonicalName = name; //规范名 119 // Handle aliasing... 120 String resolvedName;//已解析名 121 do { 122 resolvedName = this.aliasMap.get(canonicalName);//aliasMap中规范名对应的值赋值给已解析名 123 if (resolvedName != null) {//如果已解析名存在(即规范名在aliasMap中有对应的值) 124 canonicalName = resolvedName; // 这个已解析名赋值给标准名 125 } 126 } while (resolvedName != null);//不断循环,直到已解析名不存在 127 return canonicalName; 128 } 129 130 /* 131 * 如果别名alias等于canonicalName(name)就抛出异常 132 */ 133 protected void checkForAliasCircle(String name, String alias) { 134 if (alias.equals(canonicalName(name))) { 135 throw new IllegalStateException("Cannot register alias '" + alias 136 + "' for name '" + name + "': Circular reference - '" 137 + name + "' is a direct or indirect alias for '" + alias 138 + "' already"); 139 } 140 } 141 142 }