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的屬性的解析和注入,可以從書上進行檢視相關的原始碼。