Spring源碼分析之createBean主流程分析

我們知道,在調用getBean獲取bean實例的實例,首先會從緩存中獲取bean實例,如果沒有獲取到,就會去創建bean的時候。關於獲取bean實例,可以參考Spring源碼分析之getBean主流程分析,而本文將會對創建bean實例的主流程來做一個分析。而入口,當然是createBean(AbstractAutowireCapableBeanFactory)的方法。

下面來看源碼:

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) 
			throws BeanCreationException {
	if (logger.isDebugEnabled()) {
		logger.debug("Creating instance of bean '" + beanName + "'");
	}
	RootBeanDefinition mbdToUse = mbd;
	//1:解析bean的類型
	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}

	try {
	//2:處理 lookup-method 和 replace-method 配置,而Spring統稱爲override method
		mbdToUse.prepareMethodOverrides();
	}
	catch (BeanDefinitionValidationException ex) {
		........
	}

	try {
	//3:bean的後置處理器,如果有,這裏會返回代理的實例。AOP的實現基礎就是基於這裏來實現的
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		if (bean != null) {
			return bean;
		}
	}
	catch (Throwable ex) {
		........
	}
	//來創建bean的實例
	Object beanInstance = doCreateBean(beanName, mbdToUse, args);
	if (logger.isDebugEnabled()) {
		logger.debug("Finished creating instance of bean '" + beanName + "'");
	}
	return beanInstance;
}

其主流程邏輯也是比較的簡單的:

  1. 對bean類型的解析
  2. 處理methodOverrides
  3. 處理bean實例的後置處理器。如果有,則返回一個代理的類。這裏實際上是判斷類有沒有實現InstantiationAwareBeanPostProcessor接口。
  4. 創建實例bean並返回。

下面我們來看看doCreateBean中的邏輯:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
		throws BeanCreationException {
	//bean實例包裝類
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		//從緩存中清理相關中的包裝類
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		//創建bean的時候,這裏創建bean的實例有三種方法
		//1:工廠方法創建
		//2:   利用構造方法的方式注入
		//3:   利用無參構造方法注入
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	//這裏的bean應該是才被實例化的bean,還未被填充相關的屬性
	final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
	Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
	mbd.resolvedTargetType = beanType;

	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
			applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			}
			catch (Throwable ex) {
				.........
			}
			mbd.postProcessed = true;
		}
	}

	//判斷是否是早期引用的bean,如果是,則允許其提前暴露引用
	//這裏判斷的邏輯主要有三個:
 	//1:是否爲單例:isSingleton
	//2:是否允許循環引用 :allowCircularReferences
	//3:是否是在創建中的bean:isSingletonCurrentlyInCreation
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		if (logger.isDebugEnabled()) {
			logger.debug("Eagerly caching bean '" + beanName +
				"' to allow for resolving potential circular references");
		}
		addSingletonFactory(beanName, new ObjectFactory<Object>() {
			@Override
			public Object getObject() throws BeansException {
				return getEarlyBeanReference(beanName, mbd, bean);
			}
		});
	}

	Object exposedObject = bean;
	try {
		//填充bean的屬性
		populateBean(beanName, mbd, instanceWrapper);
		if (exposedObject != null) {
		//初始化bean,過程如下:
		//1:判斷是否實現了BeanNameAware,BeanClassLoaderAware以及
		//   BeanFactoryAware方法,如果有,則設置相關的屬性
		//2: 調用bean初始化的前置操作
		//3: 執行初始化的方法。
		//	如果有initializingBean,則調用afterPropertiesSet
		//	如果有InitMethod,則調用初始方法
		//4: 調用bean初始化的後置操作
		exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
	}
	catch (Throwable ex) {
		if (ex instanceof BeanCreationException && 
		beanName.equals(((BeanCreationException) ex).getBeanName())) {
			throw (BeanCreationException) ex;
		}
		else {
			throw new BeanCreationException(
		mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
		}
	}
	//解決相關的循環依賴
	if (earlySingletonExposure) {
		Object earlySingletonReference = getSingleton(beanName, false);
		if (earlySingletonReference != null) {
			if (exposedObject == bean) {
				exposedObject = earlySingletonReference;
			}
			else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
			String[] dependentBeans = getDependentBeans(beanName);
			Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
			for (String dependentBean : dependentBeans) {
				if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
					actualDependentBeans.add(dependentBean);
				}
				}
				if (!actualDependentBeans.isEmpty()) {
					......
				}
			}
		}
	}
	//註冊bean的銷燬邏輯
	try {
	registerDisposableBeanIfNecessary(beanName, bean, mbd);
	}
	catch (BeanDefinitionValidationException ex) {
		......
	}
	return exposedObject;
}

實際創建bean實例的邏輯如下:

1:創建bean的實例(工廠方法,構造器注入的方式,簡單初始化的方式)

2:是否允許其是否提前暴露引用,以便解決循環依賴的問題。

3:填充bean實例的屬性

4:初始化操作(初始方法前操作,調用初始化方法,執行初始化後的方法)

5:解決循環依賴相關的問題。

6:註冊bean的銷燬邏輯。

至此,整個創建bean實例的主流程就分析完成了,下面將以一個簡單的圖來更加形象的展示其主流程調用邏輯。

創建bean實例流程
南瓜燈cc

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章