死磕spring源码:2.spring如何获取bean

5 篇文章 0 订阅

前言(本章节主要详细介绍了单例bean,理解了这个就理解了原型bean)

上一篇文章,我们已经总结过spring解析注册bean的过程了。这一篇,将会面临一个更大的挑战,因为获取bean的流程远远要比解析注册bean的流程要复杂。解析注册bean就是将XML中bean节点转换成BeanDefinition放到BeanFactory维护的一个Map集合中,但是获取该怎么获取呢?怎么将BeanDefinition转换成bean的实例?怎么解决循环依赖的问题?带着这些问题,我们来仔细的分析以下spring的源代码。

整体流程分析

使用spring获取bean的代码很简单,通过BeanFactory的getBean方法即可,但是这个背后的获取机制确实很复杂的,首先我们打开源码看看这个getBean的方法,当然getBean有很多个重载方法,我们这里先介绍一种,即通过beanName来获取bean,其他的重载方法大同小异,感兴趣的需要大家自行钻研,通过代码可以看到最终所有的重载方法都会调用protected T doGetBean(String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly)这个方法,这个方法特别长,但为了学习必须要有耐心

protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
	//转换beanName,因为bean有可能有别名,或者是FactoryBean可以用&开头获取到原始的FactoryBean
	String beanName = this.transformedBeanName(name);
	//从缓存种获取单例bean
	Object sharedInstance = this.getSingleton(beanName);
	Object bean;
	if (sharedInstance != null && args == null) {
		if (this.logger.isTraceEnabled()) {
			if (this.isSingletonCurrentlyInCreation(beanName)) {
				this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
			} else {
				this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
			}
		}
		//如果从缓存中获取到了单例bean,则将其转换成对应的bean实例,因为从缓存中取出的有可能并不是bean实例需要做一次转换才可以使用
		bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
	} else {
		if (this.isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);                        
		}
		//如果当前的BeanFactory没有找到这个bean,那么递归查找ParentFactoryBean
		BeanFactory parentBeanFactory = this.getParentBeanFactory();
		if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
			String nameToLookup = this.originalBeanName(name);
			if (parentBeanFactory instanceof AbstractBeanFactory) {
				return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
			}
			if (args != null) {
				return parentBeanFactory.getBean(nameToLookup, args);
			}
			if (requiredType != null) {
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
			return parentBeanFactory.getBean(nameToLookup);
		}
		if (!typeCheckOnly) {
			//标记该bean已经创建
			this.markBeanAsCreated(beanName);
		}
		try {
			//将BeanDefinition转换成RootBeanDefinition
			RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
			this.checkMergedBeanDefinition(mbd, beanName, args);
			//获取依赖
			String[] dependsOn = mbd.getDependsOn();
			String[] var11;
			if (dependsOn != null) {
				var11 = dependsOn;
				int var12 = dependsOn.length;
				//编译依赖,并依次对依赖进行实例化
				for(int var13 = 0; var13 < var12; ++var13) {
					String dep = var11[var13];
					if (this.isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					this.registerDependentBean(dep, beanName);
					try {
						this.getBean(dep);
					} catch (NoSuchBeanDefinitionException var24) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
					}
				}
			}
			//创建单例bean
			if (mbd.isSingleton()) {
				sharedInstance = this.getSingleton(beanName, () -> {
					try {
						return this.createBean(beanName, mbd, args);
					} catch (BeansException var5) {
						this.destroySingleton(beanName);
						throw var5;
					}
				});
				bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			} else if (mbd.isPrototype()) {//创建原型bean
				var11 = null;

				Object prototypeInstance;
				try {
					this.beforePrototypeCreation(beanName);
					prototypeInstance = this.createBean(beanName, mbd, args);
				} finally {
					this.afterPrototypeCreation(beanName);
				}

				bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			} else {//按照指定的scope创建bean
				String scopeName = mbd.getScope();
				Scope 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, () -> {
						this.beforePrototypeCreation(beanName);

						Object var4;
						try {
							var4 = this.createBean(beanName, mbd, args);
						} finally {
							this.afterPrototypeCreation(beanName);
						}
						return var4;
					});
					bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				} catch (IllegalStateException var23) {
					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", var23);
				}
			}
		} catch (BeansException var26) {
			this.cleanupAfterBeanCreationFailure(beanName);
			throw var26;
		}
	}
	//检查bean的类型是否符合要求
	if (requiredType != null && !requiredType.isInstance(bean)) {
		try {
			T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
			if (convertedBean == null) {
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			} else {
				return convertedBean;
			}
		} catch (TypeMismatchException var25) {
			if (this.logger.isTraceEnabled()) {
				this.logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25);
			}

			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		}
	} else {
		return bean;
	}
}

