1 先贴出源码
源码及注释来自【Spring源码阅读】populateBean实现 依赖注入源码解析
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// pvs是一个MutablePropertyValues实例,里面实现了PropertyValues接口,提供属性的读写操作实现,同时可以通过调用构造函数实现深拷贝
// 在本例中,里面存在一个propertyValueList,里面只有一个propertyValue:key->value="student"->RuntimeBeanReference("<student>")
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// 空对象直接返回
return;
}
}
// 给InstantiationAwareBeanPostProcessors最后一次机会在属性注入前修改Bean的属性值
// 具体通过调用postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回
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;
}
// 根据Bean配置的依赖注入方式完成注入,默认是0,即不走以下逻辑,所有的依赖注入都需要在xml文件中有显式的配置
// 如果设置了相关的依赖装配方式,会遍历Bean中的属性,根据类型或名称来完成相应注入,无需额外配置
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
// 深拷贝当前已有的配置
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 根据名称进行注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// // 根据类型进行注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
// 结合注入后的配置,覆盖当前配置
pvs = newPvs;
}
// 容器是否注册了InstantiationAwareBeanPostProcessor
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 是否进行依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
// 过滤出所有需要进行依赖检查的属性编辑器
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// 如果有相关的后置处理器,进行后置处理
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
// 检查是否满足相关依赖关系,对应的depends-on属性,需要确保所有依赖的Bean先完成初始化
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
// 将pvs上所有的属性填充到BeanWrapper对应的Bean实例中,注意到这一步,TestBean的student属性还是RuntimeBeanReference,即还未解析实际的Student实例
applyPropertyValues(beanName, mbd, bw, pvs);
}
2 流程图
3 具体调试实例
3.1 实例1:使用@AutoWired
3.1.1 java bean代码
@Component
@PropertySource("classpath:db.properties")
public class AutoWiredBean {
@Autowired
private MessageService messageService;
@Value("${db.driver}")
private String driverClass;
}
public interface MessageService {
String getMessage();
}
@Service
public class MessageServiceImpl implements MessageService {
public String getMessage() {
return "hello world";
}
}
3.1.2 调试结果
- 既不走autowireByName,也不走autowireByType。
- 会调用AnnotationConfigApplicationContext的postProcessPropertyValues(),其具体功能及原理详见我的另一篇博客:spring 源码系列(六)- 处理@AutoWired和@Value的后置处理器AutowiredAnnotationBeanPostProcessor
- 虽然会创建一个pvs,但是length一直为0,即使走了postProcessPropertyValues(),pvs也一直是空着的,所以最后一步applyPropertyValues()什么都没干。
3.2 普通java bean
3.2.1 java bean代码
public class Person {
private String name;
public Person() {
}
public Person(String name){
this.name=name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person [name=" + name + "]";
}
}
@Component
public class TestBean {
private Person person;
public void echo() {
System.out.println("I'm a student : " + person);
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
3.2.2 调试结果
反复测试确认,使用普通bean的话,啥都没干。
3 总结
populateBean()方法虽然看上去比较复杂,但无论是AutoWireByType还是AutoWireByName都没有调用,同时从目前的测试来看:applyPropertyValues()好像也没调用。实际上就只是调用了属于InstantiationAwareBeanPostProcessor系列的Bean后置处理器的postProcessPropertyValues()方法。 尤其是AutowiredAnnotationBeanPostProcessor这个类。