8-spring原始碼3.2.18解讀+spring技術內幕(IOC容器的依賴注入(反射+遞迴呼叫))
1、導讀
以上對IOC容器的初始化過程做了詳細的分析,這個初始化過程完成的主要工作是在IOC容器中建立BeanDefinition資料對映。再次過程中並沒有對Bean依賴關係進行注入,接下來將分析一下IOC容器是怎麼樣對Bean的依賴關係進行注入的。
假設當前IOC容器已經載入了使用者定義的Bean資訊,開始分析依賴注入的原理。首先,注意到依賴注入的過程是使用者第一次向IOC容器索要Bean時觸發的,當然也有例外,也就是我們可以在BeanDefinition資訊中通過控制lazy-init屬性來讓容器完成對Bean的預例項化。這個預例項化實際上也是一個完成依賴注入的過程,但它在初始化的過程中完成的。當用戶想
2、AbstractBeanFactory類
//這裡是對BeanFactory介面的實現,比如getBean介面方法
//這些getBean介面方法最終是通過呼叫doGetBean來實現的
public Object getBean(String name) throws BeansException {
return this.doGetBean(name, (Class)null, (Object[])null, false);
}
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return this.doGetBean(name, requiredType, (Object[])null, false);
}
public Object getBean(String name, Object... args) throws BeansException {
return this.doGetBean(name, (Class)null, args, false);
}
public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
return this.doGetBean(name, requiredType, args, false);
}
//這裡是實際取得Bean的地方,也是觸發依賴注入的地方
protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = this.transformedBeanName(name);
//先從快取中取得Bean,處理那些已經被建立過的單例模式的Bean,對這種Bean的請求不需要重複的建立,直接返回即可
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if(sharedInstance != null && args == null) {
if(this.logger.isDebugEnabled()) {
if(this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.debug("Returning eagerly cached instance of singleton bean \'" + beanName + "\' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.debug("Returning cached instance of singleton bean \'" + beanName + "\'");
}
}
//這裡的getObjectForBeanInstance完成的是FactoryBean的相關處理,以取得FactoryBean的生產結果。
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
if(this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//這裡對IOC容器中的BeanDefinition是否存在進行檢查,檢查是否能在當前BeanFactory中取得需要的Bean,如果在當前的工廠中取不到,則到雙親BeanFactory中去取,如果雙親工廠取不到,那就順著雙親BeanFactory鏈一直往上查詢
BeanFactory ex = this.getParentBeanFactory();
if(ex != null && !this.containsBeanDefinition(beanName)) {
String var24 = this.originalBeanName(name);
if(args != null) {
return ex.getBean(var24, args);
}
return ex.getBean(var24, requiredType);
}
if(!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
try {
//這裡根據Bean的名字取得BeanDefinition
final RootBeanDefinition ex1 = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(ex1, beanName, args);
//獲取當前Bean的所有依賴Bean,這樣會觸發getBean的遞迴呼叫,直到取到一個沒有任何的依賴Bean為止
String[] dependsOn = ex1.getDependsOn();
String[] scopeName;
if(dependsOn != null) {
scopeName = dependsOn;
int scope = dependsOn.length;
for(int ex2 = 0; ex2 < scope; ++ex2) {
String dependsOnBean = scopeName[ex2];
this.getBean(dependsOnBean);
this.registerDependentBean(dependsOnBean, beanName);
}
}
//這裡通過呼叫createBean方法建立Singleton bean的例項,這裡有一個回撥函式getObject,會在getSingleton中呼叫ObjectFactory的createBean
if(ex1.isSingleton()) {
sharedInstance = this.getSingleton(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
try {
return AbstractBeanFactory.this.createBean(beanName, ex1, args);
} catch (BeansException var2) {
AbstractBeanFactory.this.destroySingleton(beanName);
throw var2;
}
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, ex1);
} else if(ex1.isPrototype()) {//這裡是建立prototype bean的地方
scopeName = null;
Object var25;
try {
this.beforePrototypeCreation(beanName);
var25 = this.createBean(beanName, ex1, args);
} finally {
this.afterPrototypeCreation(beanName);
}
bean = this.getObjectForBeanInstance(var25, name, beanName, ex1);
} else {
String var26 = ex1.getScope();
Scope var27 = (Scope)this.scopes.get(var26);
if(var27 == null) {
throw new IllegalStateException("No Scope registered for scope \'" + var26 + "\'");
}
try {
Object var28 = var27.get(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
AbstractBeanFactory.this.beforePrototypeCreation(beanName);
Object var1;
try {
var1 = AbstractBeanFactory.this.createBean(beanName, ex1, args);
} finally {
AbstractBeanFactory.this.afterPrototypeCreation(beanName);
}
return var1;
}
});
bean = this.getObjectForBeanInstance(var28, name, beanName, ex1);
} catch (IllegalStateException var21) {
throw new BeanCreationException(beanName, "Scope \'" + var26 + "\' 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", var21);
}
}
} catch (BeansException var23) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var23;
}
}
//這裡包含了對Bean型別檢查,如果沒有問題,則返回這個新建立的bean,這個bean已經包含了依賴關係的bean
if(requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return this.getTypeConverter().convertIfNecessary(bean, requiredType);
} catch (TypeMismatchException var22) {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Failed to convert bean \'" + name + "\' to required type [" + ClassUtils.getQualifiedName(requiredType) + "]", var22);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else {
return bean;
}
}