单例Bean的创建流程
创始人
2024-06-03 12:29:38
0

简要介绍

bean的创建,需要经过查找,创建,注入,实例化三阶段

finishBeanFactoryInitialization

前言提到,refresh方法执行了finishBeanFactoryInitialization,这个方法便是完成了bean的创建与初始化。
每一个最后都会走向doGetBean

doGetBean

doGetBean是用于返回bean的方法,如果bean不存在,还会调用其内部的doCreateBean完成bean的创建

protected  T doGetBean(final String name, @Nullable final Class requiredType,@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {final String beanName = transformedBeanName(name);Object bean;// 从缓存池中获取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 + "'");}}//这是为了防止beanFactory套用beanFactory,这里提供了递归使用getObject方法,从而获取最终beanbean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {// 空的,要不是没创建过的单例bean,要不是原型bean,并且这个bean一定不能是if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}// 打上已经创建的标记,防止对象反复创建if (!typeCheckOnly) {markBeanAsCreated(beanName);}try {final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);// 优先完成@DependOn注解指定的类的bean的创建与获取String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dep : dependsOn) {if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}// 这里面实际上就是增加这个bean依赖了哪个bean,和哪个被依赖的bean被这个bean依赖的双重引用registerDependentBean(dep, beanName);try {getBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}// 如果是单例if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);}catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.destroySingleton(beanName);throw ex;}});// 也是递归向里调用,直到返回的不是factoryBeanbean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}else if (mbd.isPrototype()) {// It's a prototype -> create a new instance.Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}else {String scopeName = mbd.getScope();if (!StringUtils.hasLength(scopeName)) {throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");}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, () -> {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}});bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {throw new ScopeNotActiveException(beanName, scopeName, ex);}}}catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName);throw ex;}}// 检查一下是否需要格式转换,比如XML的字符串转化为对象的类型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());}}return (T) bean;
}

试图直接返回

这是singletonObject的逻辑,如果一级有,直接返回,如果一级没有,那么就可能涉及修改操作,所以提前完成上锁。为什么锁的是一级缓存而不是二级缓存呢,正是因为三级缓存在完成调用之后会将对象加入二级缓存,然后其它有着相同需求正在等待的线程就可以直接从二级缓存取出对象,而不需要双重检验机制了。
然后进行二级和三级缓存的查找。如果是在三级缓存中找到的,那么就会调用其中getObject方法,这个方法在单例中就是getReference方法

//三级缓存,保存工厂
private final Map> singletonFactories = new HashMap<>(16);
//二级缓存,保存工厂创建的对象
private final Map earlySingletonObjects = new HashMap<>(16);
//一级缓存,保存所有完成创建的对象
private final Map singletonObjects = new ConcurrentHashMap<>(256);protected Object getSingleton(String beanName, boolean allowEarlyReference) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {synchronized (this.singletonObjects) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {ObjectFactory singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}return singletonObject;
}

doCreateBean方法的“AOP”

以下对源码的验证部分进行大量删除,只剩下主干
这个方法在调用doCreateBean之前,会将其加入一个set表示正在创建,在调用doCreateBean正常结束之后会将其删除,并完成一级缓存的添加和二三级缓存的清除

public Object getSingleton(String beanName, ObjectFactory singletonFactory) {synchronized (this.singletonObjects) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {// 添加进入singletonsCurrentlyInCreation,表示是正在创建的单例对象beforeSingletonCreation(beanName);boolean newSingleton = false;try {//这里才是真正调用了 doCreateBeansingletonObject = singletonFactory.getObject();// 如果走到这里说明初始化成功了newSingleton = true;} finally {if (recordSuppressedExceptions) {this.suppressedExceptions = null;}// 从singletonsCurrentlyInCreation中移除afterSingletonCreation(beanName);}// 如果初始化成功了,那么加入一级缓存if (newSingleton) {addSingleton(beanName, singletonObject);}}return singletonObject;}
}protected void addSingleton(String beanName, Object singletonObject) {// 将这个对象加入一级缓存,从二三级删除,并标记为已经注册synchronized (this.singletonObjects) {this.singletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}
}

doCreateBean的实体

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}// 实例化beanif (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}final Object bean = instanceWrapper.getWrappedInstance();Class beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}// 可以理解为走了一个beanPostProcessorssynchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);mbd.postProcessed = true;}}// 如果设置了属性,并且是正在创建的单例bean,就会添加单例工厂.boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.Object exposedObject = bean;// 注入属性populateBean(beanName, mbd, instanceWrapper);// 初始化beanexposedObject = initializeBean(beanName, exposedObject, mbd);// 如果支持循环引用,并且存在该对象,这是为了保证返回的一定是代理对象if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;}}}// 如果需要回调destory方法,会放入destroybeans,这样在销毁的时候就会从destroybeans剔除并回调registerDisposableBeanIfNecessary(beanName, bean, mbd);return exposedObject;
}

关联的属性这时候注入

属性注入的时候对Autowire注解进行了注入

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();if (hasInstAwareBpps) {if (pvs == null) {pvs = mbd.getPropertyValues();}// 使用AutowiredAnnotationBeanPostProcessor,将类中所有Autowired注解都提取出来,并在postProcessPropertyValues逐一完成注入for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {return;}}pvs = pvsToUse;}}// 把property数组放入beanWrapper里面,便于后续使用if (pvs != null) {applyPropertyValues(beanName, mbd, bw, pvs);}
}

对于三级缓存的解释

