总体流程总结:
当我们显示或者隐式地调用AbstractBeanFactory 的 getBean(...) 方法时,会触发 Bean 的加载。
对于不同作用域的 Bean,底层都会调用 AbstractAutowireCapableBeanFactory 的 createBean(...)方法进行创建。
创建 Bean 的过程中,获取到的一个实例对象后,需要获取相关属性值,然后注入到 Bean 中,其中获取属性值有三种模式:
AUTOWIRE_NO,默认,不获取相关属性值
AUTOWIRE_BY_NAME,通过名称获取没有定义属性值的"对象"的属性值,通过 getBean(String beanName) 查找
AUTOWIRE_BY_TYPE,通过类型获取没有定义属性值的"对象"的属性值,依赖注入的方式
默认情况下,获取到已定义的属性值后不会通过上面的方式去找属性值,在后续有一个属性值的后置处理,
会调用所有的 InstantiationAwareBeanPostProcessor 处理器的 postProcessProperties 方法进行处理,例如 Spring 内部有两个 InstantiationAwareBeanPostProcessor 处理器:
AutowiredAnnotationBeanPostProcessor,解析 @Autowired 和 @Value 注解标注的属性,获取对应属性值
CommonAnnotationBeanPostProcessor,会解析 @Resource 注解标注的属性,获取对应的属性值
在获取到所有的属性值后然后通过反射机制设置到 Bean 中
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
// <1> 没有相关属性值,则直接 `return` 返回
if (pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
// ------------------------开始属性值的转换与填充------------------------
MutablePropertyValues mpvs = null;
// 定义一个 `original` 集合,承载属性值(未进行转换)
List<PropertyValue> original;
// <2> 如果 `pvs` 是 MutablePropertyValues 类型,则可能已经处理过了
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
// <2.1> 属性值已经转换了,则将这些属性值设置到当前 Bean 中(反射机制),依赖注入的最终实现!!!
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
// <2.2> 没有转换过,则获取所有的属性值集合
original = mpvs.getPropertyValueList();
}
else {
// <2.2> 获取所有的属性值集合
original = Arrays.asList(pvs.getPropertyValues());
}
// 获取 TypeConverter 类型转换器,用于取代默认的 PropertyEditor 类型转换器
// 例如 Spring 3.0 之后的 ConversionService
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
// 获取对应的解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
// <3> 定义一个 `deepCopy` 集合,保存转换后的属性值
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
// <4> 遍历所有的属性值,进行转换(如果有必要)
for (PropertyValue pv : original) {
// <4.1> 已经转换过,则直接添加到 `deepCopy` 中
if (pv.isConverted()) {
deepCopy.add(pv);
}
// <4.2> 否则,开始进行转换
else {
String propertyName = pv.getName();
// 转换之前的属性值
Object originalValue = pv.getValue();
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
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);
}
// <4.2.1> 表达式的处理(如果有必要的话),例如你在 XML 配置的属性值为 `${systenm.user}`,则会解析出对应的值
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
// 转换之后的属性值
Object convertedValue = resolvedValue;
// 该属性是否可以转换
boolean convertible = bw.isWritableProperty(propertyName) && // 属性可写
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);// 不包含 `.` 和 `[`
if (convertible) {
// <4.2.2> 使用类型转换器转换属性值(如果有必要的话)
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {// 属性值没有转换过
if (convertible) {
// <4.2.3> 设置转换后的值,避免上面的各种判断
pv.setConvertedValue(convertedValue);
}
// <4.2.4> 添加到 `deepCopy` 中
deepCopy.add(pv);
}
// 属否则属性值进行了转换
else if (convertible // 可转换的
&& originalValue instanceof TypedStringValue && // 属性原始值是字符串类型
!((TypedStringValue) originalValue).isDynamic() && // 属性的原始类型值不是动态生成的字符串
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) { // 属性的原始值不是集合或者数组类型
// <4.2.3> 设置转换后的值,避免上面的各种判断
pv.setConvertedValue(convertedValue);
// <4.2.4> 添加到 `deepCopy` 中
deepCopy.add(pv);
}
// 否则
else {
// 这个属性每次都要处理,不能缓存
resolveNecessary = true;
// <4.2.4> 添加到 `deepCopy` 中
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
// <5> 如果属性值不为空,且不需要每次都处理,则设置为已转换
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
// <6> 将属性值设置到当前 Bean 中(反射机制),依赖注入的最终实现!!!
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
过程大致如下:
没有相关属性值,则直接 return 返回
开始属性值的转换与填充,先定义一个 original 集合,承载属性值(未进行转换)
如果 pvs 是 MutablePropertyValues 类型,则可能已经处理过了,否则,获取所有的属性值集合,放入 original 集合中
属性值已经转换了,则将这些属性值设置到当前 Bean 中(反射机制),依赖注入的最终实现!!!
调用 BeanWrapperImpl#setPropertyValues(PropertyValues) 方法
没有转换过,则获取所有的属性值集合,放入 original 集合中
定义一个 deepCopy 集合,保存转换后的属性值
遍历所有的属性值,进行转换(如果有必要)
已经转换过,则直接添加到 deepCopy 中
否则,开始进行转换
表达式的处理(如果有必要的话),例如你在 XML 配置的属性值为 ${systenm.user},则会解析出对应的值
使用类型转换器转换属性值(如果有必要的话)
设置转换后的值,避免上面的各种判断
添加到 deepCopy 中
如果属性值不为空,且不需要每次都处理,则设置为已转换
将属性值设置到当前 Bean 中(反射机制),依赖注入的最终实现
调用 BeanWrapperImpl#setPropertyValues(PropertyValues) 方法
整个属性注入过程非常复杂,上面仅列出了关键步骤,可以看到最终会调用 BeanWrapperImpl#setPropertyValues(PropertyValues) 方法将属性值设置到 Bean 中
在 Bean 的实例化阶段获取到的就是一个 BeanWrapperImpl 对象,所以这里调用的就是当前 Bean 的 setPropertyValues(PropertyValues) 方法,该方法的底层借助于 Java Beans 的 java.beans.PropertyDescriptor 属性描述器,获取到对应的写方法,然后通过反射机制设置当前 Bean 的属性值