在上一篇中我们分析完了
**createBean()**
,并详解讲解了三中创建单实例bean对象的方法,在bean实例创建出来之后,就是对bean的属性赋值和初始化操作,本篇我们继续往下分析。
1.populateBean()
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
/*这里是判断假如beanWrapper是空,但是mbd中的属性还有值,那就说明需要抛出异常,因为没法给一个null赋值。*/
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.
return;
}
}
/*在设置属性之前,给任何实例化的bean后处理器修改bean状态的机会。例如,这可以用来支持各种类型的属性注入。*/
/*
* mbd.isSynthetic()默认是false,取反成立。
* 判断有没有instantiationAwareBeanPostProcessors,条件成立说明有。
*/
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
/*这里又是后置处理器的一个调用点:实例化之后的调用,调用的是后置处理器的afterInstantiation方法。*/
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
/*返回值将决定当前实例需要在进行依赖注入处理,默认返回true*/
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
/*下面是处理依赖注入的逻辑*/
/*三元运算符获取属性,有就把属性赋值给pvs ,没有就给一个null*/
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
/*这里判断依赖注入是按照名字注入还是按照类型注入,根据不同的选择走不同的处理逻辑。*/
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
/*吧属性进行一个包装*/
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
/*按照名字注入,根据字段名称查找依赖bean完成注入*/
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
/*按照类型注入*/
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
/*相当于处理了依赖数据后的pvs*/
pvs = newPvs;
}
/*表示当前是否拥有instantiationAwareBeanPostProcessors需要执行*/
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
/*是否需要进行依赖检察,不重要*/
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
/*后置处理器的调用点*/
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
/*典型应用:@Autowired 注解的注入*/
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
/*将完成依赖注入(合并后的pvs)的信息应用到实例上去*/
/**
* 1.对man进行属性赋值的过程
* 2.对women进行属性赋值
*/
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
�
- 上来一套组合拳,先判断假如bean包装对象是空的,但是mbd中的属性还有值,那就说明需要抛出异常,因为没法给一个null赋值。
接下来就是在属性赋值之前,给任何实例化的bean后置处理器修改bean状态的机会。例如,这可以用来支持各种类型的属性注入。
**InstantiationAwareBeanPostProcessors**
这里又是一个后置处理器的调用点,实例化之后的调用,调用的是后置处理器的
**afterInstantiation**
方法。这个处理器的返回值将决定当前bean实例是否要进行属性注入,返回false则表示直接返回,默认返回true。�判断依赖注入按照名字注入还是按照类型注入,根据不同的选择走不同的处理逻辑。注意这里的处理并不是直接注入到bean中,而是解析到pvs中。
什么时候走这里? 必须显式的指定了配置了依赖,才会走这里。
- 如果是按照名字注入,就执行
**autowireByName()**
。 - 如果是按照类型注入,就执行
**autowireByType()**
。
- 判断当前是否还有
**InstantiationAwareBeanPostProcessors**
需要执行。 - 判断当前是否需要进行依赖检查、
- 如果还有
**InstantiationAwareBeanPostProcessors**
需要执行,循环执行后置处理器的方法 - 如果需要依赖检查,就走依赖检查的逻辑
- 如果合并后的依赖信息(pvs)不为空,就执行
**applyPropertyValues()**
进行属性赋值。
2.autowireByName()
�
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
/*bean实例中有该字段,且有该字段的setter方法,但是在bd中没有property属性。*/
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
/*便利查找出来的集合,完成依赖注入。*/
for (String propertyName : propertyNames) {
/*条件成立说明beanFactory存在当前属性的bean实例,可以注入,说明找到对应的依赖信息数据了*/
if (containsBean(propertyName)) {
/*拿到属性所对应的bean实例*/
Object bean = getBean(propertyName);
/*在属性里面追加一个property*/
pvs.add(propertyName, bean);
/*管理依赖信息*/
registerDependentBean(propertyName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
} else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
总结:autowireByName主要完成以下逻辑:
- 获取需要填充对象得非简单类型得属性名;
- 遍历第一步获取得属性名,调用getBean方法从容器中获取此属性名对应的object;
然后,如果能找到,则把此属性名和object对象保存到pvs的propertyValueList里面。
3.autowireByType()
�
protected void autowireByType( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { /*获取类型转换器*/ TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } 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()) { /*拿到setter方法*/ MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); // Do not allow eager init for type matching in case of a prioritized post-processor. boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered); /*包装成一个依赖描述信息对象*/ DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); /*解析器根据依赖描述信息查找对象,或者 容器没有该对象实例的话,但是有该类型的bd的话,也会调用getBeanByType生成对象。*/ Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); /*查询出来的依赖对象加入到pvs里面*/ 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); } } }
获取当前对象的非简单类型的属性名数组propertyNames;
- 遍历属性名数组propertyNames,获取当前属性名多对应的类型filedType;
- 通过filedType找到匹配的候选Bean对象;
- 把属性名以及bean对象添加到pvs的propertyValueList里面。
可以看到,无论是按照名字注入还是按照类型的注入方式,其实里面都会调用同一个公共的方法。**unsatisfiedNonSimpleProperties()**
,接下来分析这个方法是做什么的。
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
Set<String> result = new TreeSet<>();
/*拿到配置的properties集合*/
PropertyValues pvs = mbd.getPropertyValues();
/*拿到bean的所有字段信息,然后便利所有的字段信息*/
PropertyDescriptor[] pds = bw.getPropertyDescriptors();
/*
* 条件1成立说明 当前字段有setter方法
* 条件2成立说明 当前字段类型是否在忽略自动注入列表中,条件成立,说明不在。
* 条件3成立说明 当前字段不在xml或者其他方式的配置中配置过。
* 条件4成立说明 当前字段类型是不是简单的八种基本数据类型。基本数据类型不允许自动注入。当前字段不是基本数据类型。
* */
for (PropertyDescriptor pd : pds) {
if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
result.add(pd.getName());
}
}
return StringUtils.toStringArray(result);
}
4.applyPropertyValues()
大部分情况下,我们走属性注入的逻辑,其实都是对解析出来的依赖bean进行注入。我们来梳理一下大致的流程,看一下核心的逻辑即可。
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
// 为空直接返回
if (pvs == null || pvs.isEmpty()) {
return;
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (System.getSecurityManager() != null) {
if (bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
}
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());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
// 创建BeanDefinitionValueResolver解析器,用来解析未被解析的PropertyValue。
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// 开始遍历检查original中的属性,对未被解析的先解析/已解析的直接加入deepCopy中,最后再填充到具体的Bean实例中
List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
// 如果属性已经转化,直接添加
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
// 核心逻辑,解析获取实际的值
// 对于RuntimeReference,会解析拿到具体的beanName,最终通过getBean(beanName)拿到具体的对象
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
// 判断是否可以转换
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);
}
}
主要是关心下,解析出来的依赖,如果注入到当前正在执行属性赋值的bean对象。
**valueResolver.resolveValueIfNecessary()**
利用值解析器解析当前bean实例所依赖的bean实例。
**resolveReference()**
通过这个方法去拿到当前属性赋值的bean需要注入的bean。
**this.beanFactory.getBean()**
最终这里又递归回到了getBean()去获取所需要的bean对象。
**registerDependentBean()**
在获取到bean对象之后,会将获取到的bean对象注册到当前bean所依赖的bean集合。
至此,单实例bean的属性赋值大体流程我们就分析完了,下一篇我们将去分析单实例bean的初始化逻辑。
�
�
