bean的建立過程--doGetBean
阿新 • • 發佈:2020-09-23
protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { //處理別名,提取對應的beanName final String beanName = this.transformedBeanName(name); /** * 檢查快取中或者例項工廠中是否有對應的例項 * 為什麼會首先使用這段程式碼呢? * 因為在建立單例bean的時候會存在依賴注入的情況,而在建立依賴的時候為了避免迴圈依賴 * Spring建立bean的原則是不等bean建立完就會將建立bean的ObjectFactory提早曝光,也就是將ObjectFactory加入到快取中,一旦下個bean建立時候需要依賴上個bean則直接使用ObjectFactory*/ //直接嘗試從快取獲取或者singletonFactories中的ObjectFactory中獲取 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 + "'"); } }//返回對應的例項,有時候存在諸如BeanFactory的情況並不是直接返回例項本身而是返回指定方法返回的例項 bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null); } else { //只有在單例情況下才會嘗試解決迴圈依賴,如果是原型模式下 則直接丟擲如下異常 if (this.isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } BeanFactory parentBeanFactory = this.getParentBeanFactory(); //如果beanDefinitionMap中也就是所有已經載入的類中不包括beanname則嘗試從parentBeanFactory中檢測 if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) { String nameToLookup = this.originalBeanName(name); //遞迴到BeanFactory中尋找 if (args != null) { return parentBeanFactory.getBean(nameToLookup, args); } return parentBeanFactory.getBean(nameToLookup, requiredType); } if (!typeCheckOnly) { this.markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName); this.checkMergedBeanDefinition(mbd, beanName, args); String[] dependsOn = mbd.getDependsOn(); String[] var11; //若存在依賴則需要遞迴例項化依賴的bean if (dependsOn != null) { var11 = dependsOn; int var12 = dependsOn.length; for(int var13 = 0; var13 < var12; ++var13) { String dependsOnBean = var11[var13]; if (this.isDependent(beanName, dependsOnBean)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'"); } //快取依賴呼叫 this.registerDependentBean(dependsOnBean, beanName); this.getBean(dependsOnBean); } } //例項化依賴的bean後便可以例項化mbd本身 //singleton模式的建立 if (mbd.isSingleton()) { sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() { public Object getObject() throws BeansException { try { return AbstractBeanFactory.this.createBean(beanName, mbd, args); } catch (BeansException var2) { AbstractBeanFactory.this.destroySingleton(beanName); throw var2; } } }); bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { //protoType模式的建立 var11 = null; Object prototypeInstance; try { this.beforePrototypeCreation(beanName); prototypeInstance = this.createBean(beanName, mbd, args); } finally { this.afterPrototypeCreation(beanName); } bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { //指定的scope上例項化bean String scopeName = mbd.getScope(); Scope scope = (Scope)this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { public Object getObject() throws BeansException { AbstractBeanFactory.this.beforePrototypeCreation(beanName); Object var1; try { var1 = AbstractBeanFactory.this.createBean(beanName, mbd, args); } finally { AbstractBeanFactory.this.afterPrototypeCreation(beanName); } return var1; } }); bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException var21) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' 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的實際型別 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; } }
從上述程式碼可以看出bean的載入經歷了一個複雜的過程,以上僅能粗略的瞭解整個Spring載入bean的過程。載入的步驟大致如下
1:轉換對應的beanName
因為傳入的引數不僅是beanName也可能是別名,也可能是FactoryBean,所以需要解析:去除FactoryBean的修飾符,也就是如果name="&aa",那麼會首先去除&而使name="aa"。
取指定alias所表示的最終beanName,例如別名A指向名稱B的bean則返回B;
2:嘗試從快取中載入單例
單例在spring容器內只會建立一次,後續獲取都是從單例快取中獲取。如果獲取不到則從singletonFactories中載入。因為在建立單例bean的時候會存在依賴注入的情況,而在建立的時候為了
避免迴圈依賴,在Spring中建立bean的原則是不等bean建立完就會將建立bean的ObjectFactory提早曝光,也就是將ObjectFactory加入到快取中,一旦下個bean建立時候需要依賴上個bean則直接使用ObjectFactory
3:bean的例項化
如果從快取中得到了bean的原始狀態,則需要對bean進行例項化。
4:原型模式的依賴檢查
只有在單例情況下才會嘗試解決迴圈依賴
5:加測parentBeanFactory
如果快取中沒有取到則直接轉到父類工廠上載入。
6:將儲存xml配置檔案的GernericBeanDefinition轉換為RootBeanDefinition
7:尋找依賴
8:針對不同的scope進行bean的建立
9:型別轉換
快取池獲取bean例項
protected Object getSingleton(String beanName, boolean allowEarlyReference) { //一級快取:存放的是已經完成例項化,屬性填充和初始化步驟的單例bean例項 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) { synchronized(this.singletonObjects) { //二級快取:存放的是提前暴露的單例bean例項,可能是代理物件,也可能是未經代理的原物件,但都還沒有完成初始化的步驟 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { //三級快取:存放的是ObjectFactory的匿名內部類例項 ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName); if (singletonFactory != null) { //回撥ObjectFactory#getObject方法獲取提前暴露的引用 singletonObject = singletonFactory.getObject(); //移入二級快取 this.earlySingletonObjects.put(beanName, singletonObject); //移除三級快取 this.singletonFactories.remove(beanName); } } } } return singletonObject != NULL_OBJECT ? singletonObject : null; }