这篇文章是 IOC
容器初始化启动时,抽象类 AbstractAutowireCapableBeanFactory
的 doCreateBean()
方法里面的 populateBean()
方法,它是进行 bean
的属性数据填充注入的方法
阅读本篇文章,同时可以参考阅读 spring源码之getBean(获取 bean)方法解读(二) 和 spring aop代理对象的产生(一) 这两篇文章的 doCreateBean()
方法
Java
实体public class Teacher {
private Student student;
public Teacher() {
System.out.println("Teacher 的无参构造器被调用了");
}
public Teacher(Student student) {
System.out.println("Teacher 的有参构造器被调用了");
this.student = student;
}
public void echo() {
System.out.println("I'm a student : " + student);
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
@Override
public String toString() {
return "Teacher{" +
"student=" + student +
'}';
}
}
public class Student {
private String name;
public Student() {
System.out.println("Student 的无参构造器被调用了");
}
public Student(String name) {
System.out.println("Student 的有参构造器被调用了");
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
xml
配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="student" class="com.atguigu.pojo.Student">
<property name="name" value="小吉">property>
bean>
<bean id="teacher" class="com.atguigu.pojo.Teacher" autowire="byType">
bean>
beans>
public class Test2 {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-spring.xml");
Teacher teacher = (Teacher) applicationContext.getBean("teacher");
teacher.toString();
}
}
populateBean()
源码概览类 AbstractAutowireCapableBeanFactory
的 populateBean()
方法
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
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;
}
// pvs 是一个 MutablePropertyValues 实例,里面实现了PropertyValues接口,提供属性的读写操作实现,同时可以通过调用构造函数实现深拷贝
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 根据bean的依赖注入方式:即是否标注有 @Autowired 注解或 autowire=“byType/byName” 的标签
// 会遍历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实例中
applyPropertyValues(beanName, mbd, bw, pvs);
}
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
方法,可以决定程序是否继续进行属性填充。只要有一个 InstantiationAwareBeanPostProcessor
返回 false
,都会终止属性填充的过程@Autowired
注解或 autowire=“byType/byName”
标签,则根据 BY_NAME
或 BY_TYPE
,提取相应依赖的 bean
,并统一存入到 propertyValues
中InstantiationAwareBeanPostProcessor.postProcessProperties()
和 InstantiationAwareBeanPostProcessor.postProcessPropertyValues()
方法,对属性获取完毕填充前对属性的再次处理propertyValues
中的属性填充至 BeanWrapper
中populateBean()
源码详解 // 根据bean的依赖注入方式:即是否标注有 @Autowired 注解或 autowire=“byType/byName” 的标签
// 会遍历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;
}
如果 bean
在声明的时候指定了自动注入类型是 byName
或 byType
,则会根据这个规则,对 bean
内部排除某些特定的属性,进行 byName
或 byType
的自动装配
autowireByName()
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 根据bw的PropertyDescriptors,遍历出所有可写的(即set方法存在),存在于BeanDefinition里的PropertyValues,且不是简单属性的属性名
// 简单属性的判定参照下面方法,主要涵盖基本类型及其包装类,Number,Date等
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
// 检查缓存bean 中是否有当前bean
if (containsBean(propertyName)) {
// 递归初始化 bean,会调用 doGetBean() 来获取bean
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
// 注册依赖,将依赖关系保存到 Map> dependentBeanMapdependentBeanMap 中,key是 bean,value是 转化后的 propertyName
registerDependentBean(propertyName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("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");
}
}
}
}
byName
的处理逻辑很简单:获取需要注入的 bean
,然后递归调用 getBean
获取 bean
进行注入
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);
// 过滤出满足装配条件的Bean属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
// 获取属性描述符
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// 这里不解析Object的官方注释 :不要尝试按类型为Object类型自动装配:即使从技术上讲是不满意的,非简单的属性,也从没有意义。
if (Object.class != pd.getPropertyType()) {
// 获取指定属性的 set 方法
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
// 解析指定beanName 的属性所匹配的值,并把解析到的属性名存储在 autowiredBeanNames 中
// 当属性存在多个封装bean时,如 @Autowired List beans,会找到所有的匹配Bean 类型的bean并将其注入。
// 这里的返回值是真正的需要注入的属性, autowiredBeanNames 是需要注入的属性(可能是集合)的names
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
// 添加到待注入的bean列表中
pvs.add(propertyName, autowiredArgument);
}
// 注册依赖
for (String autowiredBeanName : autowiredBeanNames) {
// 注册依赖关系。操作 dependentBeanMap 和 dependenciesForBeanMap 集合
registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("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);
}
}
}
bw
Object.class
类型,调用resolveDependency()
方法进行校验获取对应的最后的值pvs
里面,并调用 registerDependentBean()
方法注册对应的依赖和被依赖关系使用测试代码进行调试,发现 autowiredBeanNames
的数据为下图所示
applyPropertyValues()
方法上面只是将属性保存了起来,并未真正设置到 bean
中,这里设置到 bean
中
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
// 如果属性列表为null,直接返回
if (pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
// 如果pvs 是 MutablePropertyValues 类型的封装
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
// 判断 mpvs 中的值类型已经转换完毕,则可以直接设置到BeanWrapper 中
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());
}
// 获取自定义转换类型,如果为null ,使用默认的bw, BeanWrapper 类继承了 TypeConverter
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// 这里是创建一个深度拷贝的list,解决值引用相关的问题
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
// 如果已经转换之后直接保存
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
// 进行类型转换
String propertyName = pv.getName();
Object originalValue = pv.getValue();
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
// 检查给定的属性是否可写, 或者检查属性是否是索引或嵌套的属性,比如a.b , 或者 [a,b]
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
// 进行类型转换
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// 将转换转换的值保存在pv 里面,同时加到深度拷贝list里面
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);
}
}
装配方式 | 解释 |
---|---|
AUTOWIRE_DEFAULT | 默认类型,和 AUTOWIRE_NO 相同。需要自己通过标签或者 ref 属性来指定需要注入的 bean 类型 |
AUTOWIRE_NO | 和 AUTOWIRE_DEFAULT 相同 |
AUTOWIRE_BY_NAME | 按照 bean 名称注入 |
AUTOWIRE_BY_TYPE | 按照 bean 类型注入 |
AUTOWIRE_AUTODETECT | 已过时 |
populateBean()
方法小结AUTOWIRE_DEFAULT
或 AUTOWIRE_NO
:如果通过
标签或 ref
属性指定了需要注入 bean
的类型,则会在 populateBean()
方法中通过类 RootBeanDefinition
完成 xml
配置文件标签解析,并在该方法中完成属性填充注入AUTOWIRE_BY_TYPE
或 AUTOWIRE_BY_NAME
:如果在 xml
配置文件中指定了装配方式或标注了注解 @Autowired
,则会在 populateBean()
方法中通过类 RootBeanDefinition
完成 xml
配置文件标签或注解 @Autowired
的解析,并在该方法中完成属性填充注入参考:https://blog.csdn.net/qq_36882793/article/details/106299180