目录
2.3、排除规则 - unsatisfiedNonSimpleProperties
3、@Autowired 和 @Resource 的注入工作
3.1、第六次调用后置处理器 InstantiationAwareBeanPostProcessor#postProcessProperties
3.2、CommonAnnotationBeanPostProcessor#postProcessPropertyValues
3.3、AutowiredAnnotationBeanPostProcessor #postProcessPropertyValues
3.4、需要依赖注入的对象 DefaultListableBeanFactory#resolveDependency
前言
本文是笔者阅读Spring源码的记录文章,由于本人技术水平有限,在文章中难免出现错误,如有发现,感谢各位指正。
我们在上一篇文章:spring bean生命周期二---Spring Bean实例化( Instantiation)阶段 中完成了bean的实例化过程 ,但是属性内容还没有注入,本文就是将bean的属性进行注入的过程。
一、populateBean - 概述
我们这里先整体过一遍代码,后面进行每一步的详细解读。
// AbstractAutowireCapableBeanFactory#populateBean
// beanName : bean 的name
// mbd : bean的定义信息
// bw : bean实例的包装类型,里面有bean的实例
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;
//mbd.isSynthetic() 合成类
//todo 第五次---判断属性是否填充:InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
// 给InstantiationAwareBeanPostProcessor最后一次机会在属性设置前来改变bean
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定义资源时为BeanDefiniton中设置的属性值
//这个是程序员在 bd中 写入的属性rootBeanDefinition.getPropertyValues().add("type","男的");
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//// 2. 自动装配 :autowiring自动装配的。根据名称或类型自动注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
//根据Bean名称进行autowiring自动装配处理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
//根据Bean类型进行autowiring自动装配处理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//对非autowiring的属性进行依赖注入处理
// 后处理器已经初始化
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
//TODO 获取的bean所有后置处理器找到 所有需要注入的属性
// 这里会进行 @Autowired 和 @Resource 的注入工作
// 属性填充InstantiationAwareBeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//下面是完成属性注入的
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
// 如果postProcessProperties 返回null,再调用 postProcessPropertyValues这个过时的方法
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
// 依赖检查,对应 depends-on 属性,3.0 已弃用
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
//// 4. 将属性应用到bean中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
从上看下来,整个流程如下:
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
方法,可以决定程序是否继续进行属性填充。只要有一个InstantiationAwareBeanPostProcessor
返回false,都会终止属性填充的过程。这个过程属于实例化 后置阶段上上文已经描述过了- 自动装配 :autowiring自动装配的。根据注入类型(name或type),提取依赖的bean,并统一存入到 propertyValues 中。
- @Autowired 和 @Resource 的属性注入工作,调用后置处理器应用
InstantiationAwareBeanPostProcessor#postProcessProperties
方法,对属性获取完毕填充前对属性的再次处理。
有两个实现类型 :1、AutowiredAnnotationBeanPostProcessor 中的实现类 处理 @Autowired 注解的
2、AutowiredAnnotationBeanPostProcessor 中的实现类 处理 @Autowired 注解的
- 将所有
propertyValues
中的属性填充至BeanWrapper
中。
在这里方法里按照如下顺序调用了后处理器
- InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation : 是否使用 InstantiationAwareBeanPostProcessor进行属性装配
- InstantiationAwareBeanPostProcessor.postProcessProperties : 进行属性装配
二、populateBean - 详解
2.1. 属性填充判断
这个的上文中已经描述过了这里就简单贴出代码
//mbd.isSynthetic() 合成类
//todo 第五次---判断属性是否填充:InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
// 给InstantiationAwareBeanPostProcessor最后一次机会在属性设置前来改变bean
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;
}
}
}
}
如下,这里调用了InstantiationAwareBeanPostProcessor
#postProcessAfterInstantiation
方法来决定是否继续注入属性。该方法正常返回true。如果返回false 则将取消对此bean调用任何后续的InstantiationAwareBeanPostProcessor
方法。
2.2、自动装配 :autowiring自动装配的
在下面这段代码中,对 autowiring自动装配中根据名称或类型自动注入的种类进行自动装配。
//// 2. 自动装配 :autowiring自动装配的。根据名称或类型自动注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
//根据Bean名称进行autowiring自动装配处理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
//根据Bean类型进行autowiring自动装配处理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
这一段代码的目的是,如果bean在声明的时候指定了自动注入类型是 byName或者byType,则会根据这个规则,对 bean内部的排除某些特定的属性(排除规则后面详解), 进行byName 或者 byType的自动装配。
2.2.1、自动装配 - autowireByName
//根据名称对属性进行自动依赖注入
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//对Bean对象中非简单属性(不是简单继承的对象,如8中原始类型,字符串,URL等都是简单属性)进行处理
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
//如果Spring IOC容器中包含指定名称的Bean
if (containsBean(propertyName)) {
//调用getBean方法向IOC容器索取指定名称的Bean实例,迭代触发属性的初始化和依赖注入
Object bean = getBean(propertyName);
//为指定名称的属性赋予属性值
pvs.add(propertyName, bean);
//指定名称属性注册依赖Bean名称,进行属性依赖注入
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进行注入。 关于