這篇是Spring專題Bean初始化的第二篇,主要對bean初始化具體過程的源碼分析。上篇博客Spring專題之Bean初始化源碼分析(1)中咱們對Spring如何開始初始化bean以及bena初始化的整體過程有了大體的瞭解,接下來就繼續上篇博客的結尾處開始來分析初始化bean的具體過程。segmentfault
上篇博客中咱們知道了Spring在經過判斷bean定義是不是單例bean,是不是原型bena以後,最後都是調用了createBean方法去建立bean的,因此咱們進入該方法分析具體初始化過程。進入方法後發現是該方法是AbstractBeanFactory的一個抽象方法,真正地調用是在子類AbstractAutowireCapableBeanFactory中重寫了。源碼以下:數組
//建立Bean實例對象 protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; //判斷須要建立的Bean是否能夠實例化,便是否能夠經過當前的類加載器加載 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } //校驗和準備Bean中的方法覆蓋 try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { //若是Bean配置了初始化前和初始化後的處理器,則試圖返回一個須要建立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 { //建立Bean的入口 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException ex) { throw ex; } catch (ImplicitlyAppearedSingletonException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
這裏咱們有兩個地方須要瞭解的,第一個是resolveBeforeInstantiation方法,第二個是doCreateBean方法。以後咱們重點分析doCreateBean方法,這裏的resolveBeforeInstantiation方法主要是針對Bean若是配置了初始化前和初始化後的處理器,會試圖返回一個須要建立Bean的代理對象。那麼如今咱們開始進入doCreateBean方法,源碼以下:緩存
//真正建立Bean的方法 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { //封裝被建立的Bean對象 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(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } //調用PostProcessor後置處理器 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; } } //向容器中緩存單例模式的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"); } //這裏是一個匿名內部類,爲了防止循環引用,儘早持有對象的引用 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } //Bean對象的初始化,依賴注入在此觸發 //這個exposedObject在初始化完成以後返回做爲依賴注入完成後的Bean Object exposedObject = bean; try { //將Bean實例對象封裝,而且Bean定義中配置的屬性值賦值給實例對象 populateBean(beanName, mbd, instanceWrapper); //初始化Bean對象 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) { //獲取指定名稱的已註冊的單例模式Bean對象 Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { //根據名稱獲取的已註冊的Bean和正在實例化的Bean是同一個 if (exposedObject == bean) { //當前實例化的Bean初始化完成 exposedObject = earlySingletonReference; } //當前Bean依賴其餘Bean,而且當發生循環引用時不容許新建立實例對象 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); //獲取當前Bean所依賴的其餘Bean for (String dependentBean : dependentBeans) { //對依賴Bean進行類型檢查 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. //註冊完成依賴注入的Bean try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
這裏有三個方法咱們須要注意,第一個createBeanInstance方法,這是bean實例化的第一步,第二個是populateBean方法,這是bean依賴注入的地方,第三個是initializeBean,這是初始化bean的地方。安全
首先咱們先看createBeanInstance方法,源碼以下:app
//建立Bean的實例對象 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // Make sure bean class is actually resolved at this point. //檢查確認Bean是可實例化的 Class<?> beanClass = resolveBeanClass(mbd, beanName); //使用工廠方法對Bean進行實例化 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); } // Shortcut when re-creating the same bean... //使用容器的自動裝配方法進行實例化 boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { if (autowireNecessary) { //配置了自動裝配屬性,使用容器的自動裝配實例化 //容器的自動裝配是根據參數類型匹配Bean的構造方法 return autowireConstructor(beanName, mbd, null, null); } else { //使用默認的無參構造方法實例化 return instantiateBean(beanName, mbd); } } // Need to determine the constructor... //使用Bean的構造方法進行實例化 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); }
經過上述的源碼分析,咱們知道Spring這裏對bean實例化有幾種方式,分別是工廠方法實例化,容器自動裝配以及使用默認的無參構造方法實例化。ide
而後咱們在來看populateBean方法是如何進行依賴注入的,源碼以下:源碼分析
//將Bean屬性設置到生成的實例對象上 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; } } // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the // state of the bean before properties are set. This can be used, for example, // to support styles of field injection. //使得InstantiationAwareBeanPostProcessors有機會在屬性注入以前修改bean的狀態,例如支持一些屬性類型的注入。 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; } //獲取容器在解析Bean定義資源時爲BeanDefiniton中設置的屬性值 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); //對依賴注入處理,首先處理autowiring自動裝配的依賴注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. //根據Bean名稱進行autowiring自動裝配處理 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. //根據Bean類型進行autowiring自動裝配處理 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } //對非autowiring的屬性進行依賴注入處理 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); 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); } }
這裏有也有幾個方法須要注意,分別是autowireByName、autowireByType以及applyPropertyValues。
咱們先來看下autowireByName方法,源碼以下:post
//根據名稱對屬性進行自動依賴注入 protected void autowireByName( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { //對Bean對象中非簡單屬性(不是簡單繼承的對象,如8中原始類型,字符串,URL等都是簡單屬性)進行處理 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { //若是Spring IOC容器中包含指定名稱的Bean if (containsBean(propertyName)) { //調用getBean方法向IOC容器索取指定名稱的Bean實例,迭代觸發屬性的初始化和依賴注入 Object bean = getBean(propertyName); //爲指定名稱的屬性賦予屬性值 pvs.add(propertyName, bean); //指定名稱屬性註冊依賴Bean名稱,進行屬性依賴注入 registerDependentBean(propertyName, beanName); if (logger.isDebugEnabled()) { logger.debug("Added autowiring by name from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + propertyName + "'"); } } else { if (logger.isTraceEnabled()) { logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName + "' by name: no matching bean found"); } } } }
能夠看到這裏經過找到Bean中非簡單屬性的屬性,好比CharSequence類型、Number類型、Date類型、URL類型、URI類型、Locale類型、Class類型就會忽略,具體可見BeanUtils的isSimpleProperty方法,遍歷全部被找到的屬性,若是bean定義中包含了屬性名,那麼先實例化該屬性名對應的bean,註冊一下當前bean的依賴bean。this
而後咱們看下根據類型自動裝配autowireByType方法的實現,源碼以下:debug
//根據類型對屬性進行自動依賴注入 protected void autowireByType( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { //獲取用戶定義的類型轉換器 TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } //存放解析的要注入的屬性 Set<String> autowiredBeanNames = new LinkedHashSet<>(4); //對Bean對象中非簡單屬性(不是簡單繼承的對象,如8中原始類型,字符 //URL等都是簡單屬性)進行處理 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { try { //獲取指定屬性名稱的屬性描述器 PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); // Don't try autowiring by type for type Object: never makes sense, // even if it technically is a unsatisfied, non-simple property. //不對Object類型的屬性進行autowiring自動依賴注入 if (Object.class != pd.getPropertyType()) { //獲取屬性的setter方法 MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); // Do not allow eager init for type matching in case of a prioritized post-processor. //檢查指定類型是否能夠被轉換爲目標對象的類型 boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance()); //建立一個要被注入的依賴描述 DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); //根據容器的Bean定義解析依賴關係,返回全部要被注入的Bean對象 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null) { //爲屬性賦值所引用的對象 pvs.add(propertyName, autowiredArgument); } for (String autowiredBeanName : autowiredBeanNames) { //指定名稱屬性註冊依賴Bean名稱,進行屬性依賴注入 registerDependentBean(autowiredBeanName, beanName); if (logger.isDebugEnabled()) { logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + autowiredBeanName + "'"); } } //釋放已自動注入的屬性 autowiredBeanNames.clear(); } } catch (BeansException ex) { throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex); } } }
具體的解析過程主要看resolveDependency方法,這裏感興趣的同窗能夠研究下具體過程。
最後咱們來看下applyPropertyValues方法,源碼以下:
//解析並注入依賴屬性的過程 protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { if (pvs.isEmpty()) { return; } //封裝屬性值 MutablePropertyValues mpvs = null; List<PropertyValue> original; if (System.getSecurityManager() != null) { if (bw instanceof BeanWrapperImpl) { //設置安全上下文,JDK安全機制 ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); } } if (pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues) pvs; //屬性值已經轉換 if (mpvs.isConverted()) { // Shortcut: use the pre-converted values as-is. try { //爲實例化對象設置屬性值 bw.setPropertyValues(mpvs); return; } catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values", ex); } } //獲取屬性值對象的原始類型值 original = mpvs.getPropertyValueList(); } else { original = Arrays.asList(pvs.getPropertyValues()); } //獲取用戶自定義的類型轉換 TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } //建立一個Bean定義屬性值解析器,將Bean定義中的屬性值解析爲Bean實例對象的實際值 BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter); // Create a deep copy, resolving any references for values. //爲屬性的解析值建立一個拷貝,將拷貝的數據注入到實例對象中 List<PropertyValue> deepCopy = new ArrayList<>(original.size()); boolean resolveNecessary = false; for (PropertyValue pv : original) { //屬性值不須要轉換 if (pv.isConverted()) { deepCopy.add(pv); } //屬性值須要轉換 else { String propertyName = pv.getName(); //原始的屬性值,即轉換以前的屬性值 Object originalValue = pv.getValue(); //轉換屬性值,例如將引用轉換爲IOC容器中實例化對象引用 Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); //轉換以後的屬性值 Object convertedValue = resolvedValue; //屬性值是否能夠轉換 boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName); if (convertible) { //使用用戶自定義的類型轉換器轉換屬性值 convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter); } // Possibly store converted value in merged bean definition, // in order to avoid re-conversion for every created bean instance. //存儲轉換後的屬性值,避免每次屬性注入時的轉換工做 if (resolvedValue == originalValue) { if (convertible) { //設置屬性轉換以後的值 pv.setConvertedValue(convertedValue); } deepCopy.add(pv); } //屬性是可轉換的,且屬性原始值是字符串類型,且屬性的原始類型值不是 //動態生成的字符串,且屬性的原始值不是集合或者數組類型 else if (convertible && originalValue instanceof TypedStringValue && !((TypedStringValue) originalValue).isDynamic() && !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) { pv.setConvertedValue(convertedValue); //從新封裝屬性的值 deepCopy.add(pv); } else { resolveNecessary = true; deepCopy.add(new PropertyValue(pv, convertedValue)); } } } if (mpvs != null && !resolveNecessary) { //標記屬性值已經轉換過 mpvs.setConverted(); } // Set our (possibly massaged) deep copy. //進行屬性依賴注入 try { bw.setPropertyValues(new MutablePropertyValues(deepCopy)); } catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values", ex); } }
這裏主要是對須要轉換的屬性進行轉換而後進行屬性值的依賴注入。
至此屬性的依賴注入分析結束,最後咱們看下initializeBean方法是如何對bean進行初始化操做的,其源碼以下:
//初始容器建立的Bean實例對象,爲其添加BeanPostProcessor後置處理器 protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { //JDK的安全機制驗證權限 if (System.getSecurityManager() != null) { //實現PrivilegedAction接口的匿名內部類 AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { //爲Bean實例對象包裝相關屬性,如名稱,類加載器,所屬容器等信息 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; //對BeanPostProcessor後置處理器的postProcessBeforeInitialization //回調方法的調用,爲Bean實例初始化前作一些處理 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } //調用Bean實例對象初始化的方法,這個初始化方法是在Spring Bean定義配置 //文件中經過init-method屬性指定的 try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } //對BeanPostProcessor後置處理器的postProcessAfterInitialization //回調方法的調用,爲Bean實例初始化以後作一些處理 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
至此,bean初始化操做的整體過程分析結束,固然中間存在一些細節方面的點沒有分析清楚,還須要各位小夥伴自行研究,而後有什麼問題能夠留言,你們一塊兒討論一塊兒進步。