Spring源碼學習(三)炒雞丁與populateBean沒區別
- 2019 年 10 月 4 日
- 筆記
邏輯說明
populateBean的流程 | 炒雞丁的流程 |
|---|---|
1.執行InstantiationAwareBeanPostProcessor 的postProcessAfterInstantiation (在設置屬性前去修改Bean的狀態,也可以控制是否繼續填充Bean) | 作為一個已婚男人炒菜之前,請示老婆,這很重要。 我:「我炒宮爆雞丁了,有特殊要求嗎?」 老婆大人:「沒有要求,炒吧」。 |
2.注入屬性到PropertyValues中(autowireByName/autowireByType) | 初步準備食材 準備雞肉,郫縣豆瓣醬,花生米,黃瓜 |
3.執行InstantiationAwareBeanPostProcessor的postProcessPropertyValues, 對解析完但未設置的屬性再進行處理 | 切菜 雞肉切丁,黃瓜切小塊。 |
4.對dependency-check屬性的支援,默認是不校驗 | |
5.將PropertyValues中的屬性值設置到BeanWrapper中 | 下鍋,炒熟出鍋 |
autowirebyType的大致邏輯
看了源碼總結如下:
- 不處理簡單屬性,即不處理:Enum,CharSequence,Number,Date,URI,Locale等。(具體可以查看org.springframework.beans.BeanUtils#isSimpleProperty這個方法。)
- 不對Object類型的屬性進行自動注入, 沒有意義,技術無法實現
- 解析依賴resolveDependency並設置到pvs中
- registerDependentBean 註冊當前依賴。
autowiredByType的源碼注釋
/** * Abstract method defining "autowire by type" (bean properties by type) behavior. * 抽象方法 定義 按類型注入 * <p>This is like PicoContainer default, in which there must be exactly one bean * of the property type in the bean factory. This makes bean factories simple to * configure for small namespaces, but doesn't work as well as standard Spring * behavior for bigger applications. * 類似PicoContainer(非常輕量級的Ioc容器),beanFactory中一個屬性類型必須有一個確切對應的bean * bean工廠很容易配置小的命名空間. * @param beanName the name of the bean to autowire by type 需要按類型注入的BeanName * @param mbd the merged bean definition to update through autowiring 合併後的BeanDefinition * @param bw the BeanWrapper from which we can obtain information about the bean BeanWrapper對象 * @param pvs the PropertyValues to register wired objects with 註冊屬性的屬性值 */ protected void autowireByType( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { //獲取類型轉換器 TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } //獲取需要 注入的 非簡單類型 /** * 簡單類型,詳見 * @see org.springframework.beans.BeanUtils#isSimpleProperty */ Set<String> autowiredBeanNames = new LinkedHashSet<>(4); 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類型的屬性進行自動注入, 沒有意義,技術無法實現 if (Object.class != pd.getPropertyType()) { //獲得屬性寫的方法 MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); // Do not allow eager init for type matching in case of a prioritized post-processor. // 假如實現了prioritized post-processor ,在進行類型匹配時,是不允許,eager初始化(熱載入)的 boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance()); DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); //解析依賴 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null) { pvs.add(propertyName, autowiredArgument); } for (String autowiredBeanName : autowiredBeanNames) { //註冊依賴 registerDependentBean(autowiredBeanName, beanName); if (logger.isTraceEnabled()) { logger.trace("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的邏輯。
一圖勝千言

源碼注釋
/** * Populate the bean instance in the given BeanWrapper with the property values * from the bean definition. * 填充bean的屬性 * @param beanName the name of the bean bean的名稱 * @param mbd the bean definition for the bean 合併後的Bean的定義 * @param bw the BeanWrapper with bean instance beanWrapper的對象 */ @SuppressWarnings("deprecation") // for postProcessPropertyValues 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. // 跳過沒有屬性,null實例 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. //給任何InstantiationWareBeanPostProcessors在設置屬性之前修改bean的狀態的機會。 // 例如,這可用於支援屬性注入 boolean continueWithPropertyPopulation = true; //InstantiationWareBeanPostProcessors 可以控制是否繼續填充bean if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } if (!continueWithPropertyPopulation) { return; } PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) { //根據名稱自動注入 autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) { //根據類型自動注入 autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { //有InstantiationAwareBeanPostProcessors 對象 if (pvs == null) { pvs = mbd.getPropertyValues(); } for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } } if (needsDepCheck) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } //檢查依賴Dependency-check checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null) { //將屬性值設置到Bean中 applyPropertyValues(beanName, mbd, bw, pvs); } }