1. 程式人生 > >SpringFramework的核心:IOC容器的實現------IoC容器的依賴注入

SpringFramework的核心:IOC容器的實現------IoC容器的依賴注入

如果IoC容器已經載入了使用者定義的Bean資訊,並開始分析依賴注入的原理。依賴注入是使用者第一次向IoC容器索要Bean時觸發的,當然也有例外。如果我們設定了lazy-init的屬性。是可以在剛開始初始化容器的時候就為我們生成新的bean。

首先我們從DefaultListableBeanFactory類中來檢視getBean觸發的依賴注入

org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(String, Class<T>, Object[], boolean)

getBean方法裡面都呼叫了doGetBean這個方法

由於這個方法非常非常長,所以我就不再粘貼出來。而是從這個方法裡面找尋一些有用的資訊。

doGetBean是一個很漫長的過程。而且根據我們建立的bean的要求不同,會有不同的建立方法。

首先我們要去快取中去取,處理已經被建立過的單例模式的bean,對這種bean的請求不需要重複建立。

關於這樣一行程式碼,是FactoryBean對於我們的實體bean的一個修飾作用

bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

接下里就是對BeanDefinition在IoC容器的查詢存在,如果當前的IoC容器不存在那麼就要去它的父類進行查詢。如果最後沒有查詢結果。

取得bean以及這個bean所依賴的所有bean之後,我們就需要根據bean的建立要求來進行生成bean。

一種是Singleton bean,一種是prototype bean(這種bean每一次請求都會有一個新的物件產生)

最後我們要對創建出來的bean進行型別檢查,如果沒有問題,就把我們創建出來的bean返回。

現在我們主要來看看依賴注入的關鍵步驟,怎樣根據BeanDefinition來生成對應的bean。接下來要進入到createBean中來具體進行說明。

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])

@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}

具體的我們進入到createBean中來檢視

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(String, RootBeanDefinition, Object[])

BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}

首先我們建立一個BeanWrapper來斥候我們的bean物件,如果是singleton,先把快取中的同名bean清除。

具體的建立交給createBeanInstance來完成

之後就是對bean的初始化,依賴注入。這個主要是交給populateBean()方法來完成.

當例項化bean物件生成的基礎上,spring需要對這些物件進行處理,各種bean物件生成以後,怎樣把這些bean物件的依賴關係設定好,完成整個依賴注入的過程。這裡涉及對各種物件Bean的屬性的處理過程。

依賴注入過程,先處理autowire注入 。之後對屬性的具體注入是在

applyPropertyValues(beanName, mbd, bw, pvs);

中完成的

現在進入到applyPropertyValues中去看看具體的對屬性進行解析然後注入的過程

首先我們獲取到了這個bean所需要的所有屬性

		if (pvs == null || pvs.isEmpty()) {
			return;
		}

		MutablePropertyValues mpvs = null;
		List<PropertyValue> original;

		if (System.getSecurityManager() != null) {
			if (bw instanceof BeanWrapperImpl) {
				((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
			}
		}

		if (pvs instanceof MutablePropertyValues) {
			mpvs = (MutablePropertyValues) pvs;
			if (mpvs.isConverted()) {
				// Shortcut: use the pre-converted values as-is.
				try {
					bw.setPropertyValues(mpvs);
					return;
				}
				catch (BeansException ex) {
					throw new BeanCreationException(
							mbd.getResourceDescription(), beanName, "Error setting property values", ex);
				}
			}
			original = mpvs.getPropertyValueList();
		}
		else {
			original = Arrays.asList(pvs.getPropertyValues());
		}

 

然後我們對我們的這個original連結串列進行一次拷貝。

之後我們需要獲取一系列的轉換器用來將我們的BeanDefinition內的資料以及生成的bean物件進行依賴注入

TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}
		BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

		// Create a deep copy, resolving any references for values.
		List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
		boolean resolveNecessary = false;
		for (PropertyValue pv : original) {
			if (pv.isConverted()) {
				deepCopy.add(pv);
			}
			else {
				String propertyName = pv.getName();
				Object originalValue = pv.getValue();
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
				Object convertedValue = resolvedValue;
				boolean convertible = bw.isWritableProperty(propertyName) &&
						!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
				if (convertible) {
					convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
				}
				// Possibly store converted value in merged bean definition,
				// in order to avoid re-conversion for every created bean instance.
				if (resolvedValue == originalValue) {
					if (convertible) {
						pv.setConvertedValue(convertedValue);
					}
					deepCopy.add(pv);
				}
				else if (convertible && originalValue instanceof TypedStringValue &&
						!((TypedStringValue) originalValue).isDynamic() &&
						!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
					pv.setConvertedValue(convertedValue);
					deepCopy.add(pv);
				}
				else {
					resolveNecessary = true;
					deepCopy.add(new PropertyValue(pv, convertedValue));
				}
			}
		}
		if (mpvs != null && !resolveNecessary) {
			mpvs.setConverted();
		}

之後是關於bean的屬性的解析和注入,可以從書上進行檢視相關的原始碼。