【11.实例化所有(非惰性初始化)单例Bean】 finishBeanFactoryInitialization(beanFactory);
方法概述
finishBeanFactoryInitialization 是整个 Spring IoC 核心中的核心。
该方法会实例化所有剩余的非懒加载单例 bean。
除了一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其他的非懒加载单例 bean 都会在这个方法中被实例化,并且 BeanPostProcessor 的触发也是在这个方法中。
源码剖析_finishBeanFactoryInitialization
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 1、设置此上下文的类型转换器,不是核心,往下
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析
// 不是核心,继续往下
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// 3.初始化LoadTimeWeaverAware Bean实例对象
// 处理 @EnableLoadTimeWeaving 或 <context:load-time-weaver/> 标记的类 不是核心,继续往下
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
//临时类加载器设置为空
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
// 4.冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了
// 【冻结配置】:设置冻结属性变量为true
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 5.实例化所有剩余(非懒加载)单例对象
beanFactory.preInstantiateSingletons();
}
5.实例化所有剩余(非懒加载)单例对象,见代码块1详解。
MergedBeanDefinition: “合并的 bean 定义”:
之所以称之为 “合并的”,是因为存在 “子定义” 和 “父定义” 的情况。对于一个 bean 定义来说,可能存在以下几种情况:
- 该 BeanDefinition 存在 “父定义”:首先使用 “父定义” 的参数构建一个 RootBeanDefinition,然后再使用该 BeanDefinition 的参数来进行覆盖。
- 该 BeanDefinition 不存在 “父定义”,并且该 BeanDefinition 的类型是 RootBeanDefinition:直接返回该 RootBeanDefinition 的一个克隆。
- 该 BeanDefinition 不存在 “父定义”,但是该 BeanDefinition 的类型不是 RootBeanDefinition:使用该 BeanDefinition 的参数构建一个 RootBeanDefinition。
之所以区分出2和3,是因为通常 BeanDefinition 在之前加载到 BeanFactory 中的时候,通常是被封装成 GenericBeanDefinition 或 ScannedGenericBeanDefinition,但是从这边之后 bean 的后续流程处理都是针对 RootBeanDefinition,因此在这边会统一将 BeanDefinition 转换成 RootBeanDefinition。
在我们日常使用的过程中,通常会是上面的第3种情况 如果我们使用 XML 配置来注册 bean,则该 bean 定义会被封装成:GenericBeanDefinition;如果我们使用注解的方式来注册 bean,也就是<context:component-scan /> + @Compoment,则该 bean 定义会被封装成 ScannedGenericBeanDefinition。
代码块1:preInstantiateSingletons
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
// 1.创建beanDefinitionNames的副本beanNames用于后续的遍历,以允许init等方法注册新的bean定义
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 2.遍历beanNames,触发所有非懒加载单例bean的初始化
for (String beanName : beanNames) {
// 3.获取beanName对应的MergedBeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 4.bd对应的Bean实例:不是抽象类 && 是单例 && 不是懒加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 5.判断beanName对应的bean是否为FactoryBean
if (isFactoryBean(beanName)) {
// 5.1 通过beanName获取FactoryBean实例
// 通过getBean(&beanName)拿到的是FactoryBean本身;通过getBean(beanName)拿到的是FactoryBean创建的Bean实例
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
// 5.2 判断这个FactoryBean是否希望急切的初始化
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
} else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
// 5.3 如果希望急切的初始化,则通过beanName获取bean实例
getBean(beanName);
}
} else {
// 6.如果beanName对应的bean不是FactoryBean,只是普通Bean,通过beanName获取bean实例
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// 7.遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调
for (String beanName : beanNames) {
// 7.1 拿到beanName对应的bean实例
Object singletonInstance = getSingleton(beanName);
// 7.2 判断singletonInstance是否实现了SmartInitializingSingleton接口
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
// 7.3 触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
- 3.获取 beanName 对应的 MergedBeanDefinition,见代码块2详解。
- 5.判断 beanName 对应的 bean 是否为 FactoryBean,见代码块3详解。
- 5.3 和 6. 通过 beanName 获取 bean 实例,finishBeanFactoryInitialization 方法的核心,单独分析!!。
- 7.遍历 beanNames,触发所有 SmartInitializingSingleton 的后初始化回调,这是 Spring 提供的一个扩展点,在所有非懒加载单例实例化结束后调用。
代码块2:getMergedLocalBeanDefinition
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
// 1.检查beanName对应的MergedBeanDefinition是否存在于缓存中
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
// 2.如果存在于缓存中则直接返回
return mbd;
}
// 3.如果不存在于缓存中
// 3.1 getBeanDefinition(beanName): 获取beanName对应的BeanDefinition,从beanDefinitionMap缓存中获取
// 3.2 getMergedBeanDefinition: 根据beanName和对应的BeanDefinition,获取MergedBeanDefinition
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
代码块3:isFactoryBean
@Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
// 1.拿到真正的beanName(去掉&前缀、解析别名)
String beanName = transformedBeanName(name);
// 2.尝试从缓存获取Bean实例对象
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {
// 3.beanInstance存在,则直接判断类型是否为FactoryBean
return (beanInstance instanceof FactoryBean);
} else if (containsSingleton(beanName)) {
// 4.如果beanInstance为null,并且beanName在单例对象缓存中,则代表beanName对应的单例对象为空对象,返回false
// null instance registered
return false;
}
// No singleton instance found -> check bean definition.
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// 5.如果缓存中不存在此beanName && 父beanFactory是ConfigurableBeanFactory,则调用父BeanFactory判断是否为FactoryBean
// No bean definition found in this factory -> delegate to parent.
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
// 6.通过MergedBeanDefinition来检查beanName对应的Bean是否为FactoryBean
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
2.尝试从缓存获取 bean 实例对象,见代码块4详解
代码块4:getSingleton
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1.从单例对象缓存中获取beanName对应的单例对象
Object singletonObject = this.singletonObjects.get(beanName);
// 2.如果单例对象缓存中没有,并且该beanName对应的单例bean正在创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 3.加锁进行操作
synchronized (this.singletonObjects) {
// 4.从早期单例对象缓存中获取单例对象(之所称成为早期单例对象,是因为earlySingletonObjects里
// 的对象的都是通过提前曝光的ObjectFactory创建出来的,还未进行属性填充等操作)
singletonObject = this.earlySingletonObjects.get(beanName);
// 5.如果在早期单例对象缓存中也没有,并且允许创建早期单例对象引用
if (singletonObject == null && allowEarlyReference) {
// 6.从单例工厂缓存中获取beanName的单例工厂
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 7.如果存在单例对象工厂,则通过工厂创建一个单例对象
singletonObject = singletonFactory.getObject();
// 8.将通过单例对象工厂创建的单例对象,放到早期单例对象缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
// 9.移除该beanName对应的单例对象工厂,因为该单例工厂已经创建了一个实例对象,并且放到earlySingletonObjects缓存了,
// 因此,后续获取beanName的单例对象,可以通过earlySingletonObjects缓存拿到,不需要在用到该单例工厂
this.singletonFactories.remove(beanName);
}
}
}
}
// 10.返回单例对象
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}
这段代码很重要,在正常情况下,该代码很普通,只是正常的检查下我们要拿的 bean 实例是否存在于缓存中,如果有就返回缓存中的 bean 实例,否则就返回 null。
这段代码之所以重要,是因为该段代码是 Spring 解决循环引用的核心代码。
解决循环引用逻辑:使用构造函数创建一个 “不完整” 的 bean 实例(之所以说不完整,是因为此时该 bean 实例还未初始化),并且提前曝光该 bean 实例的 ObjectFactory(提前曝光就是将 ObjectFactory 放到 singletonFactories 缓存),通过 ObjectFactory 我们可以拿到该 bean 实例的引用,如果出现循环引用,我们可以通过缓存中的 ObjectFactory 来拿到 bean 实例,从而避免出现循环引用导致的死循环。这边通过缓存中的 ObjectFactory 拿到的 bean 实例虽然拿到的是 “不完整” 的 bean 实例,但是由于是单例,所以后续初始化完成后,该 bean 实例的引用地址并不会变,所以最终我们看到的还是完整 bean 实例。
另外这个代码块中引进了4个重要缓存:
- singletonObjects 缓存:beanName -> 单例 bean 对象。
- earlySingletonObjects 缓存:beanName -> 单例 bean 对象,该缓存存放的是早期单例 bean 对象,可以理解成还未进行属性填充、初始化。
- singletonFactories 缓存:beanName -> ObjectFactory。
【singletonObjects、earlySingletonObjects、singletonFactories 在这边构成了一个类似于 “一、二、三级缓存” 的概念。】
- singletonsCurrentlyInCreation 缓存:当前正在创建单例 bean 对象的 beanName 集合。