Spring原始碼學習(三)炒雞丁與populateBean沒區別
阿新 • • 發佈:2019-10-01
的postProcessAfterInstantiation
(在設定屬性前去修改Bean的狀態,也可以控制是否繼續填充Bean)
作為一個已婚男人炒菜之前,請示老婆,這很重要。
我:“我炒宮爆雞丁了,有特殊要求嗎?”
老婆大人:“沒有要求,炒吧”。
初步準備食材
準備雞肉,郫縣豆瓣醬,花生米,黃瓜
3.執行InstantiationAwareBeanPostProcessor的postProcessPropertyValues,
對解析完但未設定的屬性再進行處理
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);
}
}