從org.springframework.context.support.AbstractApplicationContext#refresh方法開發,進入到實例化全部的非懶加載的單實例Bean的finishBeanFactoryInitialization(beanFactory)的方法:html
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()的方法:spring
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(beanName)的方法:app
@Override public Object getBean(String name) throws BeansException { //真正的獲取Bean的邏輯 return doGetBean(name, null, null, false); }
該方法啥沒幹,又交給了幹活的doGetBean(name, null, null, false)方法:ide
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的三級緩存,用它來解決循環依賴:post
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; }
Spring只能解決單例對象的setter注入的循環依賴,不能解決構造器注入,也不能解決多實例的循環依賴,因此會拋Bean當前正在建立的異常,接着判斷是否有父工廠,有就調用父工廠的getBean,若是不是僅僅作類型檢查,而是建立Bean對象,則須要調用markBeanAsCreated方法進行標識ui
① 接着調用getMergedLocalBeanDefinition(beanName)進行Bean定義的合併方法以下:this
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))方法:spa
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); } }
① 進入到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了;
① 把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; }
mbd.isPrototype(),每次使用的時候再建立,由於不會加入到單實例緩衝池中,也就沒法解決循環依賴問題。
最後獲取全部的bean的名稱(至此全部的單實例的bean已經加入到單實例Bean的緩存池中,所謂的單實例緩存池實際上就是一個ConcurrentHashMap),遍歷全部的bean名稱,根據beanName從單例緩存池中獲取全部的對象,而後判斷是不是SmartInitializingSingleton類型,是再觸發實例化以後的方法afterSingletonsInstantiated;
完整的Spring IoC源碼解析見:Spring系列(三):Spring IoC源碼解析
① getBean流程圖:
② @AutoWired注入屬性和set方法注入流程圖:
總結:經過對Spring IoC的getBean流程分析,瞭解了Bean的建立過程,先到單實例緩存池(ConcurrentHashMap)中獲取,取不到就調用createBean建立,建立成功後加入到單實例緩存池(ConcurrentHashMap)中,下次獲取的時候直接從JVM級別的緩存中獲取,Bean的生命週期,以及如何用三級緩存解決循環依賴,還有就是多實例爲何不能解決循環依賴問題。