在上篇文章中,我们详细分析了
doCreateBean()
中的4步:单例模式的循环依赖处理,本文接着分析doCreateBean()
的第5步“属性填充”,也就是populateBean()
方法。
首先回顾下CreateBean
的主流程:
createBeanInstance()
实例化 bean本章我们主要分析第5步:
在Spring中属性注入有三种方式:
xml方式如<beans>节点中的default-autowire属性
;
注解方式如:@Value()、@Resource、@Autowire、@Qualifier
本文我们主要分析 注解方式 的属性注入
//AbstractAutowireCapableBeanFactory.java
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.
/*
* 在设置属性之前给 InstantiationAwareBeanPostProcessors 最后一次改变 bean 的机会。
* 关于这段后置引用,官方的解释是:让用户可以自定义属性注入。比如用户实现一
* 个 InstantiationAwareBeanPostProcessor 类型的后置处理器,并通过
* postProcessAfterInstantiation 方法向 bean 的成员变量注入自定义的信息。当然,如果无
* 特殊需求,直接使用配置中的信息注入即可。另外,Spring 并不建议大家直接实现
* InstantiationAwareBeanPostProcessor 接口,如果想实现这种类型的后置处理器,更建议
* 通过继承 InstantiationAwareBeanPostProcessorAdapter 抽象类实现自定义后置处理器。
*/
boolean continueWithPropertyPopulation = true;
// bean 不是"合成"的,即未由应用程序本身定义 && 持有 InstantiationAwareBeanPostProcessor
<1> if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 遍历所有的 BeanPostProcessors
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 返回值为是否继续填充 bean
// postProcessAfterInstantiation:如果应该在 bean上面设置属性则返回 true,否则返回 false
// 一般情况下,应该是返回true 。
// 返回 false 的话,将会阻止在此 Bean 实例上调用任何后续的 InstantiationAwareBeanPostProcessor 实例。
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 如果后置处理器发出停止填充命令,则终止后续操作
if (!continueWithPropertyPopulation) {
return;
}
//获取Bean的属性值
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//处理依赖注入
//xml方式 即xml中<beans>节点中的default-autowire属性
<2> if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
// 将 PropertyValues 封装成 MutablePropertyValues 对象
// MutablePropertyValues 允许对属性进行简单的操作,并提供构造函数以支持Map的深度复制和构造。
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;
}
// 是否已经注册了 InstantiationAwareBeanPostProcessors
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//是否需要依赖检查(xml)
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
//属性注入(注解方式)
//已经注册IABP && 需要依赖检查
<3> if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 具体处理属性注入(注解方式)!!! 如@Value()、@Resource、@Autowire
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
//依赖检查 (xml)
<4> if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
<5> if (pvs != null) {
//对属性进行注入 (xml)
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
复制代码
主要分为以下几个步骤:
在上述代码<1>处:
/*
* 在设置属性之前给 InstantiationAwareBeanPostProcessors 最后一次改变 bean 的机会。
* 关于这段后置引用,官方的解释是:让用户可以自定义属性注入。比如用户实现一
* 个 InstantiationAwareBeanPostProcessor 类型的后置处理器,并通过
* postProcessAfterInstantiation 方法向 bean 的成员变量注入自定义的信息。当然,如果无
* 特殊需求,直接使用配置中的信息注入即可。另外,Spring 并不建议大家直接实现
* InstantiationAwareBeanPostProcessor 接口,如果想实现这种类型的后置处理器,更建议
* 通过继承 InstantiationAwareBeanPostProcessorAdapter 抽象类实现自定义后置处理器。
*/
boolean continueWithPropertyPopulation = true;
// bean 不是"合成"的,即未由应用程序本身定义 && 持有 InstantiationAwareBeanPostProcessor
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 遍历所有的 BeanPostProcessors
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 返回值为是否继续填充 bean
// postProcessAfterInstantiation:如果应该在 bean上面设置属性则返回 true,否则返回 false
// 一般情况下,应该是返回true 。
// 返回 false 的话,将会阻止在此 Bean 实例上调用任何后续的 InstantiationAwareBeanPostProcessor 实例。
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 如果后置处理器发出停止填充命令,则终止后续操作
if (!continueWithPropertyPopulation) {
return;
}
这部分逻辑注释上已经写的很清楚了。
//xml方式 即xml中<beans>节点中的default-autowire属性
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
// 将 PropertyValues 封装成 MutablePropertyValues 对象
// MutablePropertyValues 允许对属性进行简单的操作,并提供构造函数以支持Map的深度复制和构造。
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;
}
这部分代码主要是来处理XML方式的属性注入,例如xml中<beans>节点中的default-autowire属性
,因为本次Spring系列主要是分析注解方式的,这里就不详细分析了。感性趣的朋友可以自己趣了解下~
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 处理依赖注入(注解方式) 如@Value()、@Resource、@Autowire
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
这段代码就是我们要分析的核心。
首先是判断是否已经注册了InstantiationAwareBeanPostProcessor
(实例化Bean的后置处理器),如果注册了,就遍历所有的后置处理器。 我们先来了解下InstantiationAwareBeanPostProcessor
的类图结构:
InstantiationAwareBeanPostProcessor
是一个关于对象实例化前后以及实例化后设置propertyValues的回调处理器。 它有三个方法:
//这个方法用来在对象实例化前直接返回一个对象(如代理对象)来代替通过内置的实例化流程创建对象;
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
//在对象实例化完毕执行populateBean之前 如果返回false则spring不再对对应的bean实例进行自动依赖注入。
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
//这里是在spring处理完默认的成员属性,应用到指定的bean之前进行回调,可以用来检查和修改属性,最终返回的PropertyValues会应用到bean中
//@Autowired、@Resource、@Value等就是根据这个方法来实现最终注入依赖的属性的。
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
复制代码
我们主要看第三个方法postProcessPropertyValues()
,这个方法就是通过注解进行属性注入的具体实现。
该方法主要有3个实现,分别对应了不同的注解。
是Spring容器专门处理配置了自动依赖注入装配相关注解(@Autowire、@Value以及其他JSR-330注解)的Bean后置处理器。详细说明见Spring注解@Autowired源码分析
CommonAnnotationBeanPostProcessor是Spring中用于处理JavaEE5中常用注解(主要是EJB相关的注解)和Java6中关于JAX-WS相关的注解,可以处理@PostConstruct、@PreDestroy等Bean生命周期相关事件的注解,该后置处理最核心的是处理@Resource
注解,同时还可以处理JAX-WS相关的注解。详细说明见Spring注解@Resource源码分析
总结
到这里就已经完成了注解方式所有属性的注入了。