Spring源码解析(5)之bean实例化过程(上)

一、前言

        进过前面的分析,接下来就是对面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源码,看不懂就先跳,有些太过复杂的可以知道这行代码是干嘛的就行,可以先把大体的流程先看完,然后学习源码本身就是一件很枯燥很需要精力的事情,我们需要自己多看几遍然后自己调试几遍。

  1. 转换对应的beanName,这里或许很多人不理解,传进来的name不就是beanName么?其实传进来的有可能是别名或者是我们的BeanFactory,所以需要进行一系列的解析,其中解析包括以下内容,(1)去除BeanFactory的修饰符(在我Spring源码分析(1)之常见底层核心注解_jokeMqc的博客-CSDN博客 已经有介绍对应的用法了)(2)去指定的alias获取最终表示的beanName。
  2. 尝试去缓存中加载单例,这里就是为了解决循环依赖的关键代码,本节课讲完bean的加载过程会介绍spring是如果解决循环依赖的,要记得我们单例bean在容器中只会被实例化一次,后续在创建bean就直接从单例缓存池中去获取了,这里只是尝试去获取。这里为了解决循环依赖问题,在对象刚刚创建好的时候(还没有进行属性赋值),就会将创建bean的ObjectFactory提早的暴露到缓存中去,一旦下一个bean创建的时候需要上一个bean那直接就从缓存里面去获取就行了。(后面会着重将这一个)
  3. bean的实例化,如果我们从缓存中获取得到bean,我们只是获取得到bean的原始状态,不一定是我们最终需要的bean,需要getObjectForBeanInstance方法中如果bean没有实例化则在这里进行实例化.
  4. 对原型依赖的检查,为什么原型对象解决不了循环依赖,这里就说明了,我们的ioc容器并不会对原型对象进行缓存,而是获取一次则创建一次bean,isPrototypeCurrentlyInCreation是检查如果A中有B的属性,B中有A的属性,那么当依赖注入的时候,此时就会有A还没有创建完,然后需要去创建B,继而又要创建A,这个时候就会抛出异常了。
  5. 检测parentFactory,其实这里代码的意思很简单,如果当前的bean存在父容器并且当前容器找不到对应的bean定义,那么就去父容器中进行加载。
  6. 合并父类属性(下面也会有具体的介绍)
  7. 寻找依赖,就是我们在bean标注的depends-on,但是需要注意的一点就是如果A depends-on B,B depends-on A这个就会抛异常的
  8. 针对不同的scope进行bean的创建
  9. 类型转换,到这里其实整个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));
	}
  1.  去缓存中获取bean定义信息,获取得到则直接返回。
  2. 如果获取不到,则判断当前的bean是否存在父类,如果不存在,则进行深克隆后然后对应的RootBeanDefinition
  3. 如果存在父类,首先获取得到父类的名称,然后判断父类名称跟当前beanName是否一样,如果一样,则判断父类一定是在父容器中,然后去父容器那里获取得到对应BeanDenifition。
  4. 最后以父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博客

猜你喜欢

转载自blog.csdn.net/jokeMqc/article/details/120805886