Spring getBean實例化Bean的過程

前面一章關於java

refresh()方法的調用過程當中提到最終會實例化非懶加載的單例bean,今天就來看一下bean初始化的整個過程。
refresh()方法感興趣的能夠去看下前面一章內容: juejin.im/post/5cef2e…

1.首先refresh()方法最後調用finishBeanFactoryInitialization(beanFactory)執行初始化bean工做,而後會調用DefaultListableBeanFactory.preInstantiateSingletons()。部分源碼以下:緩存


這裏會獲取全部的單例的非懶加載的Beandefinition遍歷執AbstractBeanFactory.getBean()。bash

2.doGetBean方法執行過程:app

        2.1 先調用getSingleton()先去緩存中查詢有沒有,若是存在就獲取緩存中的對象。這裏有三個緩存對象,分別是:singletonObjects(單例對象的cache)、earlySingletonObjects(提早暴光的單例對象的Cache)、singletonFactories(單例對象工廠的cache)。ide

Object sharedInstance = getSingleton(beanName);
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	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;
}
複製代碼

        2.2 調用父容器的getBean若是存在直接返回。post


        2.3 判斷是否配置了depends-on屬性,若是有先建立依賴的bean。ui


        2.4 判斷是單例仍是原型,調用createBean()建立Bean實例。this

   


3.createBean的處理過程:spa

3.1 校驗override方法debug

// Prepare method overrides.
try {
	mbdToUse.prepareMethodOverrides();
}

複製代碼

3.2 這裏最關鍵的代碼代理類的生成。

try {
	// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
	//處理實現了InstantiationAwareBeanPostProcessor接口的類。
        //擴展點:能夠建立代理對象並返回
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
	if (bean != null) {
		return bean;
	}
}複製代碼

3.3 繼續調用doCreateBean方法建立bean實例

4. AbstractAutowireCapableBeanFactory類的doCreateBean方法

4.1 建立bean實例

if (instanceWrapper == null) {
	instanceWrapper = createBeanInstance(beanName, mbd, args);
}

複製代碼

//createBeanInstance的主要實現
// Candidate constructors for autowiring?
//獲取全部構造器,匹配構造器,反射調用構造器生成實例
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
		mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
	return autowireConstructor(beanName, mbd, ctors, args);
}

// Preferred constructors for default construction? 這個還不清楚怎麼用
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
	return autowireConstructor(beanName, mbd, ctors, null);
}
//調用無參構造器
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);複製代碼

無參構造器:調用SimpleInstantiationStrategy的方法instantiate進行校驗,

若是沒有構造器拋出異常;

throw new BeanInstantiationException(clazz, "No default constructor found", ex);複製代碼

若是是接口拋出異常。

throw new BeanInstantiationException(clazz, "Specified class is an interface");複製代碼

最後反射調用無參構造器初始化Bean實例。

BeanUtils

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
	Assert.notNull(ctor, "Constructor must not be null");
	try {
		ReflectionUtils.makeAccessible(ctor);
		return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
				KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
	}
	catch (InstantiationException ex) {
		throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
	}
	catch (IllegalAccessException ex) {
		throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
	}
	catch (IllegalArgumentException ex) {
		throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
	}
	catch (InvocationTargetException ex) {
		throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
	}
}複製代碼

有參數的構造器: 這裏代碼就不貼了比較多就簡單介紹下。主要是對參數的校驗,若是有引用就經過getBean獲取引用對象(也就是從新走一遍流程)。最終調用SimpleInstantiationStrategy的重載方法instantiate實例化Bean。

4.2 到此爲止Bean實例已經建立完畢,接下來就是設置屬性,初始化等工做。

   ①:解決屬性循環依賴問題,爲循環引用依賴提早緩存單例Bean

//是否提前暴露單例bean實例
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
		isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
	if (logger.isTraceEnabled()) {
		logger.trace("Eagerly caching bean '" + beanName +
				"' to allow for resolving potential circular references");
	}
        //放到singletonFactories中
	addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}複製代碼