比如A包含B,B包含A的关系,用户尝试获取A。
一开始进入A的getBean,由于缓存中不存在A,所以进入A的create方法,会生成单例工厂,并将单例工厂放入三级缓存,然后进入属性注入环节,会尝试注入B,这时陷入B的getBean。
B会标记自己是正在生成,然后进入create方法,生成单例工厂,并将单例工厂放入三级缓存,然后进入属性注入环节,会尝试注入A,这时陷入A的getBean,这时会从三级缓存中取出A的单例工厂,并且调用其getEarlyReference方法,AbstractAutoProxyCreator会将A加入AOP缓存,然后生成代理对象,并将A移出三级缓存,将其注入二级缓存,然后返回给B使用。B获取到之后会继续完成属性注入和初始化代理,然后从三级缓存中删除自己,加入一级缓存,返回代理对象B给A。
A拿到了B的代理对象,会继续完成属性注入和初始化代理,在初始化代理时候,A会检查AOP缓存,由于A会在AOP缓存里发现自己,所以直接返回。在create方法的最后,A会从二级缓存中取出A的代理,然后从二级缓存中删除A,并加入一级缓存,将A的代理返回给用户。
假设更麻烦一些,B在获取A的时候,C也在获取A,会怎样呢。由于进入二级和三级缓存都有同一把锁,比如B先进入了这把锁,那么它会先检查二级缓存是否有A,发现没有,会进入三级缓存取出A的工厂,通过A的工厂完成A的代理,再将其放入二级缓存,然后释放锁,这是C才会获取到这把锁,它会在二级缓存直接发现了A,于是直接注入,这就是二级缓存的作用。

相关内容

热门资讯

安卓13系统更新蓝牙,蓝牙功能... 你有没有发现,最近你的安卓手机好像变得不一样了?没错,就是那个神秘的安卓13系统更新,它悄悄地来到了...
安卓系统钉钉打开声音,安卓系统... 你有没有遇到过这种情况?手机里装了钉钉,可每次打开它,那声音就“嗖”地一下跳出来,吓你一跳。别急,今...
理想汽车操作系统安卓,基于安卓... 你有没有想过,一辆汽车,除了能带你去你想去的地方,还能像智能手机一样,给你带来智能化的体验呢?没错,...
安卓系统越狱还能升级吗,升级之... 你有没有想过,你的安卓手机越狱后,还能不能愉快地升级系统呢?这可是不少手机爱好者关心的大问题。今天,...
安卓系统蓝牙耳机拼多多,畅享无... 你有没有发现,最近蓝牙耳机在市场上可是火得一塌糊涂呢!尤其是安卓系统的用户,对于蓝牙耳机的要求那可是...
安卓变苹果系统桌面,桌面系统变... 你知道吗?最近有个大新闻在科技圈里炸开了锅,那就是安卓用户纷纷转向苹果系统桌面。这可不是闹着玩的,这...
鸿蒙系统怎么下安卓,鸿蒙系统下... 你有没有想过,你的手机里那个神秘的鸿蒙系统,竟然也能和安卓世界来一场亲密接触呢?没错,今天就要来揭秘...
手机安卓系统流程排行,便捷操作... 你有没有发现,现在手机的世界里,安卓系统就像是个大舞台,各种版本层出不穷,让人眼花缭乱。今天,就让我...
安卓系统左上角hd,左上角HD... 你有没有发现,每次打开安卓手机,左上角那个小小的HD标识总是默默地在那里,仿佛在诉说着什么?今天,就...
安卓系统软件文件,架构解析与功... 你有没有发现,手机里的安卓系统软件文件就像是一个神秘的宝库,里面藏着无数的宝藏?今天,就让我带你一起...
安卓系统输入法回车,探索安卓输... 你有没有发现,在使用安卓手机的时候,输入法回车键的奇妙之处?它就像是我们指尖的魔法师,轻轻一点,文字...
安卓修改系统时间的软件,轻松掌... 你有没有想过,有时候手机上的时间不对劲,是不是觉得生活节奏都被打乱了?别急,今天就来给你揭秘那些神奇...
安卓系统能改成鸿蒙吗,系统迁移... 你有没有想过,你的安卓手机能不能变成一个鸿蒙系统的“小清新”呢?这可不是天方夜谭哦,今天就来聊聊这个...
安卓机怎么从新装系统,从零开始... 亲爱的安卓手机用户们,你是否在某个瞬间突然觉得手机卡顿得像个老古董,急需给它来个“大变身”?别急,今...
安卓手机安装Linux双系统,... 你有没有想过给你的安卓手机来个变身大法?没错,就是安装Linux双系统!想象一边是流畅的安卓,一边是...
安卓系统关闭更新补丁,轻松提升... 亲爱的手机用户们,你们有没有发现,最近你的安卓手机好像有点儿“懒”了呢?更新补丁的速度明显慢了下来,...
麒麟os是不是安卓系统,揭秘与... 最近手机圈里可是热闹非凡呢!不少朋友都在问我:“麒麟OS是不是安卓系统?”这个问题可真是让人好奇,咱...
安卓系统卸载快应用,安卓系统轻... 你有没有发现,手机里的应用越来越多,有时候真的让人眼花缭乱呢?尤其是安卓系统里的那些“快应用”,虽然...
安卓14系统更新包,全新功能与... 你知道吗?最近安卓系统又来了一次大变身,那就是安卓14系统更新包!这可不是一个小打小闹的更新,而是满...
oppo安卓11.1系统新功能... 你知道吗?最近OPPO手机又来了一次大升级,安卓11.1系统的新功能简直让人眼前一亮!今天,就让我带...