光看代码可能大家还是有点迷糊,因为这个代码确实很长,理解起来也很困难。为了让大家能有一个更加深刻的认识,对照着代码,画了这么一个流程图,这样可能就很容易理解
spring获取bean的基本流程

重点流程分析

转换beanName的名称

为什么需要这样的一步呢,我们在配置bean的时候可以配置bean的id,name等属性,可以通过id或者name属性来获取这个bean,id属性是唯一的,但是name属性不是唯一的,在做bean解析的时候spring就做过bean别名的映射,具体的映射规则大家可以找一下源码自行了解
在这里插入图片描述
通过debug可以看到这个方法将zhangsan转换成userZ
在这里插入图片描述
还有一种情况,那就是FactoryBean,通过在beanName前边加&符号就可以获取到这个FactoryBean对象本身,而不是bean实例
在这里插入图片描述
这个方法总结起来来说就是将bean的其他别名转换成最终的beanName。

从缓存中获取单例bean

有代码中可以看到,spring从调用了this.getSingleton(beanName)这个方法来从缓存中获取单例bean,最终这个方法会跳转到protected Object getSingleton(String beanName, boolean allowEarlyReference)这个方法中

 protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	Object singletonObject = this.singletonObjects.get(beanName);
	if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
		synchronized(this.singletonObjects) {
			singletonObject = this.earlySingletonObjects.get(beanName);
			if (singletonObject == null && allowEarlyReference) {
				ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
				if (singletonFactory != null) {
					singletonObject = singletonFactory.getObject();
					this.earlySingletonObjects.put(beanName, singletonObject);
					this.singletonFactories.remove(beanName);
				}
			}
		}
	}
	return singletonObject;
}

这段代码里我们发现了几个集合,这几个集合具体有什么作用呢?

  1. singletonObjects:毫无疑问,这个集合就是spring容器中单例bean的缓存集合
  2. earlySingletonObjects:这个集合非常重要,它允许bean在创建之前暴漏ObjectFactory,通过这种方式可解决单例bean的循环依赖问题
  3. singletonFactories:这个集合就存放着bean的ObjectFactory,用于保存bean和ObjectFactory之间的关系。
    从缓存中获取单例bean的基本流程

如何将bean转换成bean的实例(主要是针对FactoryBean的特殊处理)

想必大家都很迷糊,为什么要把bean转换成bean实例,我们不是已经获取到bean为什么还要做转换?如果说是普通的bean当然可以直接返回,但是如果是FactoryBean呢?因为在XML配置中我们的class写的是FactoryBean,但是我们最终需要的不是FactoryBean,而是它代理的bean,大家可以看到在getBean这个方法里,最后都会调用getObjectForBeanInstance这个方法,这个方法的核心就是针对于FactoryBean的处理,接下来仔细看看源代码

protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
	if (BeanFactoryUtils.isFactoryDereference(name)) {
		if (beanInstance instanceof NullBean) {
			return beanInstance;
		}
		//如果name以&开头,而却beanInstance不是FactoryBean的实现类,那么直接会抛异常
		if (!(beanInstance instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
		}
	}
	//如果name不以&开头,而却beanInstance不是FactoryBean的实现类,那么这就要调用FactoryBean的getObject方法来获取bean实例对象
	if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
		Object object = null;
		if (mbd == null) {
			object = this.getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			FactoryBean<?> factory = (FactoryBean)beanInstance;
			if (mbd == null && this.containsBeanDefinition(beanName)) {
				mbd = this.getMergedLocalBeanDefinition(beanName);
			}
			boolean synthetic = mbd != null && mbd.isSynthetic();
			object = this.getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	} else {//这种普通的bean就不用处理了
		return beanInstance;
	}
}

