createBean方法定義在AbstractBeanFactory中:java
該方法根據給定的beanName、BeanDefinition和args實例化一個bean對象。全部bean實例的建立都會委託給該方法實現。緩存
createBean的默認實如今AbstractAutowireCapableBeanFactory類中,代碼以下:app
1 protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 2 throws BeanCreationException { 3 if (logger.isDebugEnabled()) { 4 logger.debug("Creating instance of bean '" + beanName + "'"); 5 } 6 RootBeanDefinition mbdToUse = mbd; 7 8 // Make sure bean class is actually resolved at this point, and 9 // clone the bean definition in case of a dynamically resolved Class 10 // which cannot be stored in the shared merged bean definition. 11 // 確保此時的bean已經被解析了 12 // 若是獲取的class屬性不爲null,則克隆該BeanDefinition,主要是由於動態解析的class沒法保存到共享的BeanDefinition 13 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); 14 if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { 15 mbdToUse = new RootBeanDefinition(mbd); 16 mbdToUse.setBeanClass(resolvedClass); 17 } 18 19 // Prepare method overrides. 20 try { 21 // 驗證和準備覆蓋方法 22 mbdToUse.prepareMethodOverrides(); 23 } catch (BeanDefinitionValidationException ex) { 24 throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), 25 beanName, "Validation of method overrides failed", ex); 26 } 27 28 try { 29 // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. 30 // 實例化的前置處理 31 // 給BeanPostProcessor一個機會用來返回一個代理類而不是真正的實例類 32 // AOP的功能就是基於這個地方 33 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 34 if (bean != null) { 35 return bean; 36 } 37 } catch (Throwable ex) { 38 throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, 39 "BeanPostProcessor before instantiation of bean failed", ex); 40 } 41 42 try { 43 // 建立Bean對象 44 Object beanInstance = doCreateBean(beanName, mbdToUse, args); 45 if (logger.isDebugEnabled()) { 46 logger.debug("Finished creating instance of bean '" + beanName + "'"); 47 } 48 return beanInstance; 49 } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { 50 // A previously detected exception with proper bean creation context already, 51 // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. 52 throw ex; 53 } catch (Throwable ex) { 54 throw new BeanCreationException( 55 mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); 56 } 57 }
分析:ide
1 protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch) 2 throws CannotLoadBeanClassException { 3 4 try { 5 if (mbd.hasBeanClass()) { 6 return mbd.getBeanClass(); 7 } 8 if (System.getSecurityManager() != null) { 9 return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () -> 10 doResolveBeanClass(mbd, typesToMatch), getAccessControlContext()); 11 } else { 12 return doResolveBeanClass(mbd, typesToMatch); 13 } 14 // ..... 省略異常處理 15 }
分析:函數
該方法主要是解析BeanDefinition的class類,若是解析的class類不爲空,則將其設置到mbdToUse中,由於動態解析的class沒法保存到共享的BeanDefinition中。post
1 public void prepareMethodOverrides() throws BeanDefinitionValidationException { 2 // Check that lookup methods exists. 3 // 若是方法能夠覆蓋 4 if (hasMethodOverrides()) { 5 // 獲得覆蓋方法 6 Set<MethodOverride> overrides = getMethodOverrides().getOverrides(); 7 // 同步 8 synchronized (overrides) { 9 // 循環調用 prepareMethodOverride進行覆蓋準備 10 for (MethodOverride mo : overrides) { 11 prepareMethodOverride(mo); 12 } 13 } 14 } 15 }
分析:性能
bean標籤中的lookup-method和replace-method屬性就是放在BeanDefinition的methodOverrides屬性中(關於這兩個屬性的分析後續再來分析),這裏就是對methodOverrides屬性進行處理,動態爲當前bean生產代理並使用對應的攔截器爲bean作加強處理。優化
上述處理邏輯就是循環獲取MethodOverride屬性,而後調用prepareMethodOverride進行處理。this
1 // AbstractBeanDefinition 2 protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException { 3 int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName()); 4 if (count == 0) { 5 throw new BeanDefinitionValidationException( 6 "Invalid method override: no method with name '" + mo.getMethodName() + 7 "' on class [" + getBeanClassName() + "]"); 8 } else if (count == 1) { 9 // Mark override as not overloaded, to avoid the overhead of arg type checking. 10 mo.setOverloaded(false); 11 } 12 }
分析:spa
根據方法名,從class中獲取該方法名的個數:
1 protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { 2 Object bean = null; 3 // 若是bean不是應用系統的,有BeanPostProcessor 4 if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { 5 // Make sure bean class is actually resolved at this point. 6 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 7 Class<?> targetType = determineTargetType(beanName, mbd); 8 if (targetType != null) { 9 // 前置處理 10 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); 11 if (bean != null) { 12 // 後置處理 13 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); 14 } 15 } 16 } 17 mbd.beforeInstantiationResolved = (bean != null); 18 } 19 return bean; 20 }
分析:
經過applyBeanPostProcessorsBeforeInstantiation和applyBeanPostProcessorsAfterInitialization對bean實例化前進行前置與後置處理。若是返回了代理對象,則直接返回結果,Spring後續實現AOP就是基於這個地方進行的判斷。
前置處理與後置處理後續再具體進行分析。
1 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) 2 throws BeanCreationException { 3 4 // Instantiate the bean. 5 // BeanWrapper是對Bean的包裝,其接口中所定義的功能很簡單包括設置獲取被包裝的對象、獲取被包裝bean的屬性描述器 6 BeanWrapper instanceWrapper = null; 7 // 若是是單例模型,則從未完成的FactoryBean緩存中刪除 8 if (mbd.isSingleton()) { 9 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); 10 } 11 // 使用合適的實例化策略來建立新的實例:工廠方法、構造函數自動注入、簡單初始化 12 if (instanceWrapper == null) { 13 instanceWrapper = createBeanInstance(beanName, mbd, args); 14 } 15 // 包裝的對象實例 16 final Object bean = instanceWrapper.getWrappedInstance(); 17 // 包裝的實例對象的類型 18 Class<?> beanType = instanceWrapper.getWrappedClass(); 19 if (beanType != NullBean.class) { 20 mbd.resolvedTargetType = beanType; 21 } 22 23 // Allow post-processors to modify the merged bean definition. 24 // 先作同步,而後判斷是否有後置處理 25 synchronized (mbd.postProcessingLock) { 26 if (!mbd.postProcessed) { 27 try { 28 // 後置處理修改BeanDefinition 29 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); 30 } catch (Throwable ex) { 31 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 32 "Post-processing of merged bean definition failed", ex); 33 } 34 mbd.postProcessed = true; 35 } 36 } 37 38 // Eagerly cache singletons to be able to resolve circular references 39 // even when triggered by lifecycle interfaces like BeanFactoryAware. 40 // 解決單例模式的循環依賴 // 單例模式 運行循環依賴 41 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && 42 isSingletonCurrentlyInCreation(beanName));// 當前單例bean是否正在被建立 43 if (earlySingletonExposure) { 44 if (logger.isDebugEnabled()) { 45 logger.debug("Eagerly caching bean '" + beanName + 46 "' to allow for resolving potential circular references"); 47 } 48 // 提早將建立的bean實例加入到singletonFactories中 49 // 爲了後期避免循環依賴 50 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); 51 } 52 53 // Initialize the bean instance. 54 // 開始初始化bean實例對象 55 Object exposedObject = bean; 56 try { 57 // 對bean進行填充,主要是進行屬性注入,其中,可能存在依賴於其餘bean的屬性,則會遞歸初始化依賴bean 58 populateBean(beanName, mbd, instanceWrapper); 59 // 進行bean初始化 60 exposedObject = initializeBean(beanName, exposedObject, mbd); 61 } catch (Throwable ex) { 62 if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { 63 throw (BeanCreationException) ex; 64 } else { 65 throw new BeanCreationException( 66 mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); 67 } 68 } 69 70 // 循環依賴處理 71 if (earlySingletonExposure) { 72 // 獲取earlySingletonReference 73 Object earlySingletonReference = getSingleton(beanName, false); 74 // 只有在循環依賴的狀況下,earlySingletonReference纔不會爲null 75 if (earlySingletonReference != null) { 76 // 若是exposedObject沒有在初始化方法中改變,也就是沒有被加強 77 if (exposedObject == bean) { 78 exposedObject = earlySingletonReference; 79 } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { // 處理依賴 80 String[] dependentBeans = getDependentBeans(beanName); 81 Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); 82 for (String dependentBean : dependentBeans) { 83 if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { 84 actualDependentBeans.add(dependentBean); 85 } 86 } 87 if (!actualDependentBeans.isEmpty()) { 88 throw new BeanCurrentlyInCreationException(beanName, 89 "Bean with name '" + beanName + "' has been injected into other beans [" + 90 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + 91 "] in its raw version as part of a circular reference, but has eventually been " + 92 "wrapped. This means that said other beans do not use the final version of the " + 93 "bean. This is often the result of over-eager type matching - consider using " + 94 "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); 95 } 96 } 97 } 98 } 99 100 // Register bean as disposable. 101 try { 102 // 註冊bean 103 registerDisposableBeanIfNecessary(beanName, bean, mbd); 104 } catch (BeanDefinitionValidationException ex) { 105 throw new BeanCreationException( 106 mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); 107 } 108 109 return exposedObject; 110 }
分析:
若是沒有代理對象,則會進行bean對象的建立。
上述列出了建立bean對象的主要步驟,過程仍是比較複雜的,下面一一進行分析。主要關注點createBeanInstance、populateBean、initializeBean三個函數。
1 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { 2 // Make sure bean class is actually resolved at this point. 3 // 解析bean,將bean類名解析爲class引用 4 Class<?> beanClass = resolveBeanClass(mbd, beanName); 5 6 if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { 7 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 8 "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); 9 } 10 11 // 若是存在supplier回調,則使用給定的回調方法初始化策略 12 Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); 13 if (instanceSupplier != null) { 14 return obtainFromSupplier(instanceSupplier, beanName); 15 } 16 17 // 使用FactoryBean的factor-method來建立bean,支持靜態工廠和實例工廠 18 if (mbd.getFactoryMethodName() != null) { 19 return instantiateUsingFactoryMethod(beanName, mbd, args); 20 } 21 22 // Shortcut when re-creating the same bean... 23 boolean resolved = false; 24 boolean autowireNecessary = false; 25 if (args == null) { 26 // 作同步 27 synchronized (mbd.constructorArgumentLock) { 28 // 若是已緩存的解析構造函數或者工廠方法不爲null,則能夠利用構造函數解析 29 // 由於須要根據參數確認到底使用哪一個構造函數,該過程比較消耗性能,因此採用緩存機制 30 if (mbd.resolvedConstructorOrFactoryMethod != null) { 31 resolved = true; 32 autowireNecessary = mbd.constructorArgumentsResolved; 33 } 34 } 35 } 36 // 已經解析好了,直接注入便可 37 if (resolved) { 38 // autowire自動注入,調用構造函數自動注入 39 if (autowireNecessary) { 40 return autowireConstructor(beanName, mbd, null, null); 41 } else { 42 // 使用默認構造函數構造 43 return instantiateBean(beanName, mbd); 44 } 45 } 46 47 // Need to determine the constructor... 48 // 肯定解析的構造函數 49 // 主要是檢查已經註冊的SmartInstantiationAwareBeanPostProcessor 50 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); 51 // 肯定構造方法進行bean建立 52 if (ctors != null || 53 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || 54 mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { 55 return autowireConstructor(beanName, mbd, ctors, args); 56 } 57 58 // 有參數,又沒有獲取到構造方法,則只能調用無參構造方法來建立實例 59 // 這是一個兜底的方法 60 // No special handling: simply use no-arg constructor. 61 return instantiateBean(beanName, mbd); 62 }
分析:
bean的實例化一個比較複雜的過程。
#1.若是設置Supplier回調,則使用obtainFromSupplier方法進行初始化。
首先了解下Supplier接口(java.util.function):
1 protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) { 2 // 得到原建立的Bean的對象名 3 String outerBean = this.currentlyCreatedBean.get(); 4 // 設置新的Bean對象名到currentlyCreatedBean中 5 this.currentlyCreatedBean.set(beanName); 6 Object instance; 7 try { 8 // 調用Supplier的get(),返回一個Bean對象 9 instance = instanceSupplier.get(); 10 } finally { 11 // 設置原建立的Bean對象名到currentlyCreatedBean中 12 if (outerBean != null) { 13 this.currentlyCreatedBean.set(outerBean); 14 } else { 15 this.currentlyCreatedBean.remove(); 16 } 17 } 18 // 建立BeanWrapper對象 19 BeanWrapper bw = new BeanWrapperImpl(instance); 20 // 初始化BeanWrapper 21 initBeanWrapper(bw); 22 return bw; 23 }
分析:
若是存在工廠方法,則會調用工廠方法來完成bean的初始化工做,該方法實現比較長,而且細節複雜,因爲篇幅緣由放在下篇文章中解析。
這裏僅僅分析了doCreateBean方法中的一點點內容,若是存在Supplier回調,則會直接經過Supplier來建立Bean對象,構造函數和工廠方法則失效,下面將對分析使用工廠方法實例化Bean對象的過程。
by Shawn Chen,2019.04.23,下午。