站在设计者的角度设计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(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 在这里会对@Autowired标记的属性进行依赖注入 PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } } // 依赖检查,对应depend-on属性,3.0已经弃用此属性 if (needsDepCheck) { // 过滤出所有需要进行依赖检查的属性编辑器 if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null) { // 最终将属性注入到Bean的Wrapper实例里,这里的注入主要是供 // 显式配置了autowiredbyName或者ByType的属性注入, // 针对注解来讲,由于在AutowiredAnnotationBeanPostProcessor已经完成了注入, // 所以此处不执行 applyPropertyValues(beanName, mbd, bw, pvs); } }
最开始是一些判空逻辑:
接下来的逻辑就是脑图里的第一步了:
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; } } } }
首先判断出boyfriend不是spring内部特殊的bean
!mbd.isSynthetic()
再看下容器里是否已经注册了InstantiationAwareBeanPostProcessors级别的后置处理器,如果有则通过责任链模式调用这些后置处理器的postProcessAfterInstantiation方法
这里InstantiationAwareBeanPostProcessor会在属性注入之前,有最后一次机会去修改bean的属性值,此处也可以决定是否后续的填充步骤
continueWithPropertyPopulation = false;
// 如果上面设置continueWithPropertyPopulation = false,表明用户可能已经自己填充了 // bean的属性,不需要Spring帮忙填充了。此时直接返回即可 if (!continueWithPropertyPopulation) { return; }
接下来来到:
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
pvs是一个MutablePropertyValues实例,里面实现了PropertyValues接口,提供属性的读写操作实现,同时可以通过调用构造函数实现深拷贝,获取BeanDefinition里面为Bean设置上的属性值
返回给pvs的是mbd.getPropertyValues()方法的返回值,
public MutablePropertyValues getPropertyValues() { if (this.propertyValues == null) { this.propertyValues = new MutablePropertyValues(); } return this.propertyValues; }
MutablePropertyValues类
bean的属性解析主要就是和这个类打交道的
回到populateBean方法里,第一次解析 pvs 值为空,此时就来到脑图中的第二步,按照名字 or 类型对bean进行自动装配
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
返回结果是0,表示没有配置上自动装配模式,意味着会跳过populateBean的自动装配逻辑。
之前介绍postProcessMergedBeanDefinition方法时,被@Value和@Autowired标记的成员变量已经被标记出来了,只差将其注入到bean实例里了,因此就没必要再走一遍解析了,所以就没必要执行if中的逻辑了。
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(beanName, mbd, bw, newPvs); } pvs = newPvs; }
可以看一看上面两种注入方法的逻辑。
autowireByName:
protected void autowireByName( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { // 获取要注入的非简单类型的属性名称 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { // 检测是否存在与propertyName相关的bean或BeanDefinition. // 若存在,则调用BeanFactory.getBean方法获取bean实例 if (containsBean(propertyName)) { // 从容器中获取相应的bean实例 Object bean = getBean(propertyName); // 将解析出的bean存入到属性值列表pvs中 pvs.add(propertyName, bean); // 注册依赖关系 registerDependentBean(propertyName, beanName); if (logger.isTraceEnabled()) { logger.trace("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"); } } } }
先获取非简单类型的属性名称,再根据获取出来的属性名称去依次调用容器的getBean方法获取属性名对应的bean实例,最后将获取到的bean实例连同属性的名称添加到属性列表pvs中,再将bean的依赖关系通过registerDependentBean方法给注册起来。
进入unsatisfiedNonSimpleProperties方法里:
/** * 获取非简单类型属性的名称,且该属性未被配置在配置文件中,如下例:将属性明确写在bean里面了,就不算自动装配 * <bean class="org.springframework.aop.framework.ProxyFactoryBean"> * <property name="target"> * <ref parent="accountService"/> * </property> * </bean> * * Spring认为的“简单类型“属性有哪些,如下: * 1. CharSequence接口的实现类,比如String * 2. Enum * 3. Date * 4. URI/URL * 5. Number的继承类,比如Integer/Long * 6. byte/short/int...等基本类型 * 7. Locale * 8.以上所有类型的数组形式 * * * @param mbd * @param bw * @return */ protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) { Set<String> result = new TreeSet<>(); PropertyValues pvs = mbd.getPropertyValues(); PropertyDescriptor[] pds = bw.getPropertyDescriptors(); for (PropertyDescriptor pd : pds) { if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) && !BeanUtils.isSimpleProperty(pd.getPropertyType())) { result.add(pd.getName()); } } return StringUtils.toStringArray(result); }
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); // 获取要注入的属性名称(非简单属性(8种原始类型、字符、URL等都是简单属性)) String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { try { // 获取指定属性名称的属性Descriptor(Descriptor用来记载属性的getter setter type等情况) PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); // Don't try autowiring by type for type Object: never makes sense, // even if it technically is a unsatisfied, non-simple property. // 不对Object类型的属性进行装配注入,技术上没法实现,并且没有意义 // 即如果属性类型为Object,则忽略,不做解析 if (Object.class != pd.getPropertyType()) { // 获取属性的setter方法 MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); // Do not allow eager init for type matching in case of a prioritized post-processor. // 对于继承了PriorityOrdered的post-processor,不允许立即初始化(热加载) boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance()); // 创建一个要被注入的依赖描述,方便提供统一的访问 DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); // 根据容器的BeanDefinition解析依赖关系,返回所有要被注入的Bean实例 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null) { // 将解析出的bean存入到属性值列表pvs中 pvs.add(propertyName, autowiredArgument); } for (String autowiredBeanName : autowiredBeanNames) { // 注册依赖关系 registerDependentBean(autowiredBeanName, beanName); if (logger.isTraceEnabled()) { logger.trace("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); } } }
首先也是获得非简单类型属性名称:
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
然后再根据属性名获取属性描述符PropertyDescriptor:
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
然后根据属性描述符去获取方法参数对象MethodParameter:
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
之后再根据方法参数对象去获取依赖描述符对象DependencyDescriptor:
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
进入PropertyDescriptor:
主要就是用来描述bean里的主要属性,可以通过它获取到该属性的getter或setter
回到autowireByType,
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
就是获得属性setter方法实例,保存到MethodParameter实例中,该实例是封装setter的,方便后续注入,DependencyDescriptor描述要注入的依赖
InjectionPoint是用来描述注入点的,比如boyfriend中的girlfriend就是一个注入点,girlfriend的类型、setter、注解标签这些信息都可以通过InjectionPoint来获取,DependencyDescriptor除了上述的功能外,还保存了一些额外的信息,比如:依赖是否必要
public boolean isRequired() { if (!this.required) { return false; } if (this.field != null) { return !(this.field.getType() == Optional.class || hasNullableAnnotation() || (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(this.field.getDeclaringClass()) && KotlinDelegate.isNullable(this.field))); } else { return !obtainMethodParameter().isOptional(); } }
是否是延迟加载的:
public boolean isEager() { return this.eager; }
相关的一些嵌套级别:
public void increaseNestingLevel() { this.nestingLevel ++; this.resolvableType = null; if (this.methodParameter != null) { this.methodParameter = this.methodParameter.nested(); } }
回到autowireByType,获取到DependencyDescriptor之后就可以进行属性对应的值的解析了
// 根据容器的BeanDefinition解析依赖关系,返回所有要被注入的Bean实例 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
autowiredArgument是属性的值,并将其与属性名一起添加到属性列表中
pvs.add(propertyName, autowiredArgument);
之后再注册一下bean之间的依赖关系
registerDependentBean(autowiredBeanName, beanName);
毕竟不是所有的依赖关系都是在配置里显式标注的。注册完成后就完成了该方法