从单例缓存中获取Bean
getBean()
的第一个过程,获取beanName
上篇已经介绍:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null ) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference" ); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'" ); } } beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null ); }
getSingleton()
方法Spring 对单例模式的 bean 只会创建一次。后续,如果再获取该 Bean ,则是直接从单例缓存中获取:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 private final Map<String, Object> singletonObjects = new ConcurrentHashMap <>(256 );private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap <>(16 );private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap <>(16 );private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap <>(16 ));@Override @Nullable public Object getSingleton (String beanName) { return getSingleton(beanName, true ); }@Nullable protected Object getSingleton (String beanName, boolean allowEarlyReference) { Object singletonObject = this .singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { singletonObject = this .earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { synchronized (this .singletonObjects) { singletonObject = this .singletonObjects.get(beanName); if (singletonObject == null ) { singletonObject = this .earlySingletonObjects.get(beanName); if (sing也letonObject == null ) { ObjectFactory<?> singletonFactory = this .singletonFactories.get(beanName); if (singletonFactory != null ) { singletonObject = singletonFactory.getObject(); this .earlySingletonObjects.put(beanName, singletonObject); this .singletonFactories.remove(beanName); } } } } } } return singletonObject; }
从缓存中获取单例Bean的流程:
第一步,从singletonObjects
中获取Bean对象
第二步,如果获取不到且Bean正在创建中,从earlySingletonObjects
获取Bean对象
第三步,如果获取不到且允许提前创建,从singletonFactories
获取FactoryBean
第四步,如果不为null,则通过FactoryBean.getObject()
获取Bean,然后将其加入到 earlySingletonObjects
,并且从 singletonFactories
删除,两者是互斥的,主要用来解决循环依赖的问题
总结就是:从这三个Map依次去取,取不到就取下一个Map
getObjectForBeanInstance()
方法执行完getSingleton()
如果sharedInstance != null
然后会执行该方法获取真正的实例Bean,执行该方法是因为:
1 如果 sharedInstance 是普通的单例 bean,该方法会直接返回。但如果sharedInstance 是 FactoryBean 类型的,则需调用 getObject 工厂方法获取真正的bean 实例。如果用户想获取 FactoryBean 本身,这里也不会做特别的处理,直接返回即可。毕竟 FactoryBean 的实现类本身也是一种 bean,只不过具有一点特殊的功能而已。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 protected Object getObjectForBeanInstance ( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { if (BeanFactoryUtils.isFactoryDereference(name)) { if (beanInstance instanceof NullBean) { return beanInstance; } if (!(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException (beanName, beanInstance.getClass()); } if (mbd != null ) { mbd.isFactoryBean = true ; } return beanInstance; } if (!(beanInstance instanceof FactoryBean)) { return beanInstance; } Object object = null ; if (mbd != null ) { mbd.isFactoryBean = true ; } else { object = getCachedObjectForFactoryBean(beanName); } if (object == null ) { FactoryBean<?> factory = (FactoryBean<?>) beanInstance; if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
getObjectFromFactoryBean()
方法从上面可以看出, getObjectForBeanInstance(Object beanInstance, String name, String beanName,RootBeanDefinition mbd)
方法,分成两种情况:
第一种,当该实例对象为非 FactoryBean 类型 ,直接 返回给定的 Bean 实例对象 beanInstance
。
第二种,当该实例对象为FactoryBean 类型 ,从 FactoryBean ( beanInstance
) 中,获取 Bean 实例对象,即通过getObjectFromFactoryBean()
来获取。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap <>(16 );protected Object getObjectFromFactoryBean (FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { Object object = this .factoryBeanObjectCache.get(beanName); if (object == null ) { object = doGetObjectFromFactoryBean(factory, beanName); Object alreadyThere = this .factoryBeanObjectCache.get(beanName); if (alreadyThere != null ) { object = alreadyThere; } else { if (shouldPostProcess) { if (isSingletonCurrentlyInCreation(beanName)) { return object; } beforeSingletonCreation(beanName); try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException (beanName, "Post-processing of FactoryBean's singleton object failed" , ex); } finally { afterSingletonCreation(beanName); } } if (containsSingleton(beanName)) { this .factoryBeanObjectCache.put(beanName, object); } } } return object; } } else { Object object = doGetObjectFromFactoryBean(factory, beanName); if (shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException (beanName, "Post-processing of FactoryBean's object failed" , ex); } } return object; } }
主要流程如下:
若为单例且单例 Bean 缓存中存在 beanName
,进行后续处理,否则直接调用doGetObjectFromFactoryBean()
从 FactoryBean 中获取 Bean 实例对象。
若为单例且单例 Bean 缓存中存在 beanName
,进行后续处理:第一步,获取锁。其实我们可以发现大量的同步锁,锁住的对象都是 this.singletonObjects
,主要是因为在单例模式中必须要保证全局唯一 。
1 2 3 4 5 6 7 private final Map<String, Object> singletonObjects = new ConcurrentHashMap <>(256 );@Override public final Object getSingletonMutex () { return this .singletonObjects; }
第二步,从 factoryBeanObjectCache
缓存中获取实例对象 object
。若 object
为空,则调用 doGetObjectFromFactoryBean()
方法,从 FactoryBean 获取 Bean 实例对象,底层是调用 FactoryBean.getObject()
方法,获取 Bean 对象。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 private Object doGetObjectFromFactoryBean (FactoryBean<?> factory, String beanName) throws BeanCreationException { Object object; try { if (System.getSecurityManager() != null ) { AccessControlContext acc = getAccessControlContext(); try { object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { object = factory.getObject(); } } catch (FactoryBeanNotInitializedException ex) { throw new BeanCurrentlyInCreationException (beanName, ex.toString()); } catch (Throwable ex) { throw new BeanCreationException (beanName, "FactoryBean threw exception on object creation" , ex); } if (object == null ) { if (isSingletonCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException ( beanName, "FactoryBean which is currently in creation returned null from getObject" ); } object = new NullBean (); } return object; }
第三步,如果需要后续处理( shouldPostProcess = true
),则进行进一步处理,步骤如下:
若该 Bean 处于创建中(isSingletonCurrentlyInCreation(String beanName)
方法返回 true
),则返回非处理的 Bean 对象 ,而不是存储它。
调用 beforeSingletonCreation(String beanName)
方法,进行创建之前的处理。默认实现将该 Bean 标志为当前创建的。
调用 postProcessObjectFromFactoryBean(Object object, String beanName)
方法,对从 FactoryBean 获取的 Bean 实例对象进行后置处理。
调用 afterSingletonCreation(String beanName)
方法,进行创建 Bean 之后的处理,默认实现是将该 bean 标记为不在创建中。
第四步,加入到 factoryBeanObjectCache
缓存中。
isSingletonCurrentlyInCreation()
方法该方法是用于检测当前 Bean 是否处于创建之中。
beforeSingletonCreation(String beanName)
方法,用于添加标志,当前 bean 正处于 创建中
afterSingletonCreation(String beanName)
方法,用于移除标记,当前 Bean 不处于 创建中。
以上两个方法记录了 Bean 的加载状态,是检测当前 Bean 是否处于创建中的关键之处,对解决 Bean 循环依赖起着关键作用 。
1 2 3 4 5 6 7 8 private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap <>(16 ));public boolean isSingletonCurrentlyInCreation (String beanName) { return this .singletonsCurrentlyInCreation.contains(beanName); }
该集合的元素是通过beforeSingletonCreation(String beanName)
方法添加的:
1 2 3 4 5 6 7 protected void beforeSingletonCreation (String beanName) { if (!this .inCreationCheckExclusions.contains(beanName) && !this .singletonsCurrentlyInCreation.add(beanName)) { throw new BeanCurrentlyInCreationException (beanName); } }
该集合的元素是通过afterSingletonCreation(String beanName)
方法移除的:
1 2 3 4 5 6 7 protected void afterSingletonCreation (String beanName) { if (!this .inCreationCheckExclusions.contains(beanName) && !this .singletonsCurrentlyInCreation.remove(beanName)) { throw new IllegalStateException ("Singleton '" + beanName + "' isn't currently in creation" ); } }
postProcessObjectFromFactoryBean()
方法postProcessObjectFromFactoryBean(Object object, String beanName)
方法,对从 FactoryBean 处获取的 Bean 实例对象进行后置处理。其默认实现是直接返回 object 对象,不做任何处理。
1 2 3 4 5 6 7 8 9 protected Object postProcessObjectFromFactoryBean (Object object, String beanName) throws BeansException { return object; }
方法注释里提到了应用后处理器 AbstractAutowireCapableBeanFactory.java
。
该类就覆盖了上边的方法:
1 2 3 4 5 @Override protected Object postProcessObjectFromFactoryBean (Object object, String beanName) { return applyBeanPostProcessorsAfterInitialization(object, beanName); }
尽可能保证所有 bean 初始化后都会调用注册的 BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName)
方法进行处理,在实际开发过程中大可以针对此特性设计自己的业务逻辑。