上述代码关键地方已经做了注释,可以看到这段代码最终跳转到了this.getObjectFromFactoryBean(factory, beanName, !synthetic)这个方法中了,且追踪进去看看

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
	if (factory.isSingleton() && this.containsSingleton(beanName)) {
		synchronized(this.getSingletonMutex()) {
			//先从缓存中获取bean,缓存中没有获取到才会做处理
			Object object = this.factoryBeanObjectCache.get(beanName);
			if (object == null) {
				//核心的方法,最终bean的实例通过这个方法返回
				object = this.doGetObjectFromFactoryBean(factory, beanName);
				Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
				if (alreadyThere != null) {
					object = alreadyThere;
				} else {
					if (shouldPostProcess) {
						if (this.isSingletonCurrentlyInCreation(beanName)) {
							return object;
						}
						this.beforeSingletonCreation(beanName);
						try {
							//后置处理器
							object = this.postProcessObjectFromFactoryBean(object, beanName);
						} catch (Throwable var14) {
							throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", var14);
						} finally {
							this.afterSingletonCreation(beanName);
						}
					}
					if (this.containsSingleton(beanName)) {
						this.factoryBeanObjectCache.put(beanName, object);
					}
				}
			}
			return object;
		}
	} else {
		Object object = this.doGetObjectFromFactoryBean(factory, beanName);
		if (shouldPostProcess) {
			try {
				object = this.postProcessObjectFromFactoryBean(object, beanName);
			} catch (Throwable var17) {
				throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", var17);
			}
		}
		return object;
	}
}

这段代码的逻辑也很简单,首先判断这个bean是否为单例bean,如果是单例bean则在获取到bean实例之后,会将bean存入缓存中,非单例bean则不需要这个操作,这段代码有两个重要的方法doGetObjectFromFactoryBean方法

private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
	Object object;
	...
	//权限检查判断
	if (System.getSecurityManager() != null) {
		AccessControlContext acc = this.getAccessControlContext();
		try {
			//调用FactoryBean的getObject方法
			object = AccessController.doPrivileged(factory::getObject, acc);
		} catch (PrivilegedActionException var6) {
			throw var6.getException();
		}
	} else {
		//调用FactoryBean的getObject方法
		object = factory.getObject();
	}
	...
	return object;
}

可以看到最终在这里调用了factory.getObject(),这样就可以获取到FactoryBean代理的最终的bean实例。postProcessObjectFromFactoryBean需要关注一下,这个是bean的后置处理方法,后续会重点讲解。
总结一句,通过FactoryBean来获取bean实例对象,最终是通过FactoryBean实现类的getObject方法来获取的,so easy,但是代码确实是一大堆,哈哈。

创建单例bean

前边分析过,spring首先会从缓存中加载单例bean,如果没获取到这个bean,那么spring会一次从parentBeanFactory中加载,如果最终还是没获取到,那么就表明这个bean还没创建,那么就要开始创建这个单例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);
            if (singletonObject == null) {
                ...
				//标记该bean正在创建
                this.beforeSingletonCreation(beanName);
                ...
                try {
					//调用ObjectFactory的getObject方法
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                } catch (IllegalStateException var16) {
                    ...
                } catch (BeanCreationException var17) {
                    ...
                    throw ex;
                } finally {
                    ...
                    this.afterSingletonCreation(beanName);
                }
                if (newSingleton) {
					//新创建的单例bean会存入缓存中,下一次再使用这个bean就不会再创建了
                    this.addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }

这段代码最核心的地方在这一句 singletonFactory.getObject(),单例bean就是通过这个方法创建。通过分析可以发现,无论单例bean,还是普通的bean,都是调用了AbstractBeanFactory.getObject方法,唯一不同点就是单例bean要做缓存,单例bean会解决循环依赖问题。

创建bean的终极奥义

通过以上的代码追踪,发现创建***新的bean最终就是在AbstractBeanFactory.getObject方法中诞生的***,而AbstractBeanFactory是一个抽象类,所以最终的实现方法在AbstractAutowireCapableBeanFactory中

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
	if (this.logger.isTraceEnabled()) {
		this.logger.trace("Creating instance of bean '" + beanName + "'");
	}
	RootBeanDefinition mbdToUse = mbd;
	Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		//做一次转换
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}
	try {
		//这个方法用于替换bean的方法的,主要是spring的bean下边可以定义lookup-method和replace-method
		mbdToUse.prepareMethodOverrides();
	} catch (BeanDefinitionValidationException var9) {
		throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9);
	}
	Object beanInstance;
	try {
		//这个是bean的前置处理器,这玩意儿就是以假乱真,可以用代理bean来替换真正的bean
		beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
		if (beanInstance != null) {
			return beanInstance;
		}
	} catch (Throwable var10) {
		throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
	}
	try {
		//真正创建bean的地方
		beanInstance = this.doCreateBean(beanName, mbdToUse, args);
		...
		return beanInstance;
	} catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
		throw var7;
	} catch (Throwable var8) {
		throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
	}
}

