站在设计者的角度设计populateBean:
用两个类来做测试,GirlFriend 类中注入了BoyFriend 的实例,BoyFriend 中注入了自己的实例:
package com.wjw.dao.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class BoyFriend {
@Autowired
private BoyFriend boyFriend;
}
package com.wjw.dao.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class GirlFriend {
@Autowired
private BoyFriend boyFriend;
}
从AbstractAutowireCapableBeanFactory的doCreateBean 方法中进入
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
return;
}
}
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
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);
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.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) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
最开始是一些判空逻辑: 接下来的逻辑就是脑图里的第一步了:
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
首先判断出boyfriend不是spring内部特殊的bean
!mbd.isSynthetic()
再看下容器里是否已经注册了InstantiationAwareBeanPostProcessors级别的后置处理器,如果有则通过责任链模式调用这些后置处理器的postProcessAfterInstantiation方法
这里InstantiationAwareBeanPostProcessor会在属性注入之前,有最后一次机会去修改bean的属性值,此处也可以决定是否后续的填充步骤
continueWithPropertyPopulation = false;
if (!continueWithPropertyPopulation) {
return;
}
接下来来到:
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
pvs是一个MutablePropertyValues实例,里面实现了PropertyValues接口,提供属性的读写操作实现,同时可以通过调用构造函数实现深拷贝,获取BeanDefinition里面为Bean设置上的属性值 返回给pvs的是mbd.getPropertyValues()方法的返回值,
public MutablePropertyValues getPropertyValues() {
if (this.propertyValues == null) {
this.propertyValues = new MutablePropertyValues();
}
return this.propertyValues;
}
MutablePropertyValues类 bean的属性解析主要就是和这个类打交道的
回到populateBean 方法里,第一次解析 pvs 值为空,此时就来到脑图中的第二步,按照名字 or 类型对bean进行自动装配
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
返回结果是0,表示没有配置上自动装配模式,意味着会跳过populateBean 的自动装配逻辑。
之前介绍postProcessMergedBeanDefinition方法时,被@Value和@Autowired标记的成员变量已经被标记出来了,只差将其注入到bean实例里了,因此就没必要再走一遍解析了,所以就没必要执行if中的逻辑了。
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
可以看一看上面两种注入方法的逻辑。
autowireByName:
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
Object bean = getBean(propertyName);
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");
}
}
}
}
先获取非简单类型的属性名称,再根据获取出来的属性名称去依次调用容器的getBean方法获取属性名对应的bean实例,最后将获取到的bean实例连同属性的名称添加到属性列表pvs中,再将bean的依赖关系通过registerDependentBean方法给注册起来。
进入unsatisfiedNonSimpleProperties 方法里:
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
Set<String> result = new TreeSet<>();
PropertyValues pvs = mbd.getPropertyValues();
PropertyDescriptor[] pds = bw.getPropertyDescriptors();
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);
}
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);
if (Object.class != pd.getPropertyType()) {
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
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);
}
}
}
首先也是获得非简单类型属性名称:
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
然后再根据属性名获取属性描述符PropertyDescriptor :
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
然后根据属性描述符去获取方法参数对象MethodParameter :
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
之后再根据方法参数对象去获取依赖描述符对象DependencyDescriptor :
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
进入PropertyDescriptor : 主要就是用来描述bean里的主要属性,可以通过它获取到该属性的getter或setter
回到autowireByType ,
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
就是获得属性setter方法实例,保存到MethodParameter 实例中,该实例是封装setter的,方便后续注入,DependencyDescriptor 描述要注入的依赖 InjectionPoint 是用来描述注入点的,比如boyfriend中的girlfriend就是一个注入点,girlfriend的类型、setter、注解标签这些信息都可以通过InjectionPoint 来获取,DependencyDescriptor 除了上述的功能外,还保存了一些额外的信息,比如:依赖是否必要
public boolean isRequired() {
if (!this.required) {
return false;
}
if (this.field != null) {
return !(this.field.getType() == Optional.class || hasNullableAnnotation() ||
(KotlinDetector.isKotlinReflectPresent() &&
KotlinDetector.isKotlinType(this.field.getDeclaringClass()) &&
KotlinDelegate.isNullable(this.field)));
}
else {
return !obtainMethodParameter().isOptional();
}
}
是否是延迟加载的:
public boolean isEager() {
return this.eager;
}
相关的一些嵌套级别:
public void increaseNestingLevel() {
this.nestingLevel ++;
this.resolvableType = null;
if (this.methodParameter != null) {
this.methodParameter = this.methodParameter.nested();
}
}
回到autowireByType ,获取到DependencyDescriptor 之后就可以进行属性对应的值的解析了
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
autowiredArgument是属性的值,并将其与属性名一起添加到属性列表中
pvs.add(propertyName, autowiredArgument);
之后再注册一下bean之间的依赖关系
registerDependentBean(autowiredBeanName, beanName);
毕竟不是所有的依赖关系都是在配置里显式标注的。注册完成后就完成了该方法
|