知識回顧
上一篇介紹了Spring中三級快取的singletonObjects、earlySingletonObjects、singletonFactories,Spring在處理回圈依賴時在實體化后屬性填充前將一個lambda運算式放在了三級快取中,后續在獲取時進行了判斷,如果不需要進行物件代理,那么直接回傳物件Bean,然后將三級快取中的物件洗掉,然后放在二級快取中,后面在初始化之后又將二級快取中的物件放在了一級快取中,然后洗掉了二級快取中的物件,
然后介紹了Spring在進行代理物件的創建時,會使用SmartInstantiationBeanPostProcessor介面的getEarlyBeanReference方法進行創建,創建的時候會呼叫到AbstractAutoProxyCreator類的實作,最終以JDK或者CGLIB的方式進行代理的創建,當然這些細節講的不是很清晰,只是梳理了大致脈絡,后續還會進行較為詳細的梳理,敬請期待,
接下來繼續主流程的決議,Bean的屬性填充,
物件的屬性填充
一般來說屬性填充,可能會涉及到很多東西,比如填充的屬性是基本型別還是參考型別,填充的方式又可以分為按型別、按名稱還是其他的,然后填充時值的型別是否需要進行型別轉換等,
屬性填充:

屬性填充大致可以分為對基本型別的資料進行填充和對應用型別的資料填充,populateBean方法中代碼比較繁瑣,會設計到很多的遞回呼叫,最終決議并填充屬性,
在Spring中,實際上屬性填充大致可以分為四步:

- 使用
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation介面的呼叫,可以給機會在屬性填充前對Bean進行修改,并且可以定制欄位的填充 - 按照注入方式進行屬性的填充,最侄訓將決議到的屬性和參考放入
PropertyValues中- 按型別進行自動注入
- 按名稱進行自動注入
- 如果存在
InstantiationAwareBeanPostProcessor介面,那么回圈去呼叫postProcessProperties這個方法進行注解的注入,這里呼叫的實際上就是前面進行Bean的合并時決議的注解,比如:@Autowired、@Resource、@Value等 - 屬性值的處理和決議
- 創建一個
BeanDefinitionValueResolver值決議器 - 回圈去遍歷決議屬性值,決議程序中會用到型別轉換的轉換服務
ConversionService、SPEL運算式的決議、屬性編輯器PropertyEditor - 最終決議完,會呼叫到屬性的
set方法進行寫入
- 創建一個
這里貼一下屬性值決議的時候的原始碼:
public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
// We must check each value to see whether it requires a runtime reference
// to another bean to be resolved.
// 根據值物件的型別進行決議
if (value instanceof RuntimeBeanReference) {
// 運行時參考
RuntimeBeanReference ref = (RuntimeBeanReference) value;
return resolveReference(argName, ref);
}
else if (value instanceof RuntimeBeanNameReference) {
String refName = ((RuntimeBeanNameReference) value).getBeanName();
refName = String.valueOf(doEvaluate(refName));
if (!this.beanFactory.containsBean(refName)) {
throw new BeanDefinitionStoreException(
"Invalid bean name '" + refName + "' in bean reference for " + argName);
}
return refName;
}
else if (value instanceof BeanDefinitionHolder) {
// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
}
else if (value instanceof BeanDefinition) {
// Resolve plain BeanDefinition, without contained name: use dummy name.
BeanDefinition bd = (BeanDefinition) value;
String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
ObjectUtils.getIdentityHexString(bd);
return resolveInnerBean(argName, innerBeanName, bd);
}
else if (value instanceof DependencyDescriptor) {
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
Object result = this.beanFactory.resolveDependency(
(DependencyDescriptor) value, this.beanName, autowiredBeanNames, this.typeConverter);
for (String autowiredBeanName : autowiredBeanNames) {
if (this.beanFactory.containsBean(autowiredBeanName)) {
this.beanFactory.registerDependentBean(autowiredBeanName, this.beanName);
}
}
return result;
}
// 如果值是陣列
else if (value instanceof ManagedArray) {
// May need to resolve contained runtime references.
ManagedArray array = (ManagedArray) value;
Class<?> elementType = array.resolvedElementType;
if (elementType == null) {
String elementTypeName = array.getElementTypeName();
if (StringUtils.hasText(elementTypeName)) {
try {
elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
array.resolvedElementType = elementType;
}
catch (Throwable ex) {
// Improve the message by showing the context.
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Error resolving array type for " + argName, ex);
}
}
else {
elementType = Object.class;
}
}
return resolveManagedArray(argName, (List<?>) value, elementType);
}
// 如果值是list
else if (value instanceof ManagedList) {
// May need to resolve contained runtime references.
return resolveManagedList(argName, (List<?>) value);
}
// 如果值是set
else if (value instanceof ManagedSet) {
// May need to resolve contained runtime references.
return resolveManagedSet(argName, (Set<?>) value);
}
// 如果值是map
else if (value instanceof ManagedMap) {
// May need to resolve contained runtime references.
return resolveManagedMap(argName, (Map<?, ?>) value);
}
// 如果值是properties
else if (value instanceof ManagedProperties) {
Properties original = (Properties) value;
Properties copy = new Properties();
original.forEach((propKey, propValue) -> {
if (propKey instanceof TypedStringValue) {
propKey = evaluate((TypedStringValue) propKey);
}
if (propValue instanceof TypedStringValue) {
propValue = https://www.cnblogs.com/redwinter/p/evaluate((TypedStringValue) propValue);
}
if (propKey == null || propValue == null) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,"Error converting Properties key/value pair for " + argName + ": resolved to null");
}
copy.put(propKey, propValue);
});
return copy;
}
// 如果值是字串
else if (value instanceof TypedStringValue) {
// Convert value to target type here.
TypedStringValue typedStringValue = https://www.cnblogs.com/redwinter/p/(TypedStringValue) value;
// 校驗值,比如說使用spel運算式進行決議,然后得到這個值
Object valueObject = evaluate(typedStringValue);
try {
Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
if (resolvedTargetType != null) {
// 型別轉換
return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
}
else {
return valueObject;
}
}
catch (Throwable ex) {
// Improve the message by showing the context.
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,"Error converting typed String value for " + argName, ex);
}
}
else if (value instanceof NullBean) {
return null;
}
else {
return evaluate(value);
}
}
代碼比較長,大致的話就是對屬性進行分類處理,比如參考型別的,List、Map、Set、Properties、陣列、String型別的等,
如果在填充的程序中,發現需要的Bean不存在,那么又會進行getBean、doGetBean、createBean、doCreateBean的呼叫,然后遞回的入堆疊出堆疊呼叫,最終完成屬性的填充,
下篇繼續主流程中的Bean的初始化initializeBean呼叫的解讀,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/479201.html
標籤:Java
上一篇:golang 應用自升級