代码特别长,光看代码大家脑袋估计要糊掉了,所以必须要提炼代码中的精华,理清楚整体的流程,才能更好的理解spring框架的核心原理。整理一张流程图,让大家看得可以更仔细一点
在这里插入图片描述

获取bean的class

功能很简单,代码也很简单,this.resolveBeanClass(mbd, beanName, new Class[0]),就是从className中解析出class。

处理lookup-method和replace-method

这个很少使用,大多数人可能也不是太了解,这里也不做详细解读,需要详细了解可以移步https://blog.csdn.net/qq_22912803/article/deta
ils/52503914

自定义InstantiationAwareBeanPostProcessor处理器创建bean

这一步可谓是一个骚操作,用好了绝对是妙笔生辉。它的具体作用是什么呢?就是通过这个来代替spring,根据自己的实际需要来创建bean,应用场景可以说是很多啊,这个需要大家自己琢磨,这里不做具体的详细描述,后边有功夫再详细讨论这个玩意儿。下边是spring代码的具体处理机制

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
	Object bean = null;
	if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
		//判断是否有自定义的处理器
		if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
			Class<?> targetType = this.determineTargetType(beanName, mbd);
			if (targetType != null) {
				//调用前置处理器,如果前置处理器返回了自定义的bean实例,则继续调用后置处理器
				bean = this.applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
				if (bean != null) {
					//调用后置处理器
					bean = this.applyBeanPostProcessorsAfterInitialization(bean, beanName);
				}
			}
		}
		mbd.beforeInstantiationResolved = bean != null;
	}
	return bean;
}

注释已经给出详细步骤了,大家一定要仔细琢磨哈。

spring使用常规方式创建bean

如果没有自定义的处理器,或者自定义处理器返回null,那么spring就会通过常规的方式来创建备案了,翻到上边的代码,真正通用方式创建bean是调用了doCreateBean方法

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		//根据不同的策略,构造器模式,工厂模式等等来创建实例
		instanceWrapper = this.createBeanInstance(beanName, mbd, args);
	}
	Object bean = instanceWrapper.getWrappedInstance();
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}
	synchronized(mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
				//应用对应的MergedBeanDefinitionPostProcessor处理器
				this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			} catch (Throwable var17) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
			}
			mbd.postProcessed = true;
		}
	}
	//是否允许提前曝光:单例&&允许循环依赖&&该实例正在创建中
	boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
	if (earlySingletonExposure) {
		...
		//通过Object来提前暴露bean,解决spring单例bean循环依赖的问题
		this.addSingletonFactory(beanName, () -> {return this.getEarlyBeanReference(beanName, mbd, bean);});
	}
	Object exposedObject = bean;
	try {
		//构建bean,初始化bean的核心流程
		this.populateBean(beanName, mbd, instanceWrapper);
		//调用bean的相初始化关方法
		exposedObject = this.initializeBean(beanName, exposedObject, mbd);
	} catch (Throwable var18) {
		if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
			throw (BeanCreationException)var18;
		}
		throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
	}
	if (earlySingletonExposure) {
		Object earlySingletonReference = this.getSingleton(beanName, false);
		if (earlySingletonReference != null) {
			if (exposedObject == bean) {
				exposedObject = earlySingletonReference;
			} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
				String[] dependentBeans = this.getDependentBeans(beanName);
				Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
				String[] var12 = dependentBeans;
				int var13 = dependentBeans.length;

				for(int var14 = 0; var14 < var13; ++var14) {
					String dependentBean = var12[var14];
					if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
						actualDependentBeans.add(dependentBean);
					}
				}
				if (!actualDependentBeans.isEmpty()) {
					throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
				}
			}
		}
	}
	try {
		this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
		return exposedObject;
	} catch (BeanDefinitionValidationException var16) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
	}
}

