这是我参与8月更文挑战的第27天,活动详情查看:8月更文挑战
前言
Finish the initialization of this context's bean factory, Instantiate all remaining (non-lazy-init) singletons.
该方法主要做普通Bean的创建和初始化.该方法会实例化所有剩余的非懒加载单例 bean。
Spring 源码分析系列
- Spring源码分析-源码阅读环境搭建
- Spring源码分析-IOC基本概念
- Spring源码分析-IOC核心组件
- Spring源码分析-IOC源码分析(一)
- Spring IOC源码分析-obtainFreshBeanFactory(二)
- Spring IOC源码分析-invokeBeanFactoryPostProcessors (三)
- Spring IOC源码分析-registerBeanPostProcessors(四)
下面回顾一下refresh的12个步骤
源码分析
1. 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 BeanFactoryPostProcessor
// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// 3. 初始化LoadTimeWeaverAware Bean实例对象
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 实例对象了
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 5. 实例化所有剩余(非懒加载)单例对象
beanFactory.preInstantiateSingletons();
}
2. preInstantiateSingletons
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("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<>(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实例
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
// 5.2 判断这个FactoryBean是否希望急切的初始化
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((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) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
// 7.3 触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
3. getMergedLocalBeanDefinition
MergedBeanDefinition 合并的Bean定义,之所以称为合并Bean定义,是因为存在父子关系.
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
// 先查询缓存有没有
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null && !mbd.stale) {
return mbd;
}
// 根据 beanName 和 beanName 对应的 BeanDefinition,获取 MergedBeanDefinition
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}
4. getMergedBeanDefinition
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
// 1. 枷锁
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
RootBeanDefinition previous = null;
// Check with full lock now in order to enforce the same merged instance.
// 2.检查beanName对应的MergedBeanDefinition是否存在于缓存中
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
// 3.如果beanName对应的MergedBeanDefinition不存在于缓存中
if (mbd == null || mbd.stale) {
previous = mbd;
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
// 4.如果bd的parentName为空,代表bd没有父定义,无需与父定义进行合并操作
if (bd instanceof RootBeanDefinition) {
// 4.1 如果bd的类型为RootBeanDefinition,则直接克隆一个副本
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
// 4.2 否则,构建一个RootBeanDefinition
mbd = new RootBeanDefinition(bd);
}
}
else {
// Child bean definition: needs to be merged with parent.
// 5.否则,bd存在父定义,需要与父定义合并
BeanDefinition pbd;
try {
// 5.1 获取父定义的beanName
String parentBeanName = transformedBeanName(bd.getParentName());
// 5.2 如果父定义的beanName与该bean的beanName不同
if (!beanName.equals(parentBeanName)) {
// 5.3 递归获取父定义的MergedBeanDefinition
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
// 5.4 如果父定义的beanName与bd的beanName相同,则拿到父BeanFactory,
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
// 5.5 如果父BeanFactory是ConfigurableBeanFactory,则通过父BeanFactory获取父定义的MergedBeanDefinition
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
// 5.6 如果不是,直接抛异常
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without a ConfigurableBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
// 5.7 使用父定义pbd构建一个新的RootBeanDefinition对象(深拷贝)
mbd = new RootBeanDefinition(pbd);
// 5.8 使用bd覆盖父定义
mbd.overrideFrom(bd);
}
// Set default singleton scope, if not configured before.
// 6.如果没有配置scope,则设置成默认的singleton
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(SCOPE_SINGLETON);
}
// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
// 7.如果containingBd不为空 && containingBd不为singleton && mbd为singleton
// 则将mdb的scope设置为containingBd的scope
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
// 8.将beanName与mbd放到mergedBeanDefinitions缓存,以便之后可以直接使用
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if (previous != null) {
copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
// 9.返回MergedBeanDefinition
return mbd;
}
}
5. transformedBeanName
将 name 真正解析成真正的 beanName,主要是去掉 FactoryBean 里的 “&” 前缀,和解析别名。
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
// beanName 转换
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}
// 将别名解析成真正的beanName
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
FactoryBean 和 BeanFactory的区别
BeanFactory 是 Bean 的工厂, ApplicationContext 的父类,IOC 容器的核心,负责生产和管理 Bean 对象。
FactoryBean 是 Bean,可以通过实现 FactoryBean 接口定制实例化 Bean 的逻辑,通过代理一个Bean对象,对方法前后做一些操作。
6. getMergedBeanDefinition
父子容器 BeanFactory
在 Spring 中可能存在多个 BeanFactory,多个 BeanFactory 可能存在 “父工厂” 与 “子工厂” 的关系。
最常见的例子就是:
Spring MVC 的 BeanFactory 和 Spring 的 BeanFactory,通常情况下,Spring 的 BeanFactory 是 “父工厂”,Spring MVC 的 BeanFactory 是 “子工厂”,在 Spring 中,子工厂可以使用父工厂的 BeanDefinition,因而,如果在当前 BeanFactory 中找不到,而又存在父工厂,则会去父工厂中查找。
@Override
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
//1.获取真正的beanName(解析别名)
String beanName = transformedBeanName(name);
// Efficiently check whether bean definition exists in this factory.
// 2.如果当前BeanFactory中不存在beanName的Bean定义 && 父beanFactory是ConfigurableBeanFactory,
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// 调用父BeanFactory去获取beanName的MergedBeanDefinition
return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
}
// Resolve merged bean definition locally.
// 3.在当前BeanFactory中解析beanName的MergedBeanDefinition
return getMergedLocalBeanDefinition(beanName);
}
7. 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);
}
// No singleton instance found -> check bean definition.
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
// 5.如果缓存中不存在此beanName && 父beanFactory是ConfigurableBeanFactory
// 则调用父BeanFactory判断是否为FactoryBean
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
// 6.通过MergedBeanDefinition来检查beanName对应的Bean是否为FactoryBean
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
8. getSingleton
经典的三级缓存代码, 常见面试题目如何解决循环依赖? 为什么要三级缓存,二级缓存是不是就行了等等?
spring内部有三级缓存
- singletonObjects 一级缓存,用于保存实例化、注入、初始化完成的bean实例
- earlySingletonObjects 二级缓存,用于保存实例化完成的bean实例
- singletonFactories 三级缓存,用于保存bean创建工厂,以便于后面扩展有机会创建代理对象。
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
// 1.从单例对象缓存中获取beanName对应的单例对象
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 2.如果单例对象缓存中没有,并且该beanName对应的单例bean正在创建中
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 3.加锁进行操作
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
// 4.从早期单例对象缓存中获取单例对象(一级缓存)
// 之所称成为早期单例对象,是因为earlySingletonObjects里的对象的都是通过提前曝光的ObjectFactory创建出来的,还未进行属性填充等操作
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 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);
}
}
}
}
}
}
return singletonObject;
}
9. isFactoryBean
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
Boolean result = mbd.isFactoryBean;
if (result == null) {
// 1. 获取beanName对应的Bean实例的类型
Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
// 2.返回beanType是否为FactoryBean本身、子类或子接口
result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
mbd.isFactoryBean = result;
}
return result;
}
10. predictBeanType
@Nullable
protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
Class<?> targetType = mbd.getTargetType();
if (targetType != null) {
return targetType;
}
if (mbd.getFactoryMethodName() != null) {
return null;
}
return resolveBeanClass(mbd, beanName, typesToMatch);
}
最后
回顾一下 finishBeanFactoryInitialization 主要功能普通Bean的创建和初始化. 还有一些非常容易混淆的概念
- MergedBeanDefinition 合并BeanDefinition
- FactoryBean 和 BeanFactory的区别
- 父子容器 BeanFactory
- spring内部有三级缓存, singletonObjects, earlySingletonObjects,singletonFactories