日积月累,水滴石穿 😄
在上一篇我们已经阅读过一部分 getBean
的源码了,如果从单例池中获取到了实例,就对这个实例进行判断是否是 FactoryBean
,如果是FactoryBean
,那么真正需要拿到的是 getObject
方法所返回的对象。这节继续往下看,如果没有从单例池中获取到实例,Spring 会干嘛?
单例池没有获取到Bean
//上面代码省略---
//单例池没有获取到Bean
else {
// 指定的原型bean是否正在创建中 如果是则抛出异常
// Spring不支持原型bean的循环依赖
// 当前正在创建的原型Bean都会被放在 prototypesCurrentlyInCreation 这个ThreadLocal中
//1、
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//2、
//获得父级BeanFactory
BeanFactory parentBeanFactory = getParentBeanFactory();
//当前容器的父级容器存在且当前容器中不存在指定名称的BeanDefinition,
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//将用户指定的bean名称解析为规范名称,并拼接上 & 符号
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
// 递归查找
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
//有参数,委托给父级根据指定名称和显式的参数查找
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
//没有参数->委托给父级根据指定名称和type进行查找
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
// 委托父级根据指定名称查找.
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
//3、
// 将指定的bean标记为已创建(或将要创建)。
// typeCheckOnly 上层传入为 false
// 可以去看 Spring源码(二)-XML文件的读取-BeanDefinitionReader 这篇文章 其中有个方法 hasBeanCreationStarted()
// markBeanAsCreated方法就是往 alreadyCreated 这个 Set 中添加数据
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//4、
// 得到合并后的RootBeanDefinition
// 如果指定的 BeanName 是子Bean的话同时会合并父类的相关属性
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//检查给定的合并bean定义
checkMergedBeanDefinition(mbd, beanName, args);
//确保当前bean依赖的bean已经初始化。先加载DependsOn所指定的bean
//xml写法
//<bean class="com.gongj.bean.Person" id="person" depends-on="user"></bean>
//<bean class="com.gongj.bean.User" id="user" depends-on="person"></bean>
//注解写法
//@DependsOn("user")
//获取当前Bean 所有依赖Bean的名称 比如当前beanName为A, A依赖了B
String[] dependsOn = mbd.getDependsOn(); // dependsOn也就是为 B
if (dependsOn != null) {
for (String dep : dependsOn) {
// 判断beanName(A)是不是也被dep(B)依赖了,如果是,就是相互依赖,抛出异常
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 存在两个map中
// 1. dependentBeanMap,key为dep(B), value是一个LinkedHashSet,表示dep(B)被哪些bean(A...)依赖了
// 2. dependenciesForBeanMap,key为beanName(A),value是一个LinkedHashSet,表示beanName(A)依赖了哪些dep(B) bean
registerDependentBean(dep, beanName);
try {
// 先去生成所依赖的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
//5、
// 根据Scope去创建bean
//创建单例模式Bean的实例对象
if (mbd.isSingleton()) {
//使用一个匿名内部类,创建Bean实例对象,并且注册所依赖的对象
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
//如果创建失败,显式地从容器销毁给定的bean
destroySingleton(beanName);
throw ex;
}
});
// sharedInstance可能是一个FactoryBean,如果是FactoryBean
// 那么真正需要拿到的是getObject方法所返回的对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//6、
//创建原型模式Bean实例对象
else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
// 将当前创建的Bean标记为创建中 操作的也就是 prototypesCurrentlyInCreation 这个属性
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 创建完成,从prototypesCurrentlyInCreation移除beanName
afterPrototypeCreation(beanName);
}
// prototypeInstance可能是一个FactoryBean,如果是FactoryBean,
// 那么真正需要拿到的是getObject方法所返回的对象
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//如果要创建的Bean的生命周期范围不是singleton,也不是prototype
//则从 this.scopes.get(scopeName) 获取生命周期; 实例化Bean
//如:request、session等生命周期
//7、
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
// 将当前创建的Bean标记为创建中 操作的也就是 prototypesCurrentlyInCreation 这个属性
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
// 创建完成,从prototypesCurrentlyInCreation移除beanName
afterPrototypeCreation(beanName);
}
});
// scopedInstance可能是一个FactoryBean,如果是FactoryBean,
// 那么真正需要拿到的是getObject方法所返回的对象
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
- 1、:
Spring
首先检查beanName
是否在prototypesCurrentlyInCreation
中,prototypesCurrentlyInCreation
是一个ThreadLocal
,存储了当前正在创建的原型beanName
集合,Spring
不支持原型bean
的循环依赖,所以会抛出一个BeanCurrentlyInCreationException
异常。 - 2、:获取父级容器,如果当前容器的父级容器存在且当前容器中不存在指定名称的
BeanDefinition
,就尝试去父容器中获取bean实例。 - 3、:是否获取实例以进行类型检查。将
beanName
加入alreadyCreated
的 Set 集合中,存储已经创建好的或者正在创建中的beanName
,并调用clearMergedBeanDefinition
方法,删除指定 bean 的合并 bean 定义,并将 stale 设置为 true。stale 为 true 时才会进行 bean 合并。 - 4、:将
GernericBeanDefinition
转换为RootBeanDefinition
,如果指定beanName
是子Bean 的话同时会合并父类的相关属性。如果当前 bean 有依赖 bean,则递归实例化依赖的bean,如果相互依赖,则抛出BeanCreationException
异常。 - 5、:如果
Bean
的作用域为singleton
,则创建单例 Bean 的实例对象。在这里 Spring 调用了一个重载的getSingleton(String beanName, ObjectFactory<?> singletonFactory)
方法实现了 Bean 的加载。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
//去单例池中获取实例
Object singletonObject = this.singletonObjects.get(beanName);
// 如果不存在实例,则创建单例bean实例
if (singletonObject == null) {
// 当前单例正在销毁中,抛出异常
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 把当前正在创建的beanName添加到singletonsCurrentlyInCreation中,
// singletonsCurrentlyInCreation是一个Set
//表示这些单例bean正常创建中,在没创建完时不能重复创建
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// singletonFactory是外面传进来的lambda表达式,执行lambda表达式
//就是调用 createBean()
// 创建单例bean
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 将刚刚正在创建的beanName从singletonsCurrentlyInCreation中移除
afterSingletonCreation(beanName);
}
// 将创建好的单例bean添加到单例池singletonObjects中
//和单例注册表registeredSingletons中
//并清除二级、三级缓存
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
- 6:如果
Bean
的作用域为prototype
,则创建原型模式Bean实例对象。直接调用createBean
方法,原型模式下,每次getBean
都会创建新的对象实例。 - 7:如果 Bean 的作用域不是
singleton
和prototype
,则从this.scopes.get(scopeName)
获取作用域, 实例化Bean。
类型检查
看看就好了。
//检查所需类型是否与实际bean实例的类型匹配
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
数据对象
//当前正在创建的原型bean的名称
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
new NamedThreadLocal<>("Prototype beans currently in creation");
//bean定义对象,key为beanName
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
//合并的RootBeanDefinition,key为beanName
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
//存储已经创建好的或者正在创建中的beanName
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
//单例池
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
//单例工厂的缓存, Bean名称到ObjectFactory,一旦最终对象被创建(通过objectFactory.getObject()),此引用信息将删除 二级缓存
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
//用于存储在创建Bean早期对创建的原始bean的一个引用,注意这里是原始bean,即使用工厂方法或构造方法创建出来的对象,
//一旦对象最终创建好,此引用信息将删除 三级缓存
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
//当前在创建检查中排除的bean名称
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
//当前正在创建的bean的名称,表示这些bean正常创建中,在没创建完时不能重复创建
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
// 已注册的单例beanName
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
下篇开始 createBean
的源码阅读,想想都有点激动。
- 如你对本文有疑问或本文有错误之处,欢迎评论留言指出。如觉得本文对你有所帮助,欢迎点赞和关注。