上一篇文章,我们已经总结过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 doGetBean(String name, @Nullable Class 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;
}
}
光看代码可能大家还是有点迷糊,因为这个代码确实很长,理解起来也很困难。为了让大家能有一个更加深刻的认识,对照着代码,画了这么一个流程图,这样可能就很容易理解
为什么需要这样的一步呢,我们在配置bean的时候可以配置bean的id,name等属性,可以通过id或者name属性来获取这个bean,id属性是唯一的,但是name属性不是唯一的,在做bean解析的时候spring就做过bean别名的映射,具体的映射规则大家可以找一下源码自行了解
通过debug可以看到这个方法将zhangsan转换成userZ
还有一种情况,那就是FactoryBean,通过在beanName前边加&符号就可以获取到这个FactoryBean对象本身,而不是bean实例
这个方法总结起来来说就是将bean的其他别名转换成最终的beanName。
有代码中可以看到,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;
}
这段代码里我们发现了几个集合,这几个集合具体有什么作用呢?
想必大家都很迷糊,为什么要把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,但是代码确实是一大堆,哈哈。
前边分析过,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最终就是在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框架的核心原理。整理一张流程图,让大家看得可以更仔细一点
功能很简单,代码也很简单,this.resolveBeanClass(mbd, beanName, new Class[0]),就是从className中解析出class。
这个很少使用,大多数人可能也不是太了解,这里也不做详细解读,需要详细了解可以移步https://blog.csdn.net/qq_22912803/article/deta
ils/52503914
这一步可谓是一个骚操作,用好了绝对是妙笔生辉。它的具体作用是什么呢?就是通过这个来代替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;
}
注释已经给出详细步骤了,大家一定要仔细琢磨哈。
如果没有自定义的处理器,或者自定义处理器返回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 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的流程,接下来就是将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的过程终于结束了,真不容易鸭,哈哈哈。
着名字好类似呀?三个长得特别像,后两者上一篇文章已经详细介绍过了,那么OnjectFactory有什么用呢?先看看它的定义
@FunctionalInterface
public interface ObjectFactory {
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引入的新特性,是一个十分优美的语法糖,大家有空可以研究一下函数式接口的特性,非常的好使。如果大家由。不同的见解,可以在评论列表中讨论一下哦
这是网上copy的图,想必通过上边的源码分析,大家已经能够找到这个方法的位置了,大家不妨自己仔细找找看。
这个问题是常见的面试题,也是spring核心精髓之一。首先来说,原型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的循环依赖问题。