②:populateBean方法

執行全部實現了InstantiationAwareBeanPostProcessor接口的實例,實例化Bean的後置處理

boolean continueWithPropertyPopulation = true;
//實現了InstantiationAwareBeanPostProcessor的實例將被在Bean實例化以後被執行
//postProcessAfterInstantiation方法。
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
	for (BeanPostProcessor bp : getBeanPostProcessors()) {
		if (bp instanceof InstantiationAwareBeanPostProcessor) {
			InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
			if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
				continueWithPropertyPopulation = false;
				break;
			}
		}
	}
}複製代碼

設置屬性

//獲取配置的的屬性列表<property>PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//對設置了autowire的處理,根據類型和名稱從新獲取屬性列表
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
	MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
	// Add property values based on autowire by name if applicable.
	if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
		autowireByName(beanName, mbd, bw, newPvs);
	}
	// Add property values based on autowire by type if applicable.
	if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
		autowireByType(beanName, mbd, bw, newPvs);
	}
	pvs = newPvs;
}

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
	if (pvs == null) {
		pvs = mbd.getPropertyValues();
	}
    // 設置屬性以前對屬性經行前置處理
	for (BeanPostProcessor bp : getBeanPostProcessors()) {
		if (bp instanceof InstantiationAwareBeanPostProcessor) {
			InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
			PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
			if (pvsToUse == null) {
				if (filteredPds == null) {
					filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
				}
				pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					return;
				}
			}
			pvs = pvsToUse;
		}
	}
}

if (needsDepCheck) {//是否開啓依賴校驗,默認false
	if (filteredPds == null) {
                //排除在忽略的依賴接口上定義的忽略的依賴類型或屬性
		filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
	}
        //檢查是否全部屬性已被設置
	checkDependencies(beanName, mbd, filteredPds, pvs);
}

if (pvs != null) {
        //設置屬性
	applyPropertyValues(beanName, mbd, bw, pvs);
}複製代碼

③:initializeBean方法

執行織入方法invokeAwareMethods

if (bean instanceof Aware) {
	if (bean instanceof BeanNameAware) {
		((BeanNameAware) bean).setBeanName(beanName);
	}
	if (bean instanceof BeanClassLoaderAware) {
		ClassLoader bcl = getBeanClassLoader();
		if (bcl != null) {
			((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
		}
	}
	if (bean instanceof BeanFactoryAware) {
		((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
	}
}複製代碼

執行BeanPostProcessor的postProcessBeforeInitialization方法,執行init-method以前對進行Bean處理。

if (mbd == null || !mbd.isSynthetic()) {
	wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}複製代碼

執行配置的初始化方法(init-method)

try {
       //invokeInitMethods方法執行配置的初始化方法,
        //若是bean是InitializingBean實例還會執行afterPropertiesSet方法。
	invokeInitMethods(beanName, wrappedBean, mbd);
}複製代碼

執行BeanPostProcessor的postProcessAfterInitialization方法,執行init-method以後對bean進行處理。此處能夠返回代理對象

if (mbd == null || !mbd.isSynthetic()) {
	wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}複製代碼

對scope進行處理(這部分代碼沒有去研究,有興趣的能夠本身設置不一樣的scope,而後debug跟一下)。

registerDisposableBeanIfNecessary(beanName, bean, mbd);複製代碼

5.小結

上面就是getBean的整個過程。下面盜用別人的圖來看一下整個過程的流程:


其中有些沒講有些只是簡單帶過,感興趣的本身看跟源碼的時候能夠去仔細看看。

還有一點就是BeanFactoryPostProcessor和BeanPostProcessor這兩個接口的實現類貫穿整個容器初始化的各個過程,瞭解不一樣實如今容器初始化過程當中的做用對於本身擴展Spring會有很大的幫助,強烈建議去了解一下不一樣子類的做用。

相關文章
相關標籤/搜索