站在设计者的角度设计populateBean:
-
调用Bean的Setter方法实例去给Bean设置上属性值
-
变量类型的转换,同时还要考虑处理集合类型的情况
- 配置的时候都是以字符串的形式来配置的
-
处理显式自动装配的逻辑(autowire = byName或byType)
用两个类来做测试,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 {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
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;
}
}
}
}
// 如果上面设置continueWithPropertyPopulation = false,表明用户可能已经自己填充了
// bean的属性,不需要Spring帮忙填充了。此时直接返回即可
if (!continueWithPropertyPopulation) {
return;
}
// pvs是一个MutablePropertyValues实例,里面实现了PropertyValues接口,
// 提供属性的读写操作实现,同时可以通过调用构造函数实现深拷贝
// 获取BeanDefinition里面为Bean设置上的属性值
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.
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