一、前言
进过前面的分析,接下来就是对面bean加载的过程,其实bean的加载加载过程远比bean的解析要复杂的很多,下面我们对下面的这行代码后面的作用为切入点。
public class MainClass {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println(context.getBean("tulingAspect"));
}
}
context.getBean("tulingAspect");在这行代码中实现了什么功能呢?我们可以快速体验一下Spring中代码是如果实现的。下面这个是我整理原理的一个代码调用流程图,可以先提前看,下面我们会对具体的某个方法的主干作用进行分析。
i1:>org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String) i2>org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean i2.1>:org.springframework.beans.factory.support.AbstractBeanFactory#transformedBeanName 转换 beanName i2.2>:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton 去缓存 中获取bean i2.3>:org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance 对 缓存中的获取的bean进行后续处理 i2.4>:org.springframework.beans.factory.support.AbstractBeanFactory#isPrototypeCurrentlyInCreation 判断原型bean的依赖注入 i2.5>:org.springframework.beans.factory.support.AbstractBeanFactory#getParentBeanFactory 检查父 容器加载bean i2.6>:org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition 将 bean定义转为RootBeanDifination i2.7>:检查bean的依赖(bean加载顺序的依赖) i2.8>:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton根据 scope 的添加来创建bean
i3>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean创建 bean的方法 i4>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean 真 正的创建bean的逻辑 i4.1>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance 调用构造函数创建对象
i4.2>:判断是否需要提早暴露对象(mbd.isSingleton() && this.allowCircularReferences && i sSingletonCurrentlyInCreation(beanName)); i4.3>org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory 暴露对象解决循环依赖 i4.4>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean 给创建的bean进行赋值 i4.5>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean对 bean进行初始化 i4.5.1>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods 调用XXAware接口 i4.5.2>applyBeanPostProcessorsBeforeInitialization 调用bean的后置处理器进行对处理
i4.5.2>applyBeanPostProcessorsBeforeInitialization 调用bean的后置处理器进行对处理
i4.5.3>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods 对象的初始化方法 i4.5.3.1>:org.springframework.beans.factory.InitializingBean#afterPropertiesSet 调用 InitializingBean的方法
i4.5.3.2>:String initMethodName = mbd.getInitMethodName(); 自定义的初始化方法 i5>:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton 把创建好的实 例化好的bean加载缓存中 i6>:org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance对创建的 bean进行后续的加工
以上就是getBean大体的调用过程,下面将跟着这些步骤进行源码的学习。
i1:getBean
@Override
public Object getBean(String name) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(name);
}
i2:doGetBean
这个方法很长,让我们具体来看着他具体是做了那些事情,这里给大家提一点学习源码的建议,看spring源码,看不懂就先跳,有些太过复杂的可以知道这行代码是干嘛的就行,可以先把大体的流程先看完,然后学习源码本身就是一件很枯燥很需要精力的事情,我们需要自己多看几遍然后自己调试几遍。
- 转换对应的beanName,这里或许很多人不理解,传进来的name不就是beanName么?其实传进来的有可能是别名或者是我们的BeanFactory,所以需要进行一系列的解析,其中解析包括以下内容,(1)去除BeanFactory的修饰符(在我Spring源码分析(1)之常见底层核心注解_jokeMqc的博客-CSDN博客 已经有介绍对应的用法了)(2)去指定的alias获取最终表示的beanName。
- 尝试去缓存中加载单例,这里就是为了解决循环依赖的关键代码,本节课讲完bean的加载过程会介绍spring是如果解决循环依赖的,要记得我们单例bean在容器中只会被实例化一次,后续在创建bean就直接从单例缓存池中去获取了,这里只是尝试去获取。这里为了解决循环依赖问题,在对象刚刚创建好的时候(还没有进行属性赋值),就会将创建bean的ObjectFactory提早的暴露到缓存中去,一旦下一个bean创建的时候需要上一个bean那直接就从缓存里面去获取就行了。(后面会着重将这一个)
- bean的实例化,如果我们从缓存中获取得到bean,我们只是获取得到bean的原始状态,不一定是我们最终需要的bean,需要getObjectForBeanInstance方法中如果bean没有实例化则在这里进行实例化.
- 对原型依赖的检查,为什么原型对象解决不了循环依赖,这里就说明了,我们的ioc容器并不会对原型对象进行缓存,而是获取一次则创建一次bean,isPrototypeCurrentlyInCreation是检查如果A中有B的属性,B中有A的属性,那么当依赖注入的时候,此时就会有A还没有创建完,然后需要去创建B,继而又要创建A,这个时候就会抛出异常了。
- 检测parentFactory,其实这里代码的意思很简单,如果当前的bean存在父容器并且当前容器找不到对应的bean定义,那么就去父容器中进行加载。
- 合并父类属性(下面也会有具体的介绍)
- 寻找依赖,就是我们在bean标注的depends-on,但是需要注意的一点就是如果A depends-on B,B depends-on A这个就会抛异常的
- 针对不同的scope进行bean的创建
- 类型转换,到这里其实整个bean的加载过程已经结束了。
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
/**
* 转换对应的beanName,或许大家有疑问,传进来的name 不就是beanName么?
* 传进来的有可能是别名,也有可能是FactoryBean
* 1)首先去除factoryBean的修饰符,比如name="&instA" -----> instA
* 2)取指定的alias所表示的最终的beanName,比如传入的是别名ia指向为instA的bean,那么返回的是instA
**/
final String beanName = transformedBeanName(name);
Object bean;
/**
* 设计的精髓
* 检查实例缓存中对象工厂缓存中是否包含对象(从这里返回的可能是实例化好的,也有可能没有实例化好的)
* 为什么要有这段代码?
* 因为单实例bean实例化可能存在循环依赖问题,而为了解决循环依赖问题,在对象刚刚创建好(还没有属性赋值)
* 的时候,就会把对象包装成一个对象工厂暴露出去(加入对象工厂缓存中),一旦下一个bean需要依赖它,就直接从缓存中获取
**/
// 直接从缓存中去取或从对象工厂缓存去取
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
/**
* 若从缓存中获取的sharedInstance是原始的bean(属性还没有进行实例化,那么在这里进行处理)
**/
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
/**
* 为什么Spring对原型对象无法解决循环依赖问题?
* 因为Spring ioc容器并不会缓存原型对象,所以无法提前暴露对象,每次调用都会创建新的对象
*
* 比如在对象A存在属性对象B,对象B存在属性对象A,在创建A的时候,检查依赖对象B,就会创建对象B
* 创建B的时候又发现依赖对象A,由于是原型对象,ioc容器不会对原型对象进行缓存,所以无法解决循环依赖问题
**/
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 获取父容器
BeanFactory parentBeanFactory = getParentBeanFactory();
// 如果beanDefinitionMap以及所有加载的bean不包含 本次加载的bean则从父容器中去加载
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
// 从父容器中递归查询
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
// 这里不是做类型检查,而是创建bean,这里需要标记一下
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
/**
* 合并父BeanDefinition和子BeanDefinition,后面会单独分析这个方法
**/
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 用来处理bean的加载顺序,比如要在创建instA的情况下要先创建instrB
/**
* <bean id="beanA" class="beanA" depends-on="beanB">
* <bean id="beanB" class="beanA" depends-on="beanA">
* 创建A之前需要创建B,创建B之前需要创建A就会抛出异常
**/
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 + "'");
}
// 注册依赖
registerDependentBean(dep, beanName);
try {
// 有限创建依赖对象
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 创建bean,单例
if (mbd.isSingleton()) {
// 创建单例bean
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
// 在getSingleton方法中进行回调的
@Override
public Object getObject() throws BeansException {
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;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 创建非单例的bean
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();
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, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
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;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
2.1 缓存中获取单例bean
前面介绍过了,我们的单例bean只会被容器创建一次,之后获取都是去缓存中获取。这个方法涉及到循环依赖的解决,他首先会从singletonObjects中去获取实例,如果获取不到并且当前的bean正在创建中再从earlySingletonObjects中去获取,如果还再获取不到则从singletonFactories中去获取,然后调用这个ObjectFactory的getObject()来创建bean,并放到earlySingletonObjects中
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 去缓存map中获取已经实例化的对象
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 != NULL_OBJECT ? singletonObject : null);
}
2.2从bean的实例中去获取对象
在上面的源码分析中可以看得到,在bean的整个生命周期里面,getObjectForInstance()出现的频率很高,无论是从缓存中获取的bean还是根据scope策略加载的bean,总之,我们获取得到的bean第一步就是调用这个方法来进行检测,其实就是检查当前的bean是否是FactoryBean类型的bean,如果是,那么就需要调用该bean对应的factoryBean实例中的getObject()方法来返回对应的对象。
/**
* 在bean的整个声明周期中,getObjectForBeanInstance方法是频繁使用的方法,
* 无论是从缓存中获取出来的bean,还是根据scope创建出来的bean,都要通过该方法进行检查
* 检查当前的bean是否是factoryBean,如果是则调用该对象的getObject()方法来返回我们需要的bean对象
**/
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
// 判断该beanName是否以&开头但是又不是factoryBean类型,则抛异常
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
/**
* 现在我们有了这个bean,他有可能是普通的bean也有可能是factoryBean
* 1)如果是工厂bean,我们使用他来创建实例,当如果我们想要获取的是factoryBean的实例
* 并非是工厂bean的getObject()对应的bean
**/
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
// 加载factoryBean
Object object = null;
if (mbd == null) {
/**
* 如果mbd为空,则从缓存中加载bean,FactoryBean加载的单例bean会被缓存在
* factoryBeanObjectCache集合中,不用每次都创建
**/
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// 进过前面的判断,程序走到这一步可以保证此时的bean肯定是factoryBean,所以可以进行类型转换
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// 如果mbd为空,并且包含有该beanName的BeanDefinition
if (mbd == null && containsBeanDefinition(beanName)) {
// 合并我们的bean定义
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 继续调用getObjectFromFactoryBean去获取实例
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
上面的代码并没有什么重要信息,他其中最核心的代码就是getObjectFromFactoryBean,我们接下来往下看看。
2.2.1getObjectFromFactoryBean
对FactoryBean正确性,对非FactoryBean不做任何处理,然后将Factory中解析bean的工作委托给getObjectFactoryBean。
到这里我们也发现,真正做事情也就交给了doGetObjectFromFactoryBean,而且如果返回的bean是单例,那就必须要包场全局唯一,如果没有必要重复创建,可以使用缓存来提高性能,也就是说已经加载过就要记录下来以便于下次重复使用。
/**
* 核心方法
**/
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
/**
* factoryBean有单例跟非单例之分,针对不同类型的factoryBean,这里有两种处理方式
* 1.单例的factoryBean生成的bean也认为是单例bean,需放入缓存中,供后续使用
* 2.非单例的factoryBean生成的bean则不会放入到缓存中,每次都会创建新的实例
**/
if (factory.isSingleton() && containsSingleton(beanName)) {
// 加锁,防止重复创建 可以使用缓存提高性能
synchronized (getSingletonMutex()) {
// 从缓存中获取
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// 没有获取到,则使用factoryBean的getObject()方法去获取对象
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (object != null && shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
beforeSingletonCreation(beanName);
try {
// 调用ObjectFactory的后置处理器
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
}
}
return (object != NULL_OBJECT ? object : null);
}
}
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
2.2.2 doGetObjectFromFactoryBean
在这个方法中,我们可以看得到想要看得到的方法,也就是对应factory.getObject(),上面说了,如果bean为FactoryBean类型,则当提取的并不是FactoryBean,而是FactoryBean对应的getObject()方法返回的bean,而doGetObjectFromFactoryBean正是实现这个功能的,然后我们得到对应的bean并没有返回。而是继续调用postProcessObjectFromFactoryBean,然后继续看看这个方法做了什么事情。
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
return factory.getObject();
}
}, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
return object;
}
2.2.3 postProcessObjectFromFactoryBean
这里就是就是调用对应的后置处理器进行处理。
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
return applyBeanPostProcessorsAfterInitialization(object, beanName);
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
result = processor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
2.3getMergedLocalBeanDefinition将bean定义转换为RootBeanDefinition
首先回去合并的缓存中去判断当前的bean是否已经合并过,如果合并过就直接返回。
/**
* 将 bean定义转为RootBeanDifination
* <bean id="tulingParentCompent" class="com.tuling.testparentsonbean.TulingParentCompent" abstract="true">
* <property name="tulingCompent" ref="tulingCompent"></property>
* </bean>
* <bean id="tulingSonCompent" class="com.tuling.testparentsonbean.TulingSonCompent" parent="tulingParentCompent"></bean>
**/
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// 去合并的bean定义缓存中判断当前bean是否合并过
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
// 没有合并过调用合并方法
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
- 去缓存中获取bean定义信息,获取得到则直接返回。
- 如果获取不到,则判断当前的bean是否存在父类,如果不存在,则进行深克隆后然后对应的RootBeanDefinition
- 如果存在父类,首先获取得到父类的名称,然后判断父类名称跟当前beanName是否一样,如果一样,则判断父类一定是在父容器中,然后去父容器那里获取得到对应BeanDenifition。
- 最后以父BeanDenifition为基础创建RootDefinition,也就是合并后的BeanDefinition,然后用子类属性覆盖父类的属性,然后把合并好的放入到缓存中,最后返回。
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, BeanDefinition containingBd)
throws BeanDefinitionStoreException {
// 加锁,防止并发合并
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
// Check with full lock now in order to enforce the same merged instance.
// 去缓存中获取一次bean定义
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
// 尝试没有获取到
if (mbd == null) {
// 当前的bean定义是否存在父类
if (bd.getParentName() == null) { // 没有
// 转为rootBeanDefinition,进行深度克隆然后返回
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
mbd = new RootBeanDefinition(bd);
}
}
else { // 存在父类
// 首先定义一个父的bean
BeanDefinition pbd;
try {
// 获取父的bean名称
String parentBeanName = transformedBeanName(bd.getParentName());
/**
* 判断父类的名称与子类的名称是否一样,如果一样,那么判断父类一定是在父容器中
* 原因也很简单,因为底层容器是使用map缓存<beanName,BeanDefinition>,在用一个容器中
* 使用一个beanName显然是不合适的,有些人可能就会说可以这样子去映射<beanName,[bean1,bean2]>
* 这样子似乎已经解决了一对多的问题,但是也会存在问题,因为getBean(beanName)就不知道返回哪个bean了
**/
if (!beanName.equals(parentBeanName)) {
/**
* 这里又重复调用了getMergedBeanDefinition,但是方法传参为parentBeanName
* 这里的作用是用于合并父BeanDefiniton和爷爷辈的BeanDefiniton,如果爷爷辈还有父辈,那么继续递归合并
**/
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
// 获取父容器
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
// 从父容器那里获取父类的BeanDefinitioin定义
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// 以父BeanDefiniton为基础创建RootBeanDefinition,也就是合并后的BeanDefinition
mbd = new RootBeanDefinition(pbd);
// 用子类的属性覆盖父BeanDefinition的属性
mbd.overrideFrom(bd);
}
// 如果之前没有配置,就把当前设置为单例(这里相当于设置默认的)
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
// 缓存合并后的BeanDefinition
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
return mbd;
}
}
大家可以接着阅读spring的bean的加载过程(下) Spring源码解析(6)之bean实例化过程(下)_jokeMqc的博客-CSDN博客