这又是一个超长的流程,看起来脑阔疼,这里再整理一张流程图,注意这张图是上一小节的spring使用通用方式创建bean的流程
在这里插入图片描述
看了这张图是不是很好理解了,当然大家需要具体的针对代码,以及我贴出的主要代码上的注释来阅读代码再加以理解,才能捋顺这个思路。当然,大家看完可能觉得还是没有理解循环依赖的问题,没有关系,本章中重要的是理清获取一个bean的基本流程,至于单例的循环依赖,我们下一章节再来详细介绍怎么解决循环依赖的问题。

注册单例bean到spring容器中

上边已经走完了整个创建bean的流程,接下来就是将bean塞到spring容器中,上一篇博客已经介绍过了,spring容器是什么,实质上就是一个map,把生成好的对象放入到map中,so easy。

protected void addSingleton(String beanName, Object singletonObject) {
        synchronized(this.singletonObjects) {
        	//添加到单例bean集合中
            this.singletonObjects.put(beanName, singletonObject);
            //移除该ObjectFactory
            this.singletonFactories.remove(beanName);
            //提前暴露的信息也删除掉,这个用于bean还未创建完成的时候解决循环依赖用的,现在bean已经创建完成了,所以也就不需要了。
            this.earlySingletonObjects.remove(beanName);
            //已注册的单例bean也加上
            this.registeredSingletons.add(beanName);
        }
    }

然后把创建的bean调用getObjectForBeanInstance进行一个转换操作即可,这个方便前文介绍过。当下一次再调用这个bean的时候,如果深似单例bean,则直接再缓存中获取,以为已经创建过了,现在由spring容器维护着。如果是原型bean,那就再走一遍创建bean的流程。至此,获取bean的过程终于结束了,真不容易鸭,哈哈哈。

反思与总结

ObjectFactory与BeanFactory以及FactoryBean有什么关系?

着名字好类似呀?三个长得特别像,后两者上一篇文章已经详细介绍过了,那么OnjectFactory有什么用呢?先看看它的定义

@FunctionalInterface
public interface ObjectFactory<T> {
    T getObject() throws BeansException;
}

是一个函数式接口,定义了一个getObject的方法,那么它的应用场景有哪些呢?通过上边的分析,我们发现很多地方用到了这个玩意儿,例如

sharedInstance = this.getSingleton(beanName, () -> {
	try {
		return this.createBean(beanName, mbd, args);
	} catch (BeansException var5) {
		this.destroySingleton(beanName);
		throw var5;
	}
});

还有就是作为内部扩展类的实现接口。总结来说,就是定义一个创建bean的函数式接口,以及可扩展的接口。函数式式java8引入的新特性,是一个十分优美的语法糖,大家有空可以研究一下函数式接口的特性,非常的好使。如果大家由。不同的见解,可以在评论列表中讨论一下哦

bean生命周期的理解

在这里插入图片描述
这是网上copy的图,想必通过上边的源码分析,大家已经能够找到这个方法的位置了,大家不妨自己仔细找找看。

bean的循环依赖式如何解决的

这个问题是常见的面试题,也是spring核心精髓之一。首先来说,原型bean和构造器里的循环依赖是无法解决的,只能解决单例bean属性上的循环依赖,至于解决的下一篇文章做一下详细的分析。

最后,大家看完源码一定要回头好好思索整理一下,看完一定要能学到,能对这个框架有一个整体上的认识,这样才能有所提高,否则看完一遍也没有任何益处。

单例bean和原型bean的区别是什么

1.单例bean即scope设置为singleton的bean,spring默认也是单例bean,这也是我们使用比较多的,它只会在spring容器中创建一次,并且spring内存在一个集合来维护这个bean对象。
2.原型bean即scope设置为property的bean,这个bean每次获取都要重新创建,srping内部不会维护这个bean。
3.两者解析,创建流程基本类似,唯一不同的就是spring缓存只会存储单例bean
4.spring不会解决原型bean的循环依赖,只会处理单例bean的循环依赖问题。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值