一、實例化所有的非懶加載的單實例Bean
從org.springframework.context.support.AbstractApplicationContext#refresh方法開發,進入到實例化所有的非懶加載的單實例Bean的finishBeanFactoryInitialization(beanFactory)的方法:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // 為Bean工廠設置類型轉化器 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)); } // Register a default embedded value resolver if no bean post-processor // (such as a PropertyPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(new StringValueResolver() { @Override public String resolveStringValue(String strVal) { return getEnvironment().resolvePlaceholders(strVal); } }); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. 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); //凍結所有的Bean定義 , 至此注冊的Bean定義將不被修改或任何進一步的處理 beanFactory.freezeConfiguration(); //實例化剩下的單實例Bean beanFactory.preInstantiateSingletons(); }
進入實例化剩下的單實例Bean的beanFactory.preInstantiateSingletons()的方法:
public void preInstantiateSingletons() throws BeansException { if (logger.isDebugEnabled()) { logger.debug("Pre-instantiating singletons in " + this); } //獲取我們容器中所有Bean定義的名稱 List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); //循環我們所有的bean定義名稱 for (String beanName : beanNames) { //合並我們的bean定義 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //根據bean定義判斷是不是抽象的 && 不是單例的 && 不是懶加載的 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //是否FactoryBean if (isFactoryBean(beanName)) { //是 給beanName+前綴 & 符號 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()); } //調用真正的getBean if (isEagerInit) { getBean(beanName); } } } else {//非工廠Bean就是普通的bean getBean(beanName); } } } //獲取所有的bean的名稱 至此所有的單實例的bean已經加入到單實例Bean的緩存池中,所謂的單實例緩存池實際上就是一個ConcurrentHashMap for (String beanName : beanNames) { //從單例緩存池中獲取所有的對象 Object singletonInstance = getSingleton(beanName); //判斷當前的bean是否實現了SmartInitializingSingleton接口 if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { //觸發實例化之后的方法afterSingletonsInstantiated smartSingleton.afterSingletonsInstantiated(); } } } }
前面多個地方涉及到getBean,接下來就分析下getBean(很重要)
二、getBean流程
進入getBean(beanName)的方法:
@Override public Object getBean(String name) throws BeansException { //真正的獲取Bean的邏輯 return doGetBean(name, null, null, false); }
該方法啥沒干,又交給了干活的doGetBean(name, null, null, false)方法:
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { //在這里傳入進來的name可能是別名、也有可能是工廠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 + "'"); } } /** * 如果sharedInstance是普通的單例bean,下面的方法會直接返回。但如果 * sharedInstance是FactoryBean類型的,則需調用getObject工廠方法獲取真正的 * bean實例。如果用戶想獲取 FactoryBean 本身,這里也不會做特別的處理,直接返回 * 即可。畢竟 FactoryBean 的實現類本身也是一種 bean,只不過具有一點特殊的功能而已。 */ bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { //Spring只能解決單例對象的setter注入的循環依賴,不能解決構造器注入,也不能解決多實例的循環依賴 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } //判斷是否有父工廠 BeanFactory parentBeanFactory = getParentBeanFactory(); //若存在父工廠,切當前的bean工廠不存在當前的bean定義,那么bean定義是存在於父beanFactory中 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { //獲取bean的原始名稱 String nameToLookup = originalBeanName(name); //若為AbstractBeanFactory類型,委托父類處理 if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // 委托給構造函數getBean()處理 return (T) parentBeanFactory.getBean(nameToLookup, args); } else { // 沒有args,委托給標准的getBean()處理 return parentBeanFactory.getBean(nameToLookup, requiredType); } } /** * 方法參數typeCheckOnly ,是用來判斷調用getBean(...) 方法時,表示是否為僅僅進行類型檢查獲取Bean對象 * 如果不是僅僅做類型檢查,而是創建Bean對象,則需要調用markBeanAsCreated(String beanName) 方法,進行記錄 */ if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { //從容器中獲取beanName相應的GenericBeanDefinition對象,並將其轉換為RootBeanDefinition對象 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); //檢查當前創建的bean定義是不是抽象的bean定義 checkMergedBeanDefinition(mbd, beanName, args); //處理dependsOn的依賴(這個不是我們所謂的循環依賴 而是bean創建前后的依賴) //依賴bean的名稱 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { //beanName是當前正在創建的bean,dep是正在創建的bean的依賴的bean的名稱 if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } //保存的是依賴beanName之間的映射關系:依賴beanName -> beanName的集合 registerDependentBean(dep, beanName); try { //獲取dependsOn的bean getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } //是單例則創建單例Bean if (mbd.isSingleton()) { //把beanName和一個singletonFactory匿名內部類傳入用於回調 sharedInstance = getSingleton(beanName, () -> { try { //創建bean的邏輯 return createBean(beanName, mbd, args); } catch (BeansException ex) { //創建bean的過程中發生異常,需要銷毀關於當前bean的所有信息 destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } 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; } } // Check if required type matches the type of the actual bean instance. 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; }
第一步:先嘗試去緩存中獲取對象
Object sharedInstance = getSingleton(beanName),由於第一次肯定為空:
public Object getSingleton(String beanName) { //在這里系統一般是允許早期對象引用的allowEarlyReference通過這個參數可以控制解決循環依賴 return getSingleton(beanName, true); }
進入到getSingleton(beanName, true)方法,這里涉及到Spring的三級緩存,用它來解決循環依賴:
protected Object getSingleton(String beanName, boolean allowEarlyReference) { /** * 第一步:我們嘗試去一級緩存(單例緩存池中去獲取對象,一般情況從該map中獲取的對象是直接可以使用的) * Spring IoC容器初始化加載單實例bean的時候第一次進來的時候 該map中一般返回空 */ Object singletonObject = this.singletonObjects.get(beanName); /** * 若在第一級緩存中沒有獲取到對象,並且singletonsCurrentlyInCreation正在創建的單實例的list包含該beanName * Spring IoC容器初始化加載單實例bean的時候第一次進來的時候 該list中一般返回空,但是循環依賴的時候可以滿足該條件 */ if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { /** * 嘗試去二級緩存中獲取對象(二級緩存中的對象是一個早期對象) * 何為早期對象:就是bean剛剛調用了構造方法,還沒給bean的屬性進行賦值的對象就是早期對象 */ singletonObject = this.earlySingletonObjects.get(beanName); /** * 二級緩存中也沒有獲取到對象,allowEarlyReference為true(參數是有上一個方法傳遞進來的true) */ if (singletonObject == null && allowEarlyReference) { /** * 直接從三級緩存中獲取ObjectFactory對象 這個對接就是用來解決循環依賴的關鍵所在 * 在getBean的過程中,當bean調用了構造方法的時候,把早期對象包裹成一個ObjectFactory暴露到三級緩存中 */ ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); //從三級緩存中獲取到對象不為空 if (singletonFactory != null) { /** * 在這里通過暴露的ObjectFactory包裝對象中,通過調用他的getObject()來獲取我們的早期對象 * 在這個環節中會調用到 getEarlyBeanReference()來進行后置處理 */ singletonObject = singletonFactory.getObject(); //把早期對象放置在二級緩存, this.earlySingletonObjects.put(beanName, singletonObject); //ObjectFactory 包裝對象從三級緩存中刪除掉 this.singletonFactories.remove(beanName); } } } } return singletonObject; }
第二步:走else邏輯
Spring只能解決單例對象的setter注入的循環依賴,不能解決構造器注入,也不能解決多實例的循環依賴,所以會拋Bean當前正在創建的異常,接着判斷是否有父工廠,有就調用父工廠的getBean,如果不是僅僅做類型檢查,而是創建Bean對象,則需要調用markBeanAsCreated方法進行標識
合並Bean定義信息
① 接着調用getMergedLocalBeanDefinition(beanName)進行Bean定義的合並方法如下:
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { // 快速從緩存中獲取,如果不為空,則直接返回 RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); if (mbd != null) { return mbd; } //獲取 RootBeanDefinition 對象。若獲取的 BeanDefinition 為子 BeanDefinition,則需要合並父類的相關屬性. return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); }
② 進入到getMergedBeanDefinition(beanName, getBeanDefinition(beanName))方法:
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd) throws BeanDefinitionStoreException { //調用重載的方法 return getMergedBeanDefinition(beanName, bd, null); }
③ 進入到getMergedBeanDefinition(beanName, bd, null)的方法:
protected RootBeanDefinition getMergedBeanDefinition( String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) throws BeanDefinitionStoreException { //加鎖 synchronized (this.mergedBeanDefinitions) { RootBeanDefinition mbd = null; // Check with full lock now in order to enforce the same merged instance. if (containingBd == null) { mbd = this.mergedBeanDefinitions.get(beanName); } if (mbd == null) { //bd.getParentName() == null,表明無父配置,這時直接將當前的BeanDefinition升級為RootBeanDefinition if (bd.getParentName() == null) { //直接把原始的bean定義升級為RootBeanDefinition if (bd instanceof RootBeanDefinition) { mbd = ((RootBeanDefinition) bd).cloneBeanDefinition(); } else { //包裹為RootBeanDefinition mbd = new RootBeanDefinition(bd); } } //有父定義 else { BeanDefinition pbd; try { /* * 判斷父類beanName與子類beanName名稱是否相同。若相同,則父類bean一定 * 在父容器中。原因也很簡單,容器底層是用Map緩存<beanName, bean> 鍵值對 * 的。同一個容器下,使用同一個 beanName 映射兩個bean實例顯然是不合適的 */ String parentBeanName = transformedBeanName(bd.getParentName()); if (!beanName.equals(parentBeanName)) { pbd = getMergedBeanDefinition(parentBeanName); } else { /* * 這里再次調用getMergedBeanDefinition,只不過參數值變為了 * parentBeanName,用於合並父BeanDefinition 和爺爺輩的 * BeanDefinition。如果爺爺輩的BeanDefinition仍有父 * BeanDefinition,則繼續合並 */ BeanFactory parent = getParentBeanFactory(); if (parent instanceof ConfigurableBeanFactory) { pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName); } else { throw new NoSuchBeanDefinitionException(parentBeanName, "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName + "': cannot be resolved without an AbstractBeanFactory parent"); } } } catch (NoSuchBeanDefinitionException ex) { throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName, "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex); } //以父BeanDefinition的配置信息為基本創建RootBeanDefinition mbd = new RootBeanDefinition(pbd); //用子BeanDefinition中的屬性覆蓋父BeanDefinition中的屬性 mbd.overrideFrom(bd); } // 如果用戶未配置scope屬性,則默認將該屬性配置為singleton if (!StringUtils.hasLength(mbd.getScope())) { mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON); } // A bean contained in a non-singleton bean cannot be a singleton itself. // Let's correct this on the fly here, since this might be the result of // parent-child merging for the outer bean, in which case the original inner bean // definition will not have inherited the merged outer bean's singleton status. if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) { mbd.setScope(containingBd.getScope()); } //緩存合並后的BeanDefinition if (containingBd == null && isCacheBeanMetadata()) { this.mergedBeanDefinitions.put(beanName, mbd); } } return mbd; } }
④ 然后檢查當前創建的bean定義是不是抽象的bean定義,checkMergedBeanDefinition(mbd, beanName, args)方法:
protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args) throws BeanDefinitionStoreException { //抽象的bean定義是不能夠被實例化的 if (mbd.isAbstract()) { throw new BeanIsAbstractException(beanName); } }
處理dependsOn的依賴(這個不是我們所謂的循環依賴 而是bean創建前后的依賴)
① 進入到isDependent(beanName, dependentBeanName, null)的方法:
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) { //alreadySeen已經檢測的依賴bean if (alreadySeen != null && alreadySeen.contains(beanName)) { return false; } //獲取原始beanName String canonicalName = canonicalName(beanName); //獲取創建當前bean所依賴的bean的名稱集合 Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName); //不依賴任何前置Bean直接返回 if (dependentBeans == null) { return false; } //存在,則證明存在已經注冊的依賴 if (dependentBeans.contains(dependentBeanName)) { return true; } //遞歸檢測依賴 for (String transitiveDependency : dependentBeans) { if (alreadySeen == null) { alreadySeen = new HashSet<>(); } //添加到alreadySeen 中 alreadySeen.add(beanName); //遞歸檢查依賴 if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) { return true; } } return false; }
② 進入到保存的是依賴beanName之間的映射關系:依賴beanName -> beanName的集合registerDependentBean(dep, beanName)的方法:
public void registerDependentBean(String beanName, String dependentBeanName) { //獲取原始的beanName String canonicalName = canonicalName(beanName); // 添加 <canonicalName, dependentBeanName> 到 dependentBeanMap 中 synchronized (this.dependentBeanMap) { Set<String> dependentBeans = this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8)); if (!dependentBeans.add(dependentBeanName)) { return; } } // 添加 <dependentBeanName, canonicalName> 到 dependenciesForBeanMap 中 synchronized (this.dependenciesForBeanMap) { Set<String> dependenciesForBean = this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8)); dependenciesForBean.add(canonicalName); } }
③ 然后到獲取dependsOn的Bean的getBean(dep),就獲取到了dependsOn的Bean了;
處理單實例Bean
① 把beanName和一個singletonFactory匿名內部類傳入用於回調的getSingleton方法:
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); //加鎖 synchronized (this.singletonObjects) { //嘗試從單例緩存池中獲取對象 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 在這里會把beanName加入進來,若第二次循環依賴(構造器注入會拋出異常) */ beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { //創建bean這個過程其實是調用 createBean() 方法 singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { //回調我們singletonObjects的get方法,進行正在的創建bean的邏輯 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) { //加入緩存中 addSingleton(beanName, singletonObject); } } return singletonObject; } }
第一:先到單例緩存池中獲取對象獲取,有就返回沒有就繼續往下
第二:調用標記當前的bean馬上就要被創建了beforeSingletonCreation(beanName)方法:
protected void beforeSingletonCreation(String beanName) { //若singletonsCurrentlyInCreation沒有 則添加成功 if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) { throw new BeanCurrentlyInCreationException(beanName); }
第三:創建Bean的singletonFactory.getObject()其實是調用createBean()方法:
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. 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); } Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }
真正的創建我們的bean的實例對象的doCreateBean(beanName, mbdToUse, args)的方法:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { //BeanWrapper是對Bean的包裝,其接口中所定義的功能很簡單包括設置獲取被包裝的對象,獲取被包裝bean的屬性描述器 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { //從沒有完成的FactoryBean中移除 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //使用合適的實例化策略來創建新的實例:工廠方法、構造函數自動注入、簡單初始化 比較復雜也很重要 instanceWrapper = createBeanInstance(beanName, mbd, args); } //從beanWrapper中獲取我們的早期對象 final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { //進行后置處理@AutoWired的注解的預解析 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } /** * 該對象進行判斷是否能夠暴露早期對象的條件 * 單實例 this.allowCircularReferences 默認為true * isSingletonCurrentlyInCreation(表示當前的bean對象正在創建singletonsCurrentlyInCreation包含當前正在創建的bean) */ 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"); } //把我們的早期對象包裝成一個singletonFactory對象 該對象提供了一個getObject方法,該方法內部調用getEarlyBeanReference方法 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { //給我們的屬性進行賦值(調用set方法進行賦值) 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) { /** * 去緩存中獲取到我們的對象 由於傳遞的allowEarlyReference 是false 要求只能在一級二級緩存中去獲取 * 正常普通的bean(不存在循環依賴的bean) 創建的過程中,壓根不會把三級緩存提升到二級緩存中 */ Object earlySingletonReference = getSingleton(beanName, false); //能夠獲取到 if (earlySingletonReference != null) { //經過后置處理的bean和早期的bean引用還相等的話(表示當前的bean沒有被代理過) if (exposedObject == bean) { exposedObject = earlySingletonReference; } //處理依賴的bean 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."); } } } } // Register bean as disposable. try { //注冊銷毀的bean的銷毀接口 registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
① 實例化:使用合適的實例化策略來創建新的實例:工廠方法、構造函數自動注入、簡單初始化的createBeanInstance方法:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { //從bean定義中解析出當前bean的class對象 Class<?> beanClass = resolveBeanClass(mbd, beanName); //檢測類的訪問權限。默認情況下,對於非 public 的類,是允許訪問的。若禁止訪問,這里會拋出異常 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<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } //工廠方法,我們通過配置類來進行配置的話 采用的就是工廠方法 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } //判斷當前構造函數是否被解析過 boolean resolved = false; //有沒有必須進行依賴注入 boolean autowireNecessary = false; /** * 通過getBean傳入進來的構造函數是否來指定需要推斷構造函數 * 若傳遞進來的args不為空,那么就可以直接選出對應的構造函數 */ if (args == null) { synchronized (mbd.constructorArgumentLock) { //判斷我們的bean定義信息中的resolvedConstructorOrFactoryMethod(用來緩存我們的已經解析的構造函數或者工廠方法) if (mbd.resolvedConstructorOrFactoryMethod != null) { //修改已經解析過的構造函數的標志 resolved = true; //修改標記為ture 標識構造函數或者工廠方法已經解析過 autowireNecessary = mbd.constructorArgumentsResolved; } } } //若被解析過 if (resolved) { if (autowireNecessary) { //通過有參的構造函數進行反射調用 return autowireConstructor(beanName, mbd, null, null); } else { //調用無參數的構造函數進行創建對象 return instantiateBean(beanName, mbd); } } //通過bean的后置處理器進行選舉出合適的構造函數對象 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); //通過后置處理器解析出構造器對象不為null或獲取bean定義中的注入模式是構造器注入或bean定義信息ConstructorArgumentValues或獲取通過getBean的方式傳入的構造器函數參數類型不為null if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { //通過構造函數創建對象 return autowireConstructor(beanName, mbd, ctors, args); } //使用無參數的構造函數調用創建對象 return instantiateBean(beanName, mbd); }
判斷是否暴露早期對象條件滿足就暴露早期對象,把我們的早期對象包裝成一個singletonFactory對象 該對象提供了一個getObject方法,該方法內部調用getEarlyBeanReference方法:
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; //判讀我們容器中是否有InstantiationAwareBeanPostProcessors類型的后置處理器 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { //獲取我們所有的后置處理器 for (BeanPostProcessor bp : getBeanPostProcessors()) { //判斷我們的后置處理器是不是實現了SmartInstantiationAwareBeanPostProcessor接口 if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { //進行強制轉換 SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; //挨個調用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); } } } return exposedObject; }
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))方法:
/** * 該方法用於把早期對象包裝成一個ObjectFactory 暴露到三級緩存中 用於將解決循環依賴 * @param beanName the name of the bean * @param singletonFactory the factory for the singleton object */ protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null"); //加鎖 synchronized (this.singletonObjects) { //單例緩存池中沒有包含當前的bean if (!this.singletonObjects.containsKey(beanName)) { //加入到三級緩存中 暴露早期對象用於解決循環依賴 this.singletonFactories.put(beanName, singletonFactory); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } }
②屬性賦值:給我們的屬性進行賦值(調用set方法進行賦值)populateBean(beanName, mbd, instanceWrapper)方法:
/** *給我們的對象BeanWrapper屬性賦值 * @param beanName bean的名稱 * @param mbd bean的定義 * @param bw bean實例包裝對象 */ protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { //若bw為null的話,則說明對象沒有實例化 if (bw == null) { //進入if說明對象有屬性,bw為空,不能為他設置屬性,那就在下面就執行拋出異常 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 類型的后置處理器一個修改 * bean 狀態的機會。官方的解釋是:讓用戶可以自定義屬性注入。比如用戶實現一 * 個 InstantiationAwareBeanPostProcessor 類型的后置處理器,並通過 * postProcessAfterInstantiation 方法向 bean 的成員變量注入自定義的信息。 *當時我們發現系統中的的InstantiationAwareBeanPostProcessor.postProcessAfterInstantiationM沒有進行任何處理, *若我們自己實現了這個接口 可以自定義處理.....spring 留給我們自己擴展接口的 *特殊需求,直接使用配置中的信息注入即可。 */ boolean continueWithPropertyPopulation = true; //是否持有 InstantiationAwareBeanPostProcessor if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { //獲取容器中的所有的BeanPostProcessor for (BeanPostProcessor bp : getBeanPostProcessors()) { //判斷我們的后置處理器是不是InstantiationAwareBeanPostProcessor if (bp instanceof InstantiationAwareBeanPostProcessor) { //進行強制轉化 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; //若存在后置處理器給我們屬性賦值了,那么返回false 可以來修改我們的開關變量,就不會走下面的邏輯了 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { // 返回值為是否繼續填充 bean // postProcessAfterInstantiation:如果應該在 bean上面設置屬性則返回 true,否則返回 false // 一般情況下,應該是返回true 。 // 返回 false 的話,將會阻止在此 Bean 實例上調用任何后續的 InstantiationAwareBeanPostProcessor 實 continueWithPropertyPopulation = false; break; } } } } // 如果后續處理器發出停止填充命令,則終止后續操作 if (!continueWithPropertyPopulation) { return; } //獲取bean定義的屬性 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); /** * 判斷我們的bean的屬性注入模型 * AUTOWIRE_BY_NAME 根據名稱注入 * AUTOWIRE_BY_TYPE 根據類型注入 */ if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) { //把PropertyValues封裝成為MutablePropertyValues MutablePropertyValues newPvs = new MutablePropertyValues(pvs); //根據bean的屬性名稱注入 if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } //根據bean的類型進行注入 if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } //把處理過的 屬性覆蓋原來的 pvs = newPvs; } /** * 這里又是一種后置處理,用於在 Spring 填充屬性到 bean 對象前,對屬性的值進行相應的處理, * 比如可以修改某些屬性的值。這時注入到 bean 中的值就不是配置文件中的內容了, * 而是經過后置處理器修改后的內容 */ boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); //判斷是否需要檢查依賴 boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { if (pvs == null) { pvs = mbd.getPropertyValues(); } //提出當前正在創建的beanWrapper 依賴的對象 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); } } /** * 其實,上面只是完成了所有注入屬性的獲取,將獲取的屬性封裝在 PropertyValues 的實例對象 pvs 中, * 並沒有應用到已經實例化的 bean 中。而 #applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) 方法, * 則是完成這一步驟的 */ if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); } }
③初始化:進行對象初始化操作調用initializeBean,這里會進行Aware接口進行方法的回調,然后調用Bean的后置處理器的Before方法(postProcessorsBeforeInitialization),然后Bean的初始化方法,最后調用Bean的后置處理器的After方法(PostProcessorsAfterInitialization)
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 { //若我們的Bean實現了Aware接口進行方法的回調 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //調用我們的bean的后置處理器的postProcessorsBeforeInitialization方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { //調用初始化方法 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()) { //調用我們bean的后置處理器的PostProcessorsAfterInitialization方法 動態代理就是在這里實現的 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
進入調用初始化方法invokeInitMethods(beanName, wrappedBean, mbd)方法:
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { //判斷我們的容器中是否實現了InitializingBean接口 boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isDebugEnabled()) { logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); } if (System.getSecurityManager() != null) { try { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { ((InitializingBean) bean).afterPropertiesSet(); return null; }, getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { //回調InitializingBean的afterPropertiesSet()方法 ((InitializingBean) bean).afterPropertiesSet(); } } if (mbd != null && bean.getClass() != NullBean.class) { //我們beanClass中看是否有自己定義的init方法 String initMethodName = mbd.getInitMethodName(); //判斷自定義的init方法名稱不叫afterPropertiesSet if (StringUtils.hasLength(initMethodName) && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { //調用我們自己的初始化方法 invokeCustomInitMethod(beanName, bean, mbd); } } }
至此doCreateBean創建完成然后返回
接下來bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd),為什么不直接等於sharedInstance,原因可能剛剛創建的Bean是FactoryBean類型的Bean,如果是就要調用getObject方法來獲取真正的Bean,運用場景就是那些創建Bean的邏輯比較復雜的情況下可以用這個,比如Spring整合Mybatis的SqlSessionFactoryBean
getObjectForBeanInstance(sharedInstance, name, beanName, mbd)方法:
protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // 如果name以&開頭,但beanInstance卻不是FactoryBean,則認為有問題。 if (BeanFactoryUtils.isFactoryDereference(name)) { if (beanInstance instanceof NullBean) { return beanInstance; } if (!(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass()); } } /** * 如果上面的判斷通過了,表明 beanInstance 可能是一個普通的 bean,也可能是一個 * FactoryBean。如果是一個普通的 bean,這里直接返回 beanInstance 即可。如果是 * FactoryBean,則要調用工廠方法生成一個 bean 實例。 */ if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } Object object = null; if (mbd == null) { /** * 如果 mbd 為空,則從緩存中加載 bean。FactoryBean 生成的單例 bean 會被緩存 * 在 factoryBeanObjectCache 集合中,不用每次都創建 */ object = getCachedObjectForFactoryBean(beanName); } if (object == null) { // 經過前面的判斷,到這里可以保證beanInstance是 FactoryBean類型的,所以可以進行類型轉換 FactoryBean<?> factory = (FactoryBean<?>) beanInstance; // 如果 mbd 為空,則判斷是否存在名字為 beanName 的 BeanDefinition if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } //synthetic 字面意思是"合成的"。通過全局查找,我發現在 AOP 相關的類中會將該屬性設為 true。 //所以我覺得該字段可能表示某個 bean 是不是被 AOP 增強過,也就是 AOP 基於原始類合成了一個新的代理類。 //不過目前只是猜測,沒有深究 boolean synthetic = (mbd != null && mbd.isSynthetic()); //調用 getObjectFromFactoryBean 方法繼續獲取實例 object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
接着調用object = getObjectFromFactoryBean(factory, beanName, !synthetic)方法:
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { /** * FactoryBean 也有單例和非單例之分,針對不同類型的 FactoryBean,這里有兩種處理方式: * 1. 單例 FactoryBean 生成的 bean 實例也認為是單例類型。需放入緩存中,供后續重復使用 * 2. 非單例 FactoryBean 生成的 bean 實例則不會被放入緩存中,每次都會創建新的實例 **/ if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { //從緩存中取bean實例,避免多次創建bean實例 Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { //使用工廠對象中創建實例 object = doGetObjectFromFactoryBean(factory, beanName); // Only post-process and store if not put there already during getObject() call above // (e.g. because of circular reference processing triggered by custom getBean calls) Object alreadyThere = this.factoryBeanObjectCache.get(beanName); if (alreadyThere != null) { object = alreadyThere; } else { if (shouldPostProcess) { //判斷當地的bean是否正在創建 if (isSingletonCurrentlyInCreation(beanName)) { // Temporarily return non-post-processed object, not storing it yet.. return object; } beforeSingletonCreation(beanName); try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", ex); } finally { afterSingletonCreation(beanName); } } // 這里的beanName對應於FactoryBean的實現類,FactoryBean的實現類也會被實例化,並被緩存在singletonObjects中 if (containsSingleton(beanName)) { // 這里的beanName對應於FactoryBean的實現類,FactoryBean的實現類也會被實例化,並被緩存在singletonObjects中 this.factoryBeanObjectCache.put(beanName, object); } } } return object; } } else { Object object = doGetObjectFromFactoryBean(factory, beanName); if (shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex); } } return object; } }
使用工廠對象中創建實例object = doGetObjectFromFactoryBean(factory, beanName)方法:
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) throws BeanCreationException { Object object; try { if (System.getSecurityManager() != null) { AccessControlContext acc = getAccessControlContext(); try { object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { //真正的調用工廠bean的getObject()方法 object = factory.getObject(); } } catch (FactoryBeanNotInitializedException ex) { throw new BeanCurrentlyInCreationException(beanName, ex.toString()); } catch (Throwable ex) { throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex); } // Do not accept a null value for a FactoryBean that's not fully // initialized yet: Many FactoryBeans just return null then. if (object == null) { if (isSingletonCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException( beanName, "FactoryBean which is currently in creation returned null from getObject"); } object = new NullBean(); } return object; }
處理多實例Bean
mbd.isPrototype(),每次使用的時候再創建,因為不會加入到單實例緩沖池中,也就無法解決循環依賴問題。
至此doGetBean創建完成,返回,getBean創建完成
最后獲取所有的bean的名稱(至此所有的單實例的bean已經加入到單實例Bean的緩存池中,所謂的單實例緩存池實際上就是一個ConcurrentHashMap),遍歷所有的bean名稱,根據beanName從單例緩存池中獲取所有的對象,然后判斷是否是SmartInitializingSingleton類型,是再觸發實例化之后的方法afterSingletonsInstantiated;
完整的Spring IoC源碼解析見:Spring系列(三):Spring IoC源碼解析
三、getBean流程圖
① getBean流程圖:
② @AutoWired注入屬性和set方法注入流程圖:
總結:通過對Spring IoC的getBean流程分析,了解了Bean的創建過程,先到單實例緩存池(ConcurrentHashMap)中獲取,取不到就調用createBean創建,創建成功后加入到單實例緩存池(ConcurrentHashMap)中,下次獲取的時候直接從JVM級別的緩存中獲取,Bean的生命周期,以及如何用三級緩存解決循環依賴,還有就是多實例為什么不能解決循環依賴問題。