上一節只是加載配置,並把文件內容映射到BeanDefinition中,真正的建立對象跟依賴注入是在getBean中處理的,這裏實際上就是根據BeanDefinition用反射建立對象及其依賴對象,只不過spring裏面處理的比較複雜,這裏面的每一步都有不少邏輯處理,而且在這先後作了不少的異常的判斷校驗。java
仍是以XmlBeanFactory跟蹤代碼看一下getBean流程,最終進入到AbstractBeanFactory的doGetBean方法:spring
protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { //1 去掉工廠bean的前綴& 並找到alias對應的名稱 final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. //2 先從緩存中獲取 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } //若是是bean工廠,則建立對象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: We're assumably within a circular reference. //3 在原形狀況下建立循環依賴就會報錯 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } //4 Check if bean definition exists in this factory. BeanFactory parentBeanFactory = getParentBeanFactory(); //若是存在父bean工廠而且沒有配置該bean,則從父bean工廠建立 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); //遞歸調用getBean if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { //5 轉換BeanDefinition final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); //6 depends-on標籤 // Guarantee initialization of beans that the current bean depends on. String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dependsOnBean : dependsOn) { if (isDependent(beanName, dependsOnBean)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'"); } registerDependentBean(dependsOnBean, beanName); //遞歸調用 getBean(dependsOnBean); } } //7 不一樣scope狀況下建立對象 // Singleton狀況 // Create bean instance. if (mbd.isSingleton()) { //getSingleton有單例的控制, 防止前面已經建立過該對象,若是沒建立過該對象最終也是調用createBean sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton // cache: It might have been put there // eagerly by the creation process, to allow for // circular reference resolution. // Also remove any beans that received a // temporary reference to the bean. destroySingleton(beanName); throw ex; } } }); //8 獲取最終的對象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //prototype狀況 else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } //其餘狀況 else { String scopeName = mbd.getScope(); final 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>() { @Override public Object getObject() throws BeansException { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { 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", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } //9 類型轉換 // Check if required type matches the type of the actual bean instance. if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { try { return getTypeConverter().convertIfNecessary(bean, requiredType); } catch (TypeMismatchException ex) { if (logger.isDebugEnabled()) { logger.debug("Failed to convert bean '" + name + "' to required type [" + ClassUtils.getQualifiedName(requiredType) + "]", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
時序圖以下:緩存
上面第7步,建立對象委託給了createBean,createBean中作一下初始化確認就把建立對象委託給了doCreateBean,doCreateBean核心代碼以下:app
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //1. 建立對象 instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); //...省略 // Initialize the bean instance. Object exposedObject = bean; try { //2. 填充對象 這個裏面解析了依賴的bean populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { //3. 初始化方法 exposedObject = initializeBean(beanName, exposedObject, mbd); } } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } //...省略 // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
這裏分爲三個核心過程:ide
這三部分裏面都比較複雜,後面有時間再看,看一下createBean的時序圖:ui