前言
前面幾章spring已經把需要的注冊的bean的信息已經全部加載到了BeanFactory中了,那么之后要做的事兒當然就是進行實例化了,當然了可能有人會問為何不在加載到bean信息的時候直接進行實例化呢,這不還需要依賴注入嘛,當然是要所有的都加載完了才能實例化。ApplicationContext相對於BeanFactory來說,早期的BeanFactory受制於硬件配置,所以在我們需要某個bean的時候才會進行實例化。而ApplicationContext則會在一開始就將所有的注冊的Bean(標記懶加載的,或者非單例加載除外)全部進行實例化。本文則主要介紹spring如何實例化bean,並且Bean的生命周期也會穿插其中。
這兒先放一張加載的大致流程圖
從圖中可以看到加正式加載的過程並不多,實例化->放入提前暴露容器->賦值完成后其實就算完成實例化了,但spring在其中穿插了 很多的BeanPostProcessor以及aware,同時也會根據所加載bean是否實現了InitializingBean接口來決定是否需要執行afterPropertiesSet方法。說明spring在實例化bean時給我們流下了足夠的擴展空間。
正文
我們回到上下文的refresh方法中
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { ../代碼略 try { postProcessBeanFactory(beanFactory); invokeBeanFactoryPostProcessors(beanFactory); // 注冊所有BeanPostProcessors registerBeanPostProcessors(beanFactory); ../代碼略 //實例化bean finishBeanFactoryInitialization(beanFactory); ../代碼略 } ../代碼略 } }
前面一篇我們成功的執行了invokeBeanFactoryPostProcessors方法,然后將所有的BeanFactoryPostProcessor后置方法執行了,然后也成功的將所有需要注冊到容器的bean的BeanDefination也收集到了BeanFactory中。本文則主要關注后面兩個方法。
- registerBeanPostProcessors 按照一定順序注冊BeanPostProcessor
- 實例化所有的bean
至於注冊BeanPostProcessor較為簡單,就是將系統所有的BeanPostProcessor按照順序,即我們之前也遇到的三級順序來添加,實現了PriorityOrdered為第一級,實現了Ordered為第二級,其他的為第三級。具體添加過程較為簡單所以代碼部分略過,我們直接看實例化bean的方法
1.finishBeanFactoryInitialization 實例化的入口
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // 初始化一個ConversionService if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // 初始化一個默認的EmbeddedValueResolver(如果系統沒有指定的話) if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // 實例化LoadTimeWeaverAware getBean方法會觸發實例化 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); //實例化之前凍結配置 beanFactory.freezeConfiguration(); // 實例化所有非懶加載的實例 beanFactory.preInstantiateSingletons(); }
這兒就是做了一些必要的提前設置。這兒我們進入beanFactory.preInstantiateSingletons方法,注意這兒的beanFactory一般為DefaultListableBeanFactory,本系列第二章初始化應用上下文有講到
2.preInstantiateSingletons
顧名思義,看方法名就知道是實例化之前的一些准備,看代碼
@Override public void preInstantiateSingletons() throws BeansException { //打印下日志 if (this.logger.isDebugEnabled()) { this.logger.debug("Pre-instantiating singletons in " + this); } //迭代spring找到的所有需要注冊的bean List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); //開始迭代 for (String beanName : beanNames) { //獲取該bean對應的mergedBeanDefinition //如果沒有則獲取其父類的MergedLocalBeanDefinition //如果父類為空則創建RootBeanDefinition RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //如果不是抽象類 且是單例構造 非懶加載 則實例化 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //如果該bean是FactoryBean if (isFactoryBean(beanName)) { //如果是FactoryBean則要判斷下其是否需要提早初始化 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { final FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { //非factoryBean 初始化 getBean(beanName); } } } // 如果為SmartInitializingSingleton類型 則執行下其初始化完成后的afterSingletonsInstantiated方法 for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
方法也就是獲取我們之前得到的beanDefinitionNames,然后挨個遍歷,如果其不為抽象類,且是單例加載,非延遲加載,那我們就對其進行實例化。然后根據beanName獲取其合並的BeanDefinition,也就是其BeanDefinition一直遞歸加上其父類的BeanDefinition,最終合並為一個RootBeanDefinition並返回,具體的這兒的分析可以查看這篇博客。https://blog.csdn.net/andy_zhang2007/article/details/86514320
獲取到合並的beanDefinition后,檢查其是否滿足加載的條件。這兒可以看出springboot滿足初始化即加載的條件主要由兩:單例記載,非懶加載。
然后會判斷當前迭代的bean是否是FactoryBean,如果是則進行特殊判斷處理下,這兒二者最終都會調用getBean方法來創建類。創建完成后如果該bean實現了SmartInitializingSingleton接口,則會執行下其afterSingletonsInstantiated方法。
其getBean方法是主要的創建方法,其實看到這兒也能發現。ApplicationContext方法的初始即實例化最終也是循環調用的BeanFactory的getBean方法。
3.getBean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { //獲取beanName final String beanName = transformedBeanName(name); Object bean; // 找下是否已經創建過 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 = getObjectForBeanInstance(sharedInstance, name, beanName, null); } //這兒則是創建流程 else { //重復聲明時有可能出現此問題 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } //查看父BeanFactory是否已經有了 如果有的話則返回父BeanFactory中的實例 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else 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); } } //標記該bean已經在開始被實例化 if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { //獲取合並BeanDefinition final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); //檢查下合並BeanDefinition 這兒主要檢查是否為抽象類 checkMergedBeanDefinition(mbd, beanName, args); // 獲取該bean的構造函數的參數 //如果該bean構造函數中依賴的參數中,有參數實例化也需要依賴該bean 那么直接報循環引用的錯誤 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } //如果沒有循環引用也直接先實例化其依賴 registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // 如果為scope為sington 那么只創建一個 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { 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; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } // 如果為scope為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 name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, () -> { 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; } } // 如果有合適的Converter 那么執行下converter轉換器的操作 返回轉換后的實例 if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } 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; }
該方法內容較多,但可以分步看
- 判斷是否已經創建中並能獲取實例,如果可以就返回,否則下一步
- 判斷一下重復加載的問題,然后查看父BeanFactory是否有該類,如果有則使用父類的getBean返回,否則下一步
- 判斷下循環循環引用的問題,如果構造函數有參數,但不存在循環引用,則先實例化構造參數
- 最終根據bean的scope來確定不同的初始化方式
- 根據初始化完成后的bean來尋找是否有合適的converter,如果有則轉換后返回,否則直接返回
這樣拆開看發現也就是spring很常規的一個判斷邏輯,由於不同scope只是創建的數量不一致,但是實例化bean是一致的,所以我們就直接看實例化singleton,也就是我們最常見的單例注冊。
4.單例化代碼的片段
上面的代碼中,我們着重看下創建單例的代碼片段。
if (mbd.isSingleton()) { //獲取創建后的實例 sharedInstance = getSingleton(beanName, () -> { try { //回調函數創建bean return createBean(beanName, mbd, args); } catch (BeansException ex) { //出現異常則將其銷毀 destroySingleton(beanName); throw ex; } }); //看當前的bean是一個普通的bean還是beanFactory //如果是普通的bean直接返回 //如果是factoryBean則返回其getObject方法的結果 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }
這兒可以看到通過getSingletom方法獲取bean,這個方法有個回調函數是用來創建bean的,可以得知具體創建bean的時機肯定是getSingleton中調用這個函數的時候。getSingletom則只是做了一些前后處理。那我們還是先看下回調函數中的createBean方法,畢竟這才是核心創建過程。
5.createBean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { //獲取該bean的合並BeanDefinition RootBeanDefinition mbdToUse = mbd; //查看當前RootBeanDefinition是否已經有resolveBeanClass 如果有的話直接clone一個beanDefinition Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } //檢查下所有的override方法 try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // 執行所有實現了InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法 // 這兒如果返回不為null 則就是自定義了返回的bean邏輯 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); } try { //執行doCreateBean創建bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } ../代碼省略 }
該方法內部照例做了一下准備,其中有個方法需要注意resolveBeforeInstantiation ,該方法會在實例化之前執行所有實現了InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法,如果返回值不為空則代表自定義了類實例化過程,這樣會直接返回bean而不會進行下面的所有操作。
然后執行doCreateBean創建實例對象。
6.doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // 實例化bean 如果factoryBeanInstance已經有了則將其remove掉 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //創建實例 instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); //檢查下創建出來的bean是否為null,例如我們從beanFactory中get為null 或者@Bean方法返回為null if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // 執行所有實現了MergedBeanDefinitionPostProcessor接口的類的postProcessMergedBeanDefinition方法 synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } //如果允許屬性值循環依賴,則將實例其放入一個singletonFactories緩存中,此時該類已經實例化但還未為屬性賦值 //如果該類依賴的屬性值實例化時依賴該類,那么就可以從這個singletonFactories提前拿到還未賦值的屬性值實例 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } Object exposedObject = bean; try { // 為實例賦屬性值 populateBean(beanName, mbd, instanceWrapper); //執行一些列初始化方法 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); } } //如果允許啟用提前暴露緩存 //對該結果再做一些特殊處理 if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // 如果bean是一次性的則將其注入一次性使用容器中 try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
該方法有幾個地方需要注意
- 實例化bean后檢查了該bean是否為null
- 執行了所有實現了實現了MergedBeanDefinitionPostProcessor接口的類的postProcessMergedBeanDefinition方法
- 如果出現了屬性值循環引用,且允許循環引用,那么會將實例化好但還未賦值的bean放入一個singletonFactories提前暴露容器中來解決屬性值循環引用
- 然后在為屬性賦值
- 然后執行初始化方法。
我們則簡要分析下這幾個步驟
6.1createBeanInstance創建實例
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // 確保beanClass可以被實例化 例如其是否為public Class<?> beanClass = resolveBeanClass(mbd, beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } //查看該類是否有定制的Supplier 如果有直接返回 Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } //查看該類是否為@Bean方法初始化 如果是的話執行方法邏輯 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... boolean resolved = false; boolean autowireNecessary = false; //如果初始化構造參數為null且能找到構造函數或者FactoryMethod(如果為factoryBean) if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; //查看其是否有@Autowired的參數 autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { //如果有@Autowaired參數則執行這個autowireConstructor方法 if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); } //如果沒有則執行instantiateBean方法 else { return instantiateBean(beanName, mbd); } } //如果上面沒找到有效的構造函數 就從BeanPostProcessor中查找 然后執行返回 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } // No special handling: simply use no-arg constructor. return instantiateBean(beanName, mbd); }
這兒步驟主要為
1.校驗是否能實例化
2.是否有定制的supplier,有則返回
3.是否為@Bean初始化,如果是則執行專門的實例化方法
4.如果傳入的構造參數為null,則根據自動注入的參數或者無參的方法來實例化。
5.如果傳入的參數不為null 或者需要的參數里有不是自動注入的,那么根據BeanPostProcessor找到合適的構造函數並實例化
這兒具體的對象創建過程由於篇幅就不講解了,可以根據各個方法進去仔細查看,不過大概能想到的應該就是根據傳入的參數反射創建實例,如果是@Bean方法創建的話應該是反射執行方法創建,如果需要代理的話則創建代理對象並返回。
6.2 applyMergedBeanDefinitionPostProcessors
這也是springBean生命周期中的一個重要步驟
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof MergedBeanDefinitionPostProcessor) { MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); } } }
該方法會執行所有的MergedBeanDefinitionPostProcessor 的postProcessMergedBeanDefinition方法。
6.3 處理屬性值循環引用addSingletonFactory
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
這兒注意getEarlyBeanReference又會執行所有實現了SmartInstantiationAwareBeanPostProcessor接口的getEarlyBeanReference方法。
此處其實就是利用了一個提前暴露的singletonFactories容器,將實例化但還未賦值的bean放置在其中,當循環引用的bean需要用到這個bean時就可以拿到還未賦值的bean。即可解決屬性值循環引用的問題。
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null"); synchronized (this.singletonObjects) { if (!this.singletonObjects.containsKey(beanName)) { this.singletonFactories.put(beanName, singletonFactory); //singletonFactories 提前暴露的Factories容器 this.earlySingletonObjects.remove(beanName);//singletonFactories 提前暴露的bean容器 this.registeredSingletons.add(beanName);// 已注冊的單例容器 } } }
注意這兒有兩個容器都涉及到提前引用 ,區別是earlySingletonObjects 放置的實例化的bean 而singletonFactories 放置的是實例化的bean的包裝。之所以加個包裝是為了獲取提前暴露的引用時可以執行SmartInstantiationAwareBeanPostProcessor接口的getEarlyBeanReference方法。
/** Cache of singleton factories: bean name --> ObjectFactory */ private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); /** Cache of early singleton objects: bean name --> bean instance */ private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
具體的處理循環引用的邏輯文章最后會單獨說下,這兒注意get
6.4 為屬性賦值
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { //判空 if (bw == null) { if (mbd.hasPropertyValues()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { // Skip property population phase for null instance. return; } } //檢查下是否需要賦值 如果有某個InstantiationAwareBeanPostProcessor返回未false 那么就跳過賦值操作 boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } if (!continueWithPropertyPopulation) { return; } //獲取要賦值的屬性值 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); //根據不同的來不同的注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // by name 例如@Resources if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // by type 例如@Autowied if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); //如果有對應的InstantiationAwareBeanPostProcessors則執行下其postProcessPropertyValues方法 if (hasInstAwareBpps || needsDepCheck) { if (pvs == null) { pvs = mbd.getPropertyValues(); } PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } if (pvs != null) { //將找到的屬性值賦上 applyPropertyValues(beanName, mbd, bw, pvs); } }
該方法檢查了下bean是否為空,和該bean是否需要賦值,然后找到了所有的InstantiationAwareBeanPostProcessor執行了下其postProcessPropertyValues (如果需要的話),最后將找到的值賦上。
6.5 初始化方法initializeBean
bean實例化后會執行initializeBean方法。該方法會執行很多bean生命周期相關的方法。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { //1.執行所有實現了BeanNameAware的setBeanName方法 //2.執行所有實現了BeanClassLoaderAware的setBeanClassLoader方法 //3.執行所有實現了BeanFactoryAware的setBeanFactory方法 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //執行所有實現了BeanPostProcessor的postProcessBeforeInitialization方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { //如果該類實現了InitializingBean接口,則執行afterPropertiesSet方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { //執行所有實現了BeanPostProcessor的postProcessAfterInitialization方法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
該方法會執行很多的spring生命周期的方法,首先會執行一堆的aware前置方法。然后執行BeanPostProcessor的postProcessBeforeInitialization,然后如果該類實現了InitializingBean則執行afterPropertiesSet方法,最后執行BeanPostProcessor的postProcessAfterInitialization方法(該方法可以關注下,spring aop功能正是基於此實現的)。此時創建bean的工作已經基本完成了。
7.回到getSingleton
上面所講的都是ObjectFactory的回調函數的實現內容,那么調用的時機,和調用的前后邏輯還需要我們了解一下。即本文第4節的getSingtone方法。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { //看下singletonObject中是否已經有了 如果沒有進入創建 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { //校驗一下是否正在創建中,如果正在創建中直接拋異常 if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } //將當前bean加入singletonsCurrentlyInCreation容器 beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { //執行回調函數的創建邏輯 singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } //從singletonsCurrentlyInCreation容器中移除該bean afterSingletonCreation(beanName); } if (newSingleton) { //將該bean添加到singletonObjects容器中 並從提前暴露的容器中移除 addSingleton(beanName, singletonObject); } } return singletonObject; } }
可以看到該類中主要核查防止了重復加載,然后通過回調函數獲取我們創建的bean后,將其從提前暴露的容器中移除,然后放入BeanFactory的真正的bean容器中。此時一個bean就算被創建完成已經可以正式使用了。
可以發現其中執行了很多的BeanPostProcessor和aware,這也是spring對bean的擴展性做的極高的一種體現。
到此spring初始化一個bean已經成功了。有關spring的具體加載流程簡要圖已經在一開始給出,可以對照着查看。而且spring的bean的生命周期除了銷毀部分,其他的基本就是上述的內容。
后記
關於spring解決屬性循環依賴的問題主要是如下的代碼。
protected Object getSingleton(String beanName, boolean allowEarlyReference) { //如果未從singletonObjects獲取到就要嘗試從提前暴露的容器中拿 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { //從提前暴露的容器中拿singletonObject singletonObject = this.earlySingletonObjects.get(beanName); //如果也為空 if (singletonObject == null && allowEarlyReference) { //那么嘗試從提前暴露的包裝容器中拿 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { //如果包裝容器不為空,那么就拿到其引用 然后添加到提前暴露容器中 並從提前暴露的包裝容器中移除 singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; }
可以看到在獲取bean時如果沒獲取到會嘗試從提前暴露容器中獲取,如果還是獲取不到就從提前暴露的包裝容器中獲取。如果能獲取到就將其從包裝容器中移除,設置到容器中。