>>>doGetBean()方法解析
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
/*
* 第一环节: 处理携带 &的name。这里最终获取的就是beanName
*/
String beanName = transformedBeanName(name);
Object bean;
/*
* 第二环节:从缓存中尝试获取对象
*/
Object sharedInstance = getSingleton(beanName);
/*
* 第三环节: 3.1从缓存中获取的对象不为NULL。
*/
if (sharedInstance != null && args == null) {
/*
* 这里为什么又要套呢?为什么不直接缓存呢?
* 因为从缓存中拿到的对象,可能是普通单实例,也可能是FactoryBean实例,
* 如果是FactoryBean实例,这个时候还要进行处理,主要是看name是否携带 '&'
* (携带&说明想要获取FactoryBean实例(很少用),不携带&说明想要获取内部创建的复杂对象实例(常用))
*
* 这里最终返回要么是FactoryBean对象要么是getObject()创建的对象。
* (这里如果是获取的内部创建的复杂对象并且是单例的,会将其放到缓存中)
* */
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
/*
* 以下环节的前提:从缓存中获取的对象为NULL。
*/
else {
/*
* 原型模式循环依赖的判定(Spring无法处理,只能抛出异常)
* (即原型模式对象A依赖一个B(B可能是原型也可能不是原型),B依赖A)
* 1.当前线程会在ThreadLoal中的Set集合中存储一个字符串"A",表示当前正在创建A对象
* 2.此时创建出来的A对象是一个早期对象
* 3.处理A的依赖,发现A依赖了B类型的对象,触发了getBean(B)的逻辑
* 4.根据B构造方法创建出B的早期实例
* 5.处理B的依赖,发现依赖了A
* 6.然后继续走上getBean("A")的逻辑,但是此时ThreadLocal的set集合中存
* 在A字符串说明当前A正在创建中,表示发生了循环依赖,此时直接抛出异常。
* */
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//这里处理父子容器(不再详细分析)
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//第五环节 - 合并bd 返回合并后的mbd。
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//判断当前bd是否为抽象bd,抽象bd直接抛出异常。
checkMergedBeanDefinition(mbd, beanName, args);
/*
* 第六环节-处理depends-on依赖
* <bean id = "A" depends-on = "B" >
* <bean id = "B">
*
* 循环依赖问题
* <bean id = "A" depends-on = "B" >
* <bean id = "B" depends-on = "A">
* Spring是处理不了这种情况的,需要报错。。
* Spring需要发现这种情况的产生。
* 如何发现? 依靠两个Map
* 1.dependentBeanMap 记录依赖当前beanName的其他beanName
* 2.dependenciesForBeanMap 记录当前beanName依赖的其他beanName集合。
* */
//获取A的depends-on的所有对象
String[] dependsOn = mbd.getDependsOn();
//不为NULL。
if (dependsOn != null) {
//遍历所有的depends-on对象
for (String dep : dependsOn) {
//判断循环依赖
if (isDependent(beanName, dep)) {
//这里抛出异常了 由于代码太长这里省略
}
//将依赖关系注册到两个Map中
registerDependentBean(dep, beanName);
try {
//先去获取依赖的对象。
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
//抛出异常
}
}
// 第七环节mbd是单例,创建出单例对象
if (mbd.isSingleton()) {
//从缓存中获取
sharedInstance = getSingleton(beanName, () -> {
try {
/*
* 创建根据beanName和bd创建出实例对象,创建后会放入缓存
* createBean()核心方法,
*/
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
//这里的逻辑跟3.1.1一样,还要判断&的情况
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
/*
* 这里会将当前的beanName放到ThreadLoacl的Set集合中去,
* 表示当前的这个beanName表示的对象正在创建中。
* 后续如果当前bd与某个bd产生了循环依赖,走到第四环节Spring就
* 会发现产生了原型循环依赖(Spring无法处理),直接抛出异常。
*
*/
beforePrototypeCreation(beanName);
//创建对象
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//创建完毕 会将Set中的当前beanName干掉。
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//scope除了singleton和prototye其他情况很少见,这里就不在分析了
else {
//....
}
}
//类型
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
//检查需要的类型是够符合Bean的实际类型
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
//抛出异常
}
//需要转换则进行一次转换。
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
//打印日志
}
//抛出异常
}
}
//返回bean。
return (T) bean;
}
第一环节-处理beanName
1.1transformedBeanName()
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
/*
* FACTORY_BEAN_PREFIX = '&'
* name不是以&开头的,直接return即可
* */
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
/*
* transformedBeanNameCache是一个Map,computeIfAbsent()方法
* 当key = NULL 或者 value = NULL时,这次put操作就会成功(并且会返回value),否则就会失败
* 最终Map中存一个(&person, person)
* */
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
/*
* 截取一下,将&干掉。 例如 "&person" -> "person"
* */
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
//最终将去掉&的name返回
return beanName;
});
}
1.2canonicalName()
/*
* 从alilasMap中查找
* ["C" : "B"] ["B" : "A"] 即 A有一个别名是 B,B有一个别名是C,
* 这里就是在循环查找 C -> B -> A的过程。 因为在map中是没有A作为Key的Entry的。
* */
public String canonicalName(String name) {
String canonicalName = name;
String resolvedName;
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
//最终返回A
return canonicalName;
}
第二环节-尝试从缓存中获取实例
2.1关于三级缓存
/*
* 一级缓存,key -> beanName : value创建出的单实例对象(经过完整生命周期)
* */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/*
* 三级缓存,当一个单实例bean刚被创建出来时(还未完成初始化等后续操作),会将当前bean实例
* 包装成一个ObjectFactory对象放到三级缓存。
* */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/*
* 二级缓存 : 用来保存实例化完成,但是还未初始化完成的对象
* key -> beanName : value -> Bean实例
* 当单实例bean正在创建过程中时,会先放到三级缓存中,然后其他线程调用getBean()时,
* 从三级缓存中获取到了bean对象,然后就会将此bean从三级缓存中干掉,放到二级缓存中去
*
* */
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
2.2关于ObjectFactory
Spring为单实例对象创建的早期对象会被封装为一个ObjectFactory的实现类,调用内部的getObject()方法可以得到内部的早期对象(也可能是早期对象的代理类对象(AOP)),然后会被放到三级缓存的 singletonFactories(Map) 中。
@FunctionalInterface
public interface ObjectFactory<T> {
T getObject() throws BeansException;
}
2.3getSingleton()
/*
* @param allowEarlyReference 是否允许早期引用
* 最终返回值情况
* 1.一级缓存中找到,返回
* 2.一级缓存没找到,二级缓存中找到 返回
* 3.一二级缓存都没有,三级缓存(ObjectFactory)中找到,将三级缓存中的对象干掉放到二级 * 缓存,并返回
*/
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从一级缓存中拿
Object singletonObject = this.singletonObjects.get(beanName);
/*
* 满足下面的if条件:(一级缓存没有 并且 当前的bean对象正在创建中)
* Spring会将正在创建的bean的beanName加入到一个Set集合中。
*
* 条件一成立(singletionObject == null) 有几种可能?
* 1.单实例确实未创建
* 2.单实例正在创建中,当前发生了循环依赖
*
* 什么是循环依赖? A依赖B,B依赖A。
* 单实例有几种循环依赖呢?
* 1.构造方法循环依赖 (无解)
* 2.set注入循环依赖 (有解,依靠三级缓存解决)
*
* 三级缓存如何解决set注入造成的循环依赖。
* 举个例子 A -> B , B - A.
* 1.假设Spring先实例化A,首先拿到A的构造方法,然后反射创建出A的早期对象,这时,
* 这个早期对象被包装成了ObjectFactory对象放到了三级缓存中
* 2.处理A的依赖数据,检查发现A依赖了B,所以接下来就走到getBean(B)的逻辑
* 3.拿到B的构造方法然后反射创建早期实例对象,也会将B包装成ObjectFactory放到三级缓存中
* 4.处理B的依赖数据,发现B依赖了A,所以接下来就会又走到getBean(A)去获得A对象,
* 5.所以程序这时会走到当前这个getSingleton()方法
* 6.走到这里的if判断,两个判断都会成立(1.A不在一级缓存中 2.A正在创建)
* */
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//从二级缓存中获取
singletonObject = this.earlySingletonObjects.get(beanName);
//二级缓存也没有 去三级缓存中查看。
if (singletonObject == null && allowEarlyReference) {
//加锁
synchronized (this.singletonObjects) {
/*
* Spring为什么需要有三级缓存存在,而不是只有二级缓存呢?
* AOP,靠动态代理实现。
* 3级缓存在这里又什么目的呢?
* 三级缓存中保存的是ObjectFactory,里面保存着原生的对象引用,getObject()方法需要考虑的是要返回
* 原生对象还是增强后的对象,getObject()方法会判断当前这个早期实例
* 是否需要被增强,如果需要的话,那么必须提前完成动态代理增强
* 返回代理对象,否则返回原生对象。
* */
//尝试继续从一级缓存中获取
singletonObject = this.singletonObjects.get(beanName);
//一级缓存中不存在
if (singletonObject == null) {
//再次尝试从二级缓存中获取
singletonObject = this.earlySingletonObjects.get(beanName);
//二级缓存也不存在
if (singletonObject == null) {
//从三级缓存中获取
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
//三级缓存不为NULL
if (singletonFactory != null) {
//获取包装的ObjectFactory中的早期对象
singletonObject = singletonFactory.getObject();
//将早期对象放到二级缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
//将这个beanName对应的ObjectFactory从三级缓存中干掉
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
第三环节-判断从缓存中获取对象的情况
3.1从缓存中获取对象不为NULL
3.1.1getObjectForBeanInstance()
/*
* 此方法就是判断getBean时的name情况是否是普通单实例或者是FactoryBean实例
* 传入从缓存中获取实例(不为NULL)。
*
* 1.name携带了&,说明想要获取的就是FactoryBean的实现类对象,直接返回。
* 2.name没有携带&
* 2.1获取的缓存对象不属于FactoryBean类型,说明是普通单实例对象,直接返回
* 2.2获取的缓存对象属于FactoryBean类型,且name没有携带&,说明此时想要获取的就
* 是FactoryBean.getObject()创建的对象。
* 此时需要先判断是否可以从(beanName -> FactoryBean内部对象)的map中获取
* 获取成功返回,获取失败调用内部的getObject()方法拿到内部对象,然后返回
* (注意:如果FactoryBean内部的对象规定为单例的,那么拿到内部的对象后还需要放
* 到缓存中,否则不需要放入缓存)
*/
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// 判断name是否携带了& 条件成立,说明要获取的是FactoryBean实例
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
//从缓存中获取的实例不是FactoryBean实例,说明获取错误,抛出异常
if (!(beanInstance instanceof FactoryBean)) {
//抛出异常
}
//给当前的bean实例对应的mbd打一个标记,表明当前实例是一个FactoryBean
if (mbd != null) {
mbd.isFactoryBean = true;
}
//还是返回缓存中的实例
return beanInstance;
}
/*
* 执行到这里,有几种情况?
* 1.当前bean实例就是普通单实例
* 2.当前bean实例是FactoryBean接口实现类,且想要获取内部创建的复杂对象实例
* */
//1.当前bean实例就是普通单实例
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
/*
* 2.当前bean实例是FactoryBean接口实现类,且想要获取内部创建的复杂对象实例
*/
//object保存FactoryBean实现类内部创建的对象
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
} else {
//尝试从缓存中获取FactoryBean.getObject()的返回值对象
object = getCachedObjectForFactoryBean(beanName);
}
//缓存中获取不到
if (object == null) {
//将beanInstance强转为FactoryBean对象
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
/*
* 条件一: 一般都成立
* 条件二: 判断是否存在当前beanName对应的bd
* */
if (mbd == null && containsBeanDefinition(beanName)) {
//合并bd
mbd = getMergedLocalBeanDefinition(beanName);
}
// synthetic默认为false,表示这是一个用户对象,true表示是系统对象
boolean synthetic = (mbd != null && mbd.isSynthetic());
//获取FactoryBean内部getObject()创建的对象
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
//返回object
return object;
}
3.1.2getObjectFromFactoryBean()
/*
* 判断FactoryBean内部的对象是单例还是原型模式,
*(加锁) 单例: 先从缓存中拿,拿不到调用getObject()获取对象,然后放到缓存中并返回
* 原型: 直接调用getObject()获取对象
*/
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
/*
* CASE1 FactoryBean内部维护的对象是单实例
* */
if (factory.isSingleton() && containsSingleton(beanName)) {
//加锁
synchronized (getSingletonMutex()) {
//尝试从缓存中获取 当前FactoryBean的beanName对应的内部实例
Object object = this.factoryBeanObjectCache.get(beanName);
//缓存中没有
if (object == null) {
//这里就是调用FactoryBean对象内部的getObject()方法获取内部对象
object = doGetObjectFromFactoryBean(factory, beanName);
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
beforeSingletonCreation(beanName);
try {
//执行后处理器
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
//抛异常
}
finally {
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
//将beanName -> 内部的Object(单实例) 放到缓存中(Map)中
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
//最终返回内部的object
return object;
}
}
/*
* FactoryBean内部维护的对象非单实例
* */
else {
//直接调用FactoryBean内部的getObject()方法获取对象
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
//执行后处理器
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
//抛出异常
}
}
//返回object
return object;
}
}
(以下环节都是从缓存中获取对象为NULL后的环节)
第四环节-判断原型模式循环依赖
protected boolean isPrototypeCurrentlyInCreation(String beanName) {
/*
* prototypesCurrentlyInCreation(ThreadLocal)
* 获取内部的set集合或者字符串,然后判断beanName是否存在。存在说明发生了循环依赖
* */
Object curVal = this.prototypesCurrentlyInCreation.get();
return (curVal != null &&
(curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
}
第五环节-合并BeanDefinition信息
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
//表示合并后的bd信息
RootBeanDefinition mbd = null;
//表示当前beanName对应的过期mbd信息
RootBeanDefinition previous = null;
// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
//条件成立:表示mbd是NULL 或者是过期的
if (mbd == null || mbd.stale) {
//赋值给previous
previous = mbd;
//当前bd没有父bd,就不需要处理继承了
if (bd.getParentName() == null) {
// 克隆一个bd赋值给mbd (当前bd就是RootBeanDefinition)
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
} else {
//传入当前bd构造一个RootBeanDefinition
mbd = new RootBeanDefinition(bd);
}
//当前bd使用了继承,需要进行合并
} else {
//父bd信息
BeanDefinition pbd;
try {
//获取处理了别名和&的真实父bd 的beanName
String parentBeanName = transformedBeanName(bd.getParentName());
//条件成立:子bd和父bd名称不一样,就是普通情况
if (!beanName.equals(parentBeanName)) {
//这里是一个递归调用,最终返回父bd信息
pbd = getMergedBeanDefinition(parentBeanName);
//非一般情况,子bd和父bd名称一样
} else {
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
} else {
//抛出异常
}
}
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
//按照父bd信息创建一个RootBD,赋值给mbd
mbd = new RootBeanDefinition(pbd);
//子bd覆盖mbd信息,以子bd为基准,pbd为辅
mbd.overrideFrom(bd);
}
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(SCOPE_SINGLETON);
}
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)
if (containingBd == null && isCacheBeanMetadata()) {
//缓存mbd信息
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if (previous != null) {
copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
//返回合并后的mbd。
return mbd;
}
}
第六环节-处理depends-on属性
6.1registerDependentBean
/*
* 注册依赖关系
* <bean id = "A" depends-on = "B">
* 这里的dep 就是B, beanName就是A
* 所以这里 beanName = B, dependentBeanName = A
* */
public void registerDependentBean(String beanName, String dependentBeanName) {
//循环在alilasMap中查找最终的B的beanName
String canonicalName = canonicalName(beanName);
/*
* 这里在 dependentBeanMap存储 B -> (A) <即B被A依赖>
* */
synchronized (this.dependentBeanMap) {
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
/*
* 这里在 dependenciesForBeanMap中存储 A -> (B) <即A依赖B>
* */
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
6.2sisDependent()
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
if (alreadySeen != null && alreadySeen.contains(beanName)) {
return false;
}
String canonicalName = canonicalName(beanName);
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
return false;
}
//这里如果有循环依赖的话(双标签),通过上面的两个Map会发现,这里就返回true。
if (dependentBeans.contains(dependentBeanName)) {
return true;
}
for (String transitiveDependency : dependentBeans) {
if (alreadySeen == null) {
alreadySeen = new HashSet<>();
}
alreadySeen.add(beanName);
if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
return true;
}
}
return false;
}
第七环节-创建(单)实例流程
这里我们以创建单实例(即scope = singleton)
为例子来讲解源码。
7.1getSingleton()
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);
if (singletonObject == null) {
//容器销毁时,会设置这个属性为true,这个时候就不能在创建bean了,直接抛错
if (this.singletonsCurrentlyInDestruction) {
//...抛出异常
}
/*
* 将当前beanName放入到"正在创建中的单实例集合(Set)",放入成功,
* 表示没有产生循环依赖,失败则产生循环依赖,会抛出异常
* 举个例子:构造方法参数依赖
* A -> B B -> A
* 1.加载A,根据A的构造方法,想要去实例化A对象,但是发现A的构造方法
* 有一个参数是B(在这之前,已经向集合中添加了A)
* 2.因为A的构造方法依赖B,所以触发加载B的逻辑
* 3.加载B,根据B的构造方法去实例化B,但是发现B的构造方法有一个参数是
* A(在这之前,已经向这个集合中添加了(A, B))
* 4.因为B的构造方法依赖A,所以再次触发加载A的逻辑
* 5.再次来到这个getSingleton方法里,调用
* beforeSingletonCreation(A),因为创建中集合已经有A了,所以添加失
* 败,抛出异常
*/
beforeSingletonCreation(beanName);
//创建单实例是否成功的标志。
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
/*
* 这里调用了singletonFactory.getObject()方法,因为传入的实现类
* 调用的是createBean()方法,所以这里会去创建对象。
* 一般情况这里都会创建成功
*/
singletonObject = singletonFactory.getObject();
//创建成功标志位置为true
newSingleton = true;
}
catch (IllegalStateException ex) {
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。
afterSingletonCreation(beanName);
}
//正常逻辑,createBean()会创建成功,
if (newSingleton) {
//这里将二级三级缓存当前beanName的对象全部清空,然后加入一级缓存中
addSingleton(beanName, singletonObject);
}
}
//最终返回。
return singletonObject;
}
}
7.2addSingletion()
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
//将当前bean实例加入一级缓存
this.singletonObjects.put(beanName, singletonObject);
//将当前的bean实例从三级缓存干掉
this.singletonFactories.remove(beanName);
//将当前的beanName对应的实例从二级缓存干掉。
this.earlySingletonObjects.remove(beanName);
//加入已注册单实例集合(Set)中
this.registeredSingletons.add(beanName);
}
}
7.3beforeSingletonCreation()
protected void beforeSingletonCreation(String beanName) {
/*
* 条件一一般都成立
* 条件二:singletonsCurrentlyInCreation(Set集合),表示当前beanName的单实例
* 对象正在创建中添加set失败,直接抛出异常。
*/
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
7.4createBean()
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
//加载bd内部的class到JVM中,并返回Class对象
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
//这里保证bd内部的beanClass(Object)一定不为NULL。
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
//重新构造一个bd
mbdToUse = new RootBeanDefinition(mbd);
//将Class设置进去
mbdToUse.setBeanClass(resolvedClass);
}
// 处理方法重写。。。
try {
mbdToUse.prepareMethodOverrides();
}
try {
/*
* 这里通过后处理器,在这一步返回一个代理实例对象,注意,这里的代理对象不是AOP逻辑实现的地方。
* 这里也并非是BeanPostPressor的执行过程(BPP是在Bean对象已经被创建出来后执行的,这里Bean还没有被创建)
* */
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
//如果通过代理创建出来了对象,这里直接返回了。
if (bean != null) {
return bean;
}
}
try {
/*
* 核心方法doCreateBean(), 创建bean实例,进行依赖注入,执行生命周期方法
* 等都是在这个方法中完成的,下期我们将主要讲解此方法。
* */
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
//打印日志
}
//最终返回
return beanInstance;
}
}
7.5总结第七环节创建单实例Bean的流程
- 对象的创建是在createBean()方法完成的。
- 进入getSingleton()中,会先尝试将当前要创建对象的beanName放到一个Set集合中
(表示当前beanName对应的对象正在处于正在创建状态)
,放入失败说明发生了循环依赖(走到这里说明一二三缓存中都没有当前beanName对应的对象 (参考第二环节) ),直接抛出异常。 - 然后调用createBean()方法开始创建对象,在寻找到合适的构造器后,然后反射创建对象(还未执行后续的生命周期方法),然后就会将这个早期对象包装成一个ObjectFactory放到三级缓存中(这里后续如果在创建其他对象的过程中调用了getBean(当前对象)的逻辑,那么就会从三级缓存中拿到当前的早期对象,然后将三级缓存中的当前对象删除并放到二级缓存中去。)
- 后续执行属性注入、init-method等生命周期方法对这个对象进行完整的初始化。
- createBean()方法执行成功后(一个完整的对象诞生)会将当前的beanName从(正在创建的对象)Set集合中干掉,
然后将当前对象(已经执行了完整生命周期)放到一级缓存中,然后将二级三级缓存中的当前beanName的对象全部干掉
- 判断创建的bean是否需要进行类型转换,最终返回创建的对象。