spring源码对属性赋值 populateBean (XML)

前篇传送门
上篇文章了解了spring注解是如何进行赋值操作,接下继续看看xml配置是如何进行赋值的
先想一个问题,xml中配置有哪些类型?

  1. RuntimeBeanReference bean对象
  2. RuntimeBeanNameReference
  3. BeanDefinitionHolder
  4. BeanDefinition
  5. DependencyDescriptor
  6. ManagedArray 数组
  7. ManagedList List集合
  8. ManagedSet set集合
  9. ManagedMap map
  10. ManagedProperties
  11. 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赋值的时候处理过程有点繁琐,总的来说属性赋值也是咱们在开发的过程中用到比较多的一环。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值