前篇传送门
上篇文章了解了spring注解是如何进行赋值操作,接下继续看看xml配置是如何进行赋值的
先想一个问题,xml中配置有哪些类型?
- RuntimeBeanReference bean对象
- RuntimeBeanNameReference
- BeanDefinitionHolder
- BeanDefinition
- DependencyDescriptor
- ManagedArray 数组
- ManagedList List集合
- ManagedSet set集合
- ManagedMap map
- ManagedProperties
- NullBean
AbstractAutowireCapableBeanFactory.applyPropertyValues 给xml属性赋值
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
// 在处理注解的时候进行了过滤
if (pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
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());
}
// bw也是一个TypeConverter
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
// 这里就是就是对bean工厂、bean名称、bean定义信息、类型转换器的一个包装
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// 没搞明白这里为什么要搞深拷贝,猜测有两个对象值相互转换
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();
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
// 获取的其实是set方法
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
}
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
// 获取对应的值(bean对象会执行getBean一套流程)
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
// 下面这些处理操作无非就是判断对应的数据是否需要进行转换操作
// 然后把属性和值封装后,放到deepCopy集合中,到时候统一对当前对象进行赋值操作
boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
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();
}
// 进行属性赋值操作
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}catch (BeansException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
BeanWrapper.setPropertyValues 给已经封装好的属性值赋值
for (PropertyValue pv : propertyValues) {
try {
setPropertyValue(pv);
}
}
PropertyHandler.setValue(valueToApply);
ReflectionUtils.makeAccessible(writeMethod);
// 不管他们怎么判断,最终还是通过反射进行赋值操作
// getWrappedInstance():当前的实例对象
// value就是咱们需要设置的值
writeMethod.invoke(getWrappedInstance(), value);
xml方式赋值和注解赋值很类似,只不过xml赋值的时候处理过程有点繁琐,总的来说属性赋值也是咱们在开发的过程中用到比较多的一环。