主题
除了Spring 学习记录5 BeanFactory 里写的几个接口外,BeanFactory的实现类还实现了一些其他接口,这篇文章主要介绍这些接口和实现类.
结构
DefaultListableBeanFactory和它的父类们除了实现了BF的各种接口以外还实现了AliasRegistry和BeanDefinitionRegistry接口.而且不同等级的父类和BF的相关接口都有交集..
AliasRegistry
这个接口根据说明来看意思是提供别名注册的服务.虽然没有实际使用过别名,不过1个bean确实可以有N个别名.

1 /* 2 * Copyright 2002-2008 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.springframework.core; 18 19 /** 20 * Common interface for managing aliases. Serves as super-interface for 21 * {@link org.springframework.beans.factory.support.BeanDefinitionRegistry}. 22 * 23 * @author Juergen Hoeller 24 * @since 2.5.2 25 */ 26 public interface AliasRegistry { 27 28 /** 29 * Given a name, register an alias for it. 30 * @param name the canonical name 31 * @param alias the alias to be registered 32 * @throws IllegalStateException if the alias is already in use 33 * and may not be overridden 34 */ 35 void registerAlias(String name, String alias); 36 37 /** 38 * Remove the specified alias from this registry. 39 * @param alias the alias to remove 40 * @throws IllegalStateException if no such alias was found 41 */ 42 void removeAlias(String alias); 43 44 /** 45 * Determine whether this given name is defines as an alias 46 * (as opposed to the name of an actually registered component). 47 * @param beanName the bean name to check 48 * @return whether the given name is an alias 49 */ 50 boolean isAlias(String beanName); 51 52 /** 53 * Return the aliases for the given name, if defined. 54 * @param name the name to check for aliases 55 * @return the aliases, or an empty array if none 56 */ 57 String[] getAliases(String name); 58 59 }
接口就4个方法.
1.为1个beanname注册1个别名,
2.删除1个别名
3.判断1个name是否是别名
4.根据beanname获取所有别名.
SimpleAliasRegistry
这个类实现了AliasRegistry,用了1个ConcurrentHashMap来存储所有别名的映射关系.
测试代码:
1 package spring.bf; 2 3 import org.junit.Test; 4 import org.junit.runner.RunWith; 5 import org.springframework.core.SimpleAliasRegistry; 6 import org.springframework.test.context.ContextConfiguration; 7 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 8 import org.springframework.util.StringValueResolver; 9 10 import java.util.Arrays; 11 12 @RunWith(SpringJUnit4ClassRunner.class) 13 @ContextConfiguration("classpath:test-application-context.xml") 14 public class SimpleAliasRegistryTest { 15 16 SimpleAliasRegistry simpleAliasRegistry = new SimpleAliasRegistry(); 17 18 /** 19 * 别名不能循环引用 20 * 会调用checkForAliasCircle方法,做循环引用的检查 21 * 里面会调用canonicalName方法,这个方法会不停的用传入的name当做别名去找他对应的beanname,层层找下去,找到最后1个beanname以后和alias比较一下,如果一直,说明有循环引用就抛出异常 22 */ 23 @Test 24 public void test() { 25 simpleAliasRegistry.registerAlias("b1", "a1"); 26 simpleAliasRegistry.registerAlias("a1", "a2"); 27 //simpleAliasRegistry.registerAlias("a2", "b1"); //java.lang.IllegalStateException: Cannot register alias 'b1' for name 'a2': Circular reference - 'a2' is a direct or indirect alias for 'b1' already 28 } 29 30 /** 31 * 默认情况下别名可以覆盖 32 * 根据子类会不会重写allowAliasOverriding来做决定,默认是true 33 */ 34 @Test 35 public void test2() { 36 simpleAliasRegistry.registerAlias("b1", "a1"); 37 simpleAliasRegistry.registerAlias("b2", "a1"); 38 System.out.println(Arrays.toString(simpleAliasRegistry.getAliases("b1"))); // [] 39 System.out.println(Arrays.toString(simpleAliasRegistry.getAliases("b2"))); // [a1] 40 } 41 42 /** 43 * 移除不存在的bean会抛异常 44 * 所以调用之前可以先用isAlias做判断 45 */ 46 @Test 47 public void test3() { 48 //simpleAliasRegistry.removeAlias("not exists"); // java.lang.IllegalStateException: No alias 'not exists' registered 49 } 50 51 // getAliases会调用retrieveAliases方法,它会递归调用自身,根据beanname找到alias,再把alias当做beanname,把所有的alias都找出来. 52 53 /** 54 * 测试resolveAliases方法 55 */ 56 @Test 57 public void test4() { 58 simpleAliasRegistry.registerAlias("b1", "a1"); 59 simpleAliasRegistry.registerAlias("b2", "a2"); 60 // 报错 61 // java.lang.IllegalStateException: Cannot register resolved alias 'a1' (original: 'a2') for name 'b2': It is already registered for name 'b2'. 62 // 提示感觉有问题.其实应该提示It is already registered for name 'b1'. 63 // 因为alias a2 被解析为a1, 而a1已经指向的是beanname b1,所以不能再指向b2 64 simpleAliasRegistry.resolveAliases(new StringValueResolver() { 65 @Override 66 public String resolveStringValue(String strVal) { 67 if (strVal.equals("a2")) { 68 return "a1"; 69 } 70 return strVal; 71 } 72 }); 73 } 74 }
方法基本在测试里都测了.
另外感觉resolveAliases有一个提示有点问题,请参test4方法.
DefaultSingletonBeanRegistry
直接上注释吧...很多方法目前还不知道为什么这么写.什么时候会用到.看到后面的子类可能就会懂了.

1 /* 2 * Copyright 2002-2015 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.springframework.beans.factory.support; 18 19 import org.apache.commons.logging.Log; 20 import org.apache.commons.logging.LogFactory; 21 import org.springframework.beans.factory.*; 22 import org.springframework.beans.factory.config.SingletonBeanRegistry; 23 import org.springframework.core.SimpleAliasRegistry; 24 import org.springframework.util.Assert; 25 import org.springframework.util.StringUtils; 26 27 import java.util.*; 28 import java.util.concurrent.ConcurrentHashMap; 29 30 /** 31 * Generic registry for shared bean instances, implementing the 32 * {@link org.springframework.beans.factory.config.SingletonBeanRegistry}. 33 * Allows for registering singleton instances that should be shared 34 * for all callers of the registry, to be obtained via bean name. 35 *36 *
Also supports registration of
37 * {@link org.springframework.beans.factory.DisposableBean} instances, 38 * (which might or might not correspond to registered singletons), 39 * to be destroyed on shutdown of the registry. Dependencies between 40 * beans can be registered to enforce an appropriate shutdown order. 41 *42 *
This class mainly serves as base class for
43 * {@link org.springframework.beans.factory.BeanFactory} implementations, 44 * factoring out the common management of singleton bean instances. Note that 45 * the {@link org.springframework.beans.factory.config.ConfigurableBeanFactory} 46 * interface extends the {@link SingletonBeanRegistry} interface. 47 *48 *
Note that this class assumes neither a bean definition concept
49 * nor a specific creation process for bean instances, in contrast to 50 * {@link AbstractBeanFactory} and {@link DefaultListableBeanFactory} 51 * (which inherit from it). Can alternatively also be used as a nested 52 * helper to delegate to. 53 * 54 * @author Juergen Hoeller 55 * @see #registerSingleton 56 * @see #registerDisposableBean 57 * @see org.springframework.beans.factory.DisposableBean 58 * @see org.springframework.beans.factory.config.ConfigurableBeanFactory 59 * @since 2.0 60 */ 61 public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { 62 63 /** 64 * Internal marker for a null singleton object: 65 * used as marker value for concurrent Maps (which don't support null values). 66 * concurrent Maps里不能put null,所以用这个代替 67 */ 68 protected static final Object NULL_OBJECT = new Object(); 69 70 71 /** 72 * Logger available to subclasses 73 */ 74 protected final Log logger = LogFactory.getLog(getClass()); 75 76 /** 77 * Cache of singleton objects: bean name --> bean instance 78 * 存单例的bean,FactoryBean也算 79 */ 80 private final MapsingletonObjects = new ConcurrentHashMap (64); 81 82 /** 83 * Cache of singleton factories: bean name --> ObjectFactory 84 * 存ObjectFactory,我自己没用过. 85 * 测试的时候发现有循环引用的时候.比如A,B相互引用的时候,先扫描到A注册A.当前工厂的一个内部类对象会被注册到这里.有1个bean的引用指向B 86 */ 87 private final Map > singletonFactories = new HashMap >(16); 88 89 /** 90 * Cache of early singleton objects: bean name --> bean instance 91 * 一般情况下可能这个map都是空的,只有2个bean相互引用的时候才会有值. 92 * 看英文解释似乎是一个bean还没被完全创建完的时候会被丢到这个map里.可能作用是先让其他bean先能够引用这个bean吧 93 * 测试A和B相互引用,先扫描到A的话A会放到这里里面,然后开始注册B,B注册完了再remove 94 */ 95 private final Map earlySingletonObjects = new HashMap (16); 96 97 /** 98 * Set of registered singletons, containing the bean names in registration order 99 * 注册的bean的name都会放到这里 100 */ 101 private final Set registeredSingletons = new LinkedHashSet (64); 102 103 /** 104 * Names of beans that are currently in creation 105 * 注册A的时候如果A和B相互引用,A会被放到这里里面.和earlySingletonObjects一起使用 106 */ 107 private final Set singletonsCurrentlyInCreation = 108 Collections.newSetFromMap(new ConcurrentHashMap (16)); 109 110 /** 111 * Names of beans currently excluded from in creation checks 112 * 创建bean过程中有一些bean已经在创建了在创建会报错,用这个可以排除掉这个检查,不知道啥时候会用到 113 */ 114 private final Set inCreationCheckExclusions = 115 Collections.newSetFromMap(new ConcurrentHashMap (16)); 116 117 /** 118 * List of suppressed Exceptions, available for associating related causes 119 * 创建bean过程中出现一些特定的错误的时候可以无视这些错误继续创建 120 */ 121 private Set suppressedExceptions; 122 123 /** 124 * Flag that indicates whether we're currently within destroySingletons 125 * 是否正在销毁bean,可能是factory在destroy的时候就不能再创建bean了 126 */ 127 private boolean singletonsCurrentlyInDestruction = false; 128 129 /** 130 * Disposable bean instances: bean name --> disposable instance 131 * 存disposableBean 132 */ 133 private final Map disposableBeans = new LinkedHashMap (); 134 135 /** 136 * Map between containing bean names: bean name --> Set of bean names that the bean contains 137 * 似乎是用在innerbean和outerbean的时候使用.我一直没使用过这种bean 138 */ 139 private final Map > containedBeanMap = new ConcurrentHashMap >(16); 140 141 /** 142 * Map between dependent bean names: bean name --> Set of dependent bean names 143 * A中有B,那key就是B,value就是A.销毁B之前需要先销毁A 144 */ 145 private final Map > dependentBeanMap = new ConcurrentHashMap >(64); 146 147 /** 148 * Map between depending bean names: bean name --> Set of bean names for the bean's dependencies 149 * 和dependentBeanMap刚好相反,A中有B和C的引用.那key是A value是B和C 150 */ 151 private final Map > dependenciesForBeanMap = new ConcurrentHashMap >(64); 152 153 154 /** 155 * 注册单例bean 156 * 157 * @param beanName 158 * @param singletonObject 159 * @throws IllegalStateException 160 */ 161 @Override 162 public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException { 163 Assert.notNull(beanName, "'beanName' must not be null"); 164 synchronized (this.singletonObjects) { 165 Object oldObject = this.singletonObjects.get(beanName); 166 // 从singletonObjects获取bean,有bean说明已经注册过了不让重新注册 167 if (oldObject != null) { 168 throw new IllegalStateException("Could not register object [" + singletonObject + 169 "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound"); 170 } 171 // 没注册过就掉注册方法 172 addSingleton(beanName, singletonObject); 173 } 174 } 175 176 /** 177 * Add the given singleton object to the singleton cache of this factory. 178 * To be called for eager registration of singletons.
179 * 注册1个单例bean 180 * 181 * @param beanName the name of the bean 182 * @param singletonObject the singleton object 183 */ 184 protected void addSingleton(String beanName, Object singletonObject) { 185 synchronized (this.singletonObjects) { 186 // 注册的单例bean放到singletonObjects和registeredSingletons里,null的话为了防止map抛出异常所以要put一个默认的obj 187 // 但是我也不知道为什么时候add的时候singletonFactories和earlySingletonObjects会有值,需要remove. 188 this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT)); 189 this.singletonFactories.remove(beanName); 190 this.earlySingletonObjects.remove(beanName); 191 this.registeredSingletons.add(beanName); 192 } 193 } 194 195 /** 196 * Add the given singleton factory for building the specified singleton 197 * if necessary. 198 *To be called for eager registration of singletons, e.g. to be able to
199 * resolve circular references. 200 * 和addSingleton几乎一样的道理 201 * 202 * @param beanName the name of the bean 203 * @param singletonFactory the factory for the singleton object 204 */ 205 protected void addSingletonFactory(String beanName, ObjectFactory> singletonFactory) { 206 Assert.notNull(singletonFactory, "Singleton factory must not be null"); 207 synchronized (this.singletonObjects) { 208 if (!this.singletonObjects.containsKey(beanName)) { 209 this.singletonFactories.put(beanName, singletonFactory); 210 this.earlySingletonObjects.remove(beanName); 211 this.registeredSingletons.add(beanName); 212 } 213 } 214 } 215 216 @Override 217 public Object getSingleton(String beanName) { 218 return getSingleton(beanName, true); 219 } 220 221 /** 222 * Return the (raw) singleton object registered under the given name. 223 *Checks already instantiated singletons and also allows for an early
224 * reference to a currently created singleton (resolving a circular reference). 225 * 获取一个单例 226 * 227 * @param beanName the name of the bean to look for 228 * @param allowEarlyReference whether early references should be created or not 229 * @return the registered singleton object, or {@code null} if none found 230 */ 231 protected Object getSingleton(String beanName, boolean allowEarlyReference) { 232 Object singletonObject = this.singletonObjects.get(beanName); 233 // 从singletonObjects中先获取,如果非空就直接返回,如果是空的,判断是否正在创建中 234 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { 235 synchronized (this.singletonObjects) { 236 // 如果正在创建就从earlySingletonObjects中获取A,B相互引用先加载A的时候A会被先放到earlySingletonObjects中而不是singletonObjects中,因为A还没创建就需要创建B 237 singletonObject = this.earlySingletonObjects.get(beanName); 238 // 目前我还没遇到过allowEarlyReference为true的情况 239 if (singletonObject == null && allowEarlyReference) { 240 ObjectFactory> singletonFactory = this.singletonFactories.get(beanName); 241 if (singletonFactory != null) { 242 singletonObject = singletonFactory.getObject(); 243 this.earlySingletonObjects.put(beanName, singletonObject); 244 this.singletonFactories.remove(beanName); 245 } 246 } 247 } 248 } 249 return (singletonObject != NULL_OBJECT ? singletonObject : null); 250 } 251 252 /** 253 * Return the (raw) singleton object registered under the given name, 254 * creating and registering a new one if none registered yet. 255 * 也是获取bean,但是没有的时候可以从工厂里获取 256 * 257 * @param beanName the name of the bean 258 * @param singletonFactory the ObjectFactory to lazily create the singleton 259 * with, if necessary 260 * @return the registered singleton object 261 */ 262 public Object getSingleton(String beanName, ObjectFactory> singletonFactory) { 263 Assert.notNull(beanName, "'beanName' must not be null"); 264 synchronized (this.singletonObjects) { 265 // 获取bean 266 Object singletonObject = this.singletonObjects.get(beanName); 267 if (singletonObject == null) { 268 // 如果工厂正在destroy.就直接抛异常 269 if (this.singletonsCurrentlyInDestruction) { 270 throw new BeanCreationNotAllowedException(beanName, 271 "Singleton bean creation not allowed while the singletons of this factory are in destruction " + 272 "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); 273 } 274 if (logger.isDebugEnabled()) { 275 logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); 276 } 277 // 创建之前做校验,如果已经正在创建了.就报错. 278 beforeSingletonCreation(beanName); 279 boolean newSingleton = false; 280 boolean recordSuppressedExceptions = (this.suppressedExceptions == null); 281 if (recordSuppressedExceptions) { 282 this.suppressedExceptions = new LinkedHashSet(); 283 } 284 try { 285 // 从工厂里获取 286 singletonObject = singletonFactory.getObject(); 287 newSingleton = true; 288 } catch (IllegalStateException ex) { 289 // Has the singleton object implicitly appeared in the meantime -> 290 // if yes, proceed with it since the exception indicates that state. 291 // 之前有 同步 不知道什么时候会进这条分支 292 singletonObject = this.singletonObjects.get(beanName); 293 if (singletonObject == null) { 294 throw ex; 295 } 296 } catch (BeanCreationException ex) { 297 // 如果创建报错了.就把之前抑制的错误一起抛出,不过这个方法里没看到有添加抑制错误的. 298 if (recordSuppressedExceptions) { 299 for (Exception suppressedException : this.suppressedExceptions) { 300 ex.addRelatedCause(suppressedException); 301 } 302 } 303 throw ex; 304 } finally { 305 if (recordSuppressedExceptions) { 306 this.suppressedExceptions = null; 307 } 308 // 把之前的singletonsCurrentlyInCreation添加的正在创建的bean删掉 309 afterSingletonCreation(beanName); 310 } 311 // 如果是新创建了bean就添加到相应的map里 312 if (newSingleton) { 313 addSingleton(beanName, singletonObject); 314 } 315 } 316 return (singletonObject != NULL_OBJECT ? singletonObject : null); 317 } 318 } 319 320 /** 321 * Register an Exception that happened to get suppressed during the creation of a 322 * singleton bean instance, e.g. a temporary circular reference resolution problem. 323 * 添加需要抑制的错误,创建过程中如果报了这些错误,不算出错.本类中没被调用 324 * 325 * @param ex the Exception to register 326 */ 327 protected void onSuppressedException(Exception ex) { 328 synchronized (this.singletonObjects) { 329 if (this.suppressedExceptions != null) { 330 this.suppressedExceptions.add(ex); 331 } 332 } 333 } 334 335 /** 336 * Remove the bean with the given name from the singleton cache of this factory, 337 * to be able to clean up eager registration of a singleton if creation failed. 338 * 移除一个单例bean 339 * 340 * @param beanName the name of the bean 341 * @see #getSingletonMutex() 342 */ 343 protected void removeSingleton(String beanName) { 344 synchronized (this.singletonObjects) { 345 this.singletonObjects.remove(beanName); 346 this.singletonFactories.remove(beanName); 347 this.earlySingletonObjects.remove(beanName); 348 this.registeredSingletons.remove(beanName); 349 } 350 } 351 352 @Override 353 public boolean containsSingleton(String beanName) { 354 return this.singletonObjects.containsKey(beanName); 355 } 356 357 @Override 358 public String[] getSingletonNames() { 359 synchronized (this.singletonObjects) { 360 return StringUtils.toStringArray(this.registeredSingletons); 361 } 362 } 363 364 @Override 365 public int getSingletonCount() { 366 synchronized (this.singletonObjects) { 367 return this.registeredSingletons.size(); 368 } 369 } 370 371 372 /** 373 * 设置一个bean正在被创建的标志,其实是放到一个跳过检查的set里.在这个set里的bean都会跳过检查.不然正在创建又执行创建需要抛出异常 374 * @param beanName 375 * @param inCreation 376 */ 377 public void setCurrentlyInCreation(String beanName, boolean inCreation) { 378 Assert.notNull(beanName, "Bean name must not be null"); 379 if (!inCreation) { 380 this.inCreationCheckExclusions.add(beanName); 381 } else { 382 this.inCreationCheckExclusions.remove(beanName); 383 } 384 } 385 386 public boolean isCurrentlyInCreation(String beanName) { 387 Assert.notNull(beanName, "Bean name must not be null"); 388 return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation(beanName)); 389 } 390 391 /** 392 * setCurrentlyInCreation方法只是用1个set集合记录需要跳过检查步骤的bean,singletonsCurrentlyInCreation里存的bean才是真正正在创建的bean 393 * @param beanName 394 * @return 395 */ 396 protected boolean isActuallyInCreation(String beanName) { 397 return isSingletonCurrentlyInCreation(beanName); 398 } 399 400 /** 401 * Return whether the specified singleton bean is currently in creation 402 * (within the entire factory). 403 * 参考isActuallyInCreation方法 404 * 405 * @param beanName the name of the bean 406 */ 407 public boolean isSingletonCurrentlyInCreation(String beanName) { 408 return this.singletonsCurrentlyInCreation.contains(beanName); 409 } 410 411 /** 412 * Callback before singleton creation. 413 * The default implementation register the singleton as currently in creation.
414 * 在ObjectFactory创建bean之前检查一下是否已经正在创建这个bean了. 415 * 416 * @param beanName the name of the singleton about to be created 417 * @see #isSingletonCurrentlyInCreation 418 */ 419 protected void beforeSingletonCreation(String beanName) { 420 if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) { 421 throw new BeanCurrentlyInCreationException(beanName); 422 } 423 } 424 425 /** 426 * Callback after singleton creation. 427 *The default implementation marks the singleton as not in creation anymore.
428 * 在ObjectFactory创建bean之后,需要这个bean正在创建的标志移除 429 * 430 * @param beanName the name of the singleton that has been created 431 * @see #isSingletonCurrentlyInCreation 432 */ 433 protected void afterSingletonCreation(String beanName) { 434 if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) { 435 throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation"); 436 } 437 } 438 439 440 /** 441 * Add the given bean to the list of disposable beans in this registry. 442 *Disposable beans usually correspond to registered singletons,
443 * matching the bean name but potentially being a different instance 444 * (for example, a DisposableBean adapter for a singleton that does not 445 * naturally implement Spring's DisposableBean interface). 446 * 注册DisposableBean 447 * 448 * @param beanName the name of the bean 449 * @param bean the bean instance 450 */ 451 public void registerDisposableBean(String beanName, DisposableBean bean) { 452 synchronized (this.disposableBeans) { 453 this.disposableBeans.put(beanName, bean); 454 } 455 } 456 457 /** 458 * Register a containment relationship between two beans, 459 * e.g. between an inner bean and its containing outer bean. 460 *Also registers the containing bean as dependent on the contained bean
461 * in terms of destruction order. 462 * 注册嵌套的bean.我从来没用过. 463 * 464 * @param containedBeanName the name of the contained (inner) bean 内部bean 465 * @param containingBeanName the name of the containing (outer) bean 外部bean 466 * @see #registerDependentBean 467 */ 468 public void registerContainedBean(String containedBeanName, String containingBeanName) { 469 // A quick check for an existing entry upfront, avoiding synchronization... 470 SetcontainedBeans = this.containedBeanMap.get(containingBeanName); 471 if (containedBeans != null && containedBeans.contains(containedBeanName)) { 472 return; 473 } 474 475 // No entry yet -> fully synchronized manipulation of the containedBeans Set 476 synchronized (this.containedBeanMap) { 477 containedBeans = this.containedBeanMap.get(containingBeanName); 478 if (containedBeans == null) { 479 containedBeans = new LinkedHashSet (8); 480 this.containedBeanMap.put(containingBeanName, containedBeans); 481 } 482 containedBeans.add(containedBeanName); 483 } 484 registerDependentBean(containedBeanName, containingBeanName); 485 } 486 487 /** 488 * Register a dependent bean for the given bean, 489 * to be destroyed before the given bean is destroyed. 490 * 注册相互依赖的bean.比如A中有B.dependentBeanMap里key是B,value是A.需要先销毁A再销毁B 491 * dependenciesForBeanMap刚好相反.可以参考之前成员域上的注释 492 * 493 * @param beanName the name of the bean 494 * @param dependentBeanName the name of the dependent bean 495 */ 496 public void registerDependentBean(String beanName, String dependentBeanName) { 497 // A quick check for an existing entry upfront, avoiding synchronization... 498 // 先把别名转化到真正的bean name 499 String canonicalName = canonicalName(beanName); 500 Set dependentBeans = this.dependentBeanMap.get(canonicalName); 501 if (dependentBeans != null && dependentBeans.contains(dependentBeanName)) { 502 return; 503 } 504 505 // No entry yet -> fully synchronized manipulation of the dependentBeans Set 506 // 依赖之前没注册过就注册到相应的map里去 507 synchronized (this.dependentBeanMap) { 508 dependentBeans = this.dependentBeanMap.get(canonicalName); 509 if (dependentBeans == null) { 510 dependentBeans = new LinkedHashSet (8); 511 this.dependentBeanMap.put(canonicalName, dependentBeans); 512 } 513 dependentBeans.add(dependentBeanName); 514 } 515 synchronized (this.dependenciesForBeanMap) { 516 Set dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName); 517 if (dependenciesForBean == null) { 518 dependenciesForBean = new LinkedHashSet (8); 519 this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean); 520 } 521 dependenciesForBean.add(canonicalName); 522 } 523 } 524 525 /** 526 * Determine whether the specified dependent bean has been registered as 527 * dependent on the given bean or on any of its transitive dependencies. 528 * 判断2个bean是否有依赖关系 529 * 530 * @param beanName the name of the bean to check 531 * @param dependentBeanName the name of the dependent bean 532 * @since 4.0 533 */ 534 protected boolean isDependent(String beanName, String dependentBeanName) { 535 return isDependent(beanName, dependentBeanName, null); 536 } 537 538 /** 539 * 判断2个bean是否有依赖关系,A中有B,B中有C,那C依赖A是true. 540 * @param beanName 541 * @param dependentBeanName 542 * @param alreadySeen 543 * @return 544 */ 545 private boolean isDependent(String beanName, String dependentBeanName, Set alreadySeen) { 546 String canonicalName = canonicalName(beanName); 547 if (alreadySeen != null && alreadySeen.contains(beanName)) { 548 return false; 549 } 550 // canonicalName是C dependentBeans是B 551 Set dependentBeans = this.dependentBeanMap.get(canonicalName); 552 if (dependentBeans == null) { 553 return false; 554 } 555 if (dependentBeans.contains(dependentBeanName)) { 556 return true; 557 } 558 // 第一轮没找到A只找到包含B的一个set.所以再便利这个set.去看这个set里的bean是否依赖A,但是可能会有循环引用.所以找过的bean需要记录,不需要再找 559 for (String transitiveDependency : dependentBeans) { 560 if (alreadySeen == null) { 561 alreadySeen = new HashSet (); 562 } 563 alreadySeen.add(beanName); // 已经找过的bean放到这里.C已经找过了. 564 if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) { // 递归调用,判断B是否依赖A,是true.而C依赖B,所以C依赖A 565 return true; 566 } 567 } 568 return false; 569 } 570 571 /** 572 * Determine whether a dependent bean has been registered for the given name. 573 * 574 * @param beanName the name of the bean to check 575 */ 576 protected boolean hasDependentBean(String beanName) { 577 return this.dependentBeanMap.containsKey(beanName); 578 } 579 580 /** 581 * Return the names of all beans which depend on the specified bean, if any. 582 * 583 * @param beanName the name of the bean 584 * @return the array of dependent bean names, or an empty array if none 585 */ 586 public String[] getDependentBeans(String beanName) { 587 Set dependentBeans = this.dependentBeanMap.get(beanName); 588 if (dependentBeans == null) { 589 return new String[0]; 590 } 591 return StringUtils.toStringArray(dependentBeans); 592 } 593 594 /** 595 * Return the names of all beans that the specified bean depends on, if any. 596 * 597 * @param beanName the name of the bean 598 * @return the array of names of beans which the bean depends on, 599 * or an empty array if none 600 */ 601 public String[] getDependenciesForBean(String beanName) { 602 Set dependenciesForBean = this.dependenciesForBeanMap.get(beanName); 603 if (dependenciesForBean == null) { 604 return new String[0]; 605 } 606 return dependenciesForBean.toArray(new String[dependenciesForBean.size()]); 607 } 608 609 /** 610 * 销毁单例bean 611 */ 612 public void destroySingletons() { 613 if (logger.isDebugEnabled()) { 614 logger.debug("Destroying singletons in " + this); 615 } 616 // 设置正在销毁的标志 617 synchronized (this.singletonObjects) { 618 this.singletonsCurrentlyInDestruction = true; 619 } 620 621 String[] disposableBeanNames; 622 synchronized (this.disposableBeans) { 623 disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet()); 624 } 625 // 取出所有disposableBeans然后调用每个bean都调用相应的销毁方法 626 for (int i = disposableBeanNames.length - 1; i >= 0; i--) { 627 destroySingleton(disposableBeanNames[i]); 628 } 629 630 // 所有缓存清空 631 this.containedBeanMap.clear(); 632 this.dependentBeanMap.clear(); 633 this.dependenciesForBeanMap.clear(); 634 635 synchronized (this.singletonObjects) { 636 this.singletonObjects.clear(); 637 this.singletonFactories.clear(); 638 this.earlySingletonObjects.clear(); 639 this.registeredSingletons.clear(); 640 this.singletonsCurrentlyInDestruction = false; 641 } 642 } 643 644 /** 645 * Destroy the given bean. Delegates to {@code destroyBean} 646 * if a corresponding disposable bean instance is found. 647 * 648 * @param beanName the name of the bean 649 * @see #destroyBean 650 */ 651 public void destroySingleton(String beanName) { 652 // Remove a registered singleton of the given name, if any. 653 removeSingleton(beanName); 654 655 // Destroy the corresponding DisposableBean instance. 656 DisposableBean disposableBean; 657 synchronized (this.disposableBeans) { 658 disposableBean = (DisposableBean) this.disposableBeans.remove(beanName); 659 } 660 destroyBean(beanName, disposableBean); 661 } 662 663 /** 664 * Destroy the given bean. Must destroy beans that depend on the given 665 * bean before the bean itself. Should not throw any exceptions. 666 * 667 * @param beanName the name of the bean 668 * @param bean the bean instance to destroy 669 */ 670 protected void destroyBean(String beanName, DisposableBean bean) { 671 // Trigger destruction of dependent beans first... 672 // 销毁1个bean的时候需要按顺序,先销毁引用她的bean,再销毁他自己 673 Set dependencies = this.dependentBeanMap.remove(beanName); 674 if (dependencies != null) { 675 if (logger.isDebugEnabled()) { 676 logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies); 677 } 678 for (String dependentBeanName : dependencies) { 679 //对于每个引用这个bean的所有bean,先销毁他们,再销毁当前这个beanName对应的bean,A中有B需要先销毁A 680 destroySingleton(dependentBeanName); 681 } 682 } 683 684 // Actually destroy the bean now... 685 if (bean != null) { 686 try { 687 bean.destroy(); // DisposableBean接口的方法 688 } catch (Throwable ex) { 689 logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex); 690 } 691 } 692 693 // Trigger destruction of contained beans... 694 // 对于内部bean也一样,先销毁外部的bean 695 Set containedBeans = this.containedBeanMap.remove(beanName); 696 if (containedBeans != null) { 697 for (String containedBeanName : containedBeans) { 698 destroySingleton(containedBeanName); 699 } 700 } 701 702 // Remove destroyed bean from other beans' dependencies. 703 // 销毁了这个bean,那dependentBeanMap中如果其他bean依赖这个bean,就都可以移除这个bean的引用.比如A中有B和C类.destroyB的时候需要先destroy A 704 // 那destroy A了以后因为C也依赖A.所以也要把dependentBeanMap的key c 对应的vaalue A也删除,不然下次删除C的时候又要删除A.这样就重复destroy A了. 705 synchronized (this.dependentBeanMap) { 706 for (Iterator >> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext(); ) { 707 Map.Entry > entry = it.next(); 708 Set dependenciesToClean = entry.getValue(); 709 dependenciesToClean.remove(beanName); 710 if (dependenciesToClean.isEmpty()) { 711 it.remove(); 712 } 713 } 714 } 715 716 // Remove destroyed bean's prepared dependency information. 717 this.dependenciesForBeanMap.remove(beanName); 718 } 719 720 /** 721 * Exposes the singleton mutex to subclasses and external collaborators. 722 * Subclasses should synchronize on the given Object if they perform
723 * any sort of extended singleton creation phase. In particular, subclasses 724 * should not have their own mutexes involved in singleton creation, 725 * to avoid the potential for deadlocks in lazy-init situations. 726 */ 727 public final Object getSingletonMutex() { 728 return this.singletonObjects; 729 } 730 731 }
FactoryBeanRegistrySupport
这个类基本上和它的父类DefaultSingletonBeanRegistry功能差不多.就是多了1个叫做factoryBeanObjectCache的map去缓存FactoryBean生成的bean...代码写法都大同小异..我想分享下期中的1个方法
1 /** 2 * Obtain an object to expose from the given FactoryBean. 3 * 4 * @param factory the FactoryBean instance 5 * @param beanName the name of the bean 6 * @param shouldPostProcess whether the bean is subject to post-processing 7 * @return the object obtained from the FactoryBean 8 * @throws BeanCreationException if FactoryBean object creation failed 9 * @see org.springframework.beans.factory.FactoryBean#getObject() 10 */ 11 protected Object getObjectFromFactoryBean(FactoryBean> factory, String beanName, boolean shouldPostProcess) { 12 if (factory.isSingleton() && containsSingleton(beanName)) { // FactoryBean返回的对象是单例并且FactoryBean(不是返回的对象)这个bean已经在缓存中了 13 synchronized (getSingletonMutex()) { 14 Object object = this.factoryBeanObjectCache.get(beanName); // 从缓存里拿FactoryBean的返回对象 15 if (object == null) { // 没缓存的话 16 object = doGetObjectFromFactoryBean(factory, beanName); // 就重新生成 17 // Only post-process and store if not put there already during getObject() call above 18 // (e.g. because of circular reference processing triggered by custom getBean calls) 19 Object alreadyThere = this.factoryBeanObjectCache.get(beanName); // 不懂为什么上面去过一次是null了需要再取几次...什么时候会发生呢? 20 if (alreadyThere != null) { 21 object = alreadyThere; 22 } else { 23 if (object != null && shouldPostProcess) { 24 try { 25 object = postProcessObjectFromFactoryBean(object, beanName); // 后置处理 26 } catch (Throwable ex) { 27 throw new BeanCreationException(beanName, 28 "Post-processing of FactoryBean's singleton object failed", ex); 29 } 30 } 31 this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT)); 32 } 33 } 34 return (object != NULL_OBJECT ? object : null); 35 } 36 } else { // 不是单例,或者第一次调用FactoryBean不再缓存中 37 Object object = doGetObjectFromFactoryBean(factory, beanName); // 从FactoryBean里生成 38 if (object != null && shouldPostProcess) { 39 try { 40 object = postProcessObjectFromFactoryBean(object, beanName); // 后置处理 41 } catch (Throwable ex) { 42 throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex); 43 } 44 } 45 return object; 46 } 47 }
对比它的父类里的一些map....
factoryBeanObjectCache里存的是BeanFactory的getObject返回的对象.
singletonObjects里存一般的单例和BeanFactory对象.
然后不管是BeanFactory还是BeanFactory返回的对象.beanname都是不带&,这点和使用BeanFactory的getBean方法不太一样...等看到后面的BF可能就清楚为什么了.
另外postProcessObjectFromFactoryBean这个方法在当前类里仅仅返回传入参数object.但是是个protected的方法,子类肯定会去重写的.这个方法不出意外应该就是BeanPostProcessor参与Spring声明周期的地方(对于FactoryBean来说).
一个小测试:
1 package spring.bf; 2 3 import org.junit.Test; 4 import org.junit.runner.RunWith; 5 import org.springframework.beans.BeansException; 6 import org.springframework.beans.factory.FactoryBean; 7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.beans.factory.annotation.Qualifier; 9 import org.springframework.beans.factory.config.BeanPostProcessor; 10 import org.springframework.stereotype.Component; 11 import org.springframework.test.context.ContextConfiguration; 12 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 13 14 @RunWith(SpringJUnit4ClassRunner.class) 15 @ContextConfiguration("classpath:test-application-context.xml") 16 public class FactoryBeanRegistrySupportTest { 17 18 @Autowired 19 @Qualifier("factoryBeanRegistrySupportTest_FactoryBean") 20 Object o; 21 22 /** 23 * 测试BeanFactory和BeanPostProcessor 24 */ 25 @Test 26 public void test1() { 27 System.out.println(o); 28 } 29 } 30 31 32 @Component 33 class FactoryBeanRegistrySupportTest_FactoryBean implements FactoryBean
输出:
postProcessBeforeInitialization ->factoryBeanRegistrySupportTest_FactoryBean 这个是FactoryBean作为单例被new的时候做的
postProcessAfterInitialization ->factoryBeanRegistrySupportTest_FactoryBean 这个是FactoryBean作为单例被new的时候做的
postProcessAfterInitialization ->factoryBeanRegistrySupportTest_FactoryBean 这个是FactoryBean的getObject返回的对象做的
java.lang.Object@f1e3986 输出getObject返回的对象
那么为什么FactoryBean的返回对象不要做postProcessBeforeInitialization,只做了postProcessAfterInitialization 呢??? 为什么这样设定??? 不太懂.
我觉得.可能是其他bean的afterProperties可能会扫描一些特性的bean做处理..这里工厂返回的bean肯定没有被之前扫描到.而postProcessBeforeInitialization是要在afterProperties之前做的(对于单个bean来说).所以这里不再执行.
AbstractBeanFactory

1 /* 2 * Copyright 2002-2015 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.springframework.beans.factory.support; 18 19 import org.springframework.beans.*; 20 import org.springframework.beans.factory.*; 21 import org.springframework.beans.factory.config.*; 22 import org.springframework.core.DecoratingClassLoader; 23 import org.springframework.core.NamedThreadLocal; 24 import org.springframework.core.convert.ConversionService; 25 import org.springframework.util.*; 26 27 import java.beans.PropertyEditor; 28 import java.security.*; 29 import java.util.*; 30 import java.util.concurrent.ConcurrentHashMap; 31 32 /** 33 * Abstract base class for {@link org.springframework.beans.factory.BeanFactory} 34 * implementations, providing the full capabilities of the 35 * {@link org.springframework.beans.factory.config.ConfigurableBeanFactory} SPI. 36 * Does not assume a listable bean factory: can therefore also be used 37 * as base class for bean factory implementations which obtain bean definitions 38 * from some backend resource (where bean definition access is an expensive operation). 39 *40 *
This class provides a singleton cache (through its base class
41 * {@link org.springframework.beans.factory.support.DefaultSingletonBeanRegistry}, 42 * singleton/prototype determination, {@link org.springframework.beans.factory.FactoryBean} 43 * handling, aliases, bean definition merging for child bean definitions, 44 * and bean destruction ({@link org.springframework.beans.factory.DisposableBean} 45 * interface, custom destroy methods). Furthermore, it can manage a bean factory 46 * hierarchy (delegating to the parent in case of an unknown bean), through implementing 47 * the {@link org.springframework.beans.factory.HierarchicalBeanFactory} interface. 48 *49 *
The main template methods to be implemented by subclasses are
50 * {@link #getBeanDefinition} and {@link #createBean}, retrieving a bean definition 51 * for a given bean name and creating a bean instance for a given bean definition, 52 * respectively. Default implementations of those operations can be found in 53 * {@link DefaultListableBeanFactory} and {@link AbstractAutowireCapableBeanFactory}. 54 * 55 * @author Rod Johnson 56 * @author Juergen Hoeller 57 * @author Costin Leau 58 * @author Chris Beams 59 * @see #getBeanDefinition 60 * @see #createBean 61 * @see AbstractAutowireCapableBeanFactory#createBean 62 * @see DefaultListableBeanFactory#getBeanDefinition 63 * @since 15 April 2001 64 */ 65 public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { 66 67 /** 68 * Parent bean factory, for bean inheritance support 69 */ 70 private BeanFactory parentBeanFactory; 71 72 /** 73 * ClassLoader to resolve bean class names with, if necessary 74 */ 75 private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); 76 77 /** 78 * ClassLoader to temporarily resolve bean class names with, if necessary 79 */ 80 private ClassLoader tempClassLoader; 81 82 /** 83 * Whether to cache bean metadata or rather reobtain it for every access 84 */ 85 private boolean cacheBeanMetadata = true; 86 87 /** 88 * Resolution strategy for expressions in bean definition values 89 */ 90 private BeanExpressionResolver beanExpressionResolver; 91 92 /** 93 * Spring ConversionService to use instead of PropertyEditors 94 */ 95 private ConversionService conversionService; 96 97 /** 98 * Custom PropertyEditorRegistrars to apply to the beans of this factory 99 */ 100 private final SetpropertyEditorRegistrars = 101 new LinkedHashSet (4); 102 103 /** 104 * A custom TypeConverter to use, overriding the default PropertyEditor mechanism 105 */ 106 private TypeConverter typeConverter; 107 108 /** 109 * Custom PropertyEditors to apply to the beans of this factory 110 */ 111 private final Map , Class extends PropertyEditor>> customEditors = 112 new HashMap , Class extends PropertyEditor>>(4); 113 114 /** 115 * String resolvers to apply e.g. to annotation attribute values 116 */ 117 private final List embeddedValueResolvers = new LinkedList (); 118 119 /** 120 * BeanPostProcessors to apply in createBean 121 */ 122 private final List beanPostProcessors = new ArrayList (); 123 124 /** 125 * Indicates whether any InstantiationAwareBeanPostProcessors have been registered 126 */ 127 private boolean hasInstantiationAwareBeanPostProcessors; 128 129 /** 130 * Indicates whether any DestructionAwareBeanPostProcessors have been registered 131 */ 132 private boolean hasDestructionAwareBeanPostProcessors; 133 134 /** 135 * Map from scope identifier String to corresponding Scope 136 */ 137 private final Map scopes = new LinkedHashMap (8); 138 139 /** 140 * Security context used when running with a SecurityManager 141 */ 142 private SecurityContextProvider securityContextProvider; 143 144 /** 145 * Map from bean name to merged RootBeanDefinition 146 */ 147 private final Map mergedBeanDefinitions = 148 new ConcurrentHashMap (64); 149 150 /** 151 * Names of beans that have already been created at least once 152 */ 153 private final Set alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap (64)); 154 155 /** 156 * Names of beans that are currently in creation 157 */ 158 private final ThreadLocal
一些方法加了注释,还有很多方法和其中的ifelse不明白为什么要这么写...
后续的一些逻辑要做实验才会明白了....