前言
本系列所有基于 Spring 5.2.2.BUILD-SNAPSHOT
版本。由于 Spring 整个体系太过于庞大,因此只会进行关键部分的源码解析。html
本篇文章主要介绍 Spring IoC 容器中 bean
的属性赋值阶段。java
正文
咱们在Spring IoC bean 的建立一文中分析建立 bean
实例的主要流程,此时建立出来的 bean
仍是个属性未赋值的实例,在建立完以后会进入 populateBean()
方法,即进入属性赋值阶段。咱们简单回顾一下,上次分析过的 doCreateBean()
方法:缓存
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // 实例化 bean BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { // 若是bean的做用域是singleton,则须要移除未完成的FactoryBean实例的缓存 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { // 经过构造函数反射建立bean的实例,可是属性并未赋值,见下文详解 instanceWrapper = createBeanInstance(beanName, mbd, args); } // 获取bean的实例 final Object bean = instanceWrapper.getWrappedInstance(); // 获取bean的类型 Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { // BeanDefinition 合并后的回调,见下文详解 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } // 省略异常处理... mbd.postProcessed = true; } } // bean的做用域是单例 && 容许循环引用 && 当前bean正在建立中 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); // 若是容许bean提早曝光 if (earlySingletonExposure) { // 将beanName和ObjectFactory造成的key-value对放入singletonFactories缓存中 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } Object exposedObject = bean; try { // 给 bean 的属性赋值 populateBean(beanName, mbd, instanceWrapper); // 初始化 bean exposedObject = initializeBean(beanName, exposedObject, mbd); } // 省略部分代码 }
属性赋值
AbstractAutowireCapableBeanFactory#populateBean
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 { return; } } // 给InstantiationAwareBeanPostProcessors最后一次机会在属性设置前来改变bean // 例如:能够用来支持属性注入的类型 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { // 这里会调用bean实例化后的生命周期回调,返回false会跳过下面的属性赋值阶段 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } } // 获取PropertyValues PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); // 获取依赖注入类型 int resolvedAutowireMode = mbd.getResolvedAutowireMode(); // 若是依赖注入类型是 byName 或者 byType if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { // 赋值pvs到可修改的MutablePropertyValues MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // 根据名称自动注入,见下文详解 if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // 根据类型自动注入,见下文详解 if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } // 是否有注册InstantiationAwareBeanPostProcessors的实现类 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } // 遍历并找到InstantiationAwareBeanPostProcessor的实现类,调用处理属性值的后置处理方法 for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; 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); // 若是属性值的后置处理方法返回null,直接返回,不会进行底下的属性值应用阶段 if (pvsToUse == null) { return; } } pvs = pvsToUse; } } } if (needsDepCheck) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null) { // 属性填充,见下文详解 applyPropertyValues(beanName, mbd, bw, pvs); } }
上面方法首先会调用 bean
的实例化后生命周期回调方法,若是返回 false
会跳过下面的属性赋值阶段。关于 InstantiationAwareBeanPostProcessors
接口在Spring IoC bean 的建立一文中介绍过,这里再也不赘述。接着判断是不是按 名称 或者 类型 自动注入属性并填入 newPvs
中,接着调用 bean
属性填充前的生命周期回调。属性填充前生命周期回调方法有两个 postProcessProperties()
和 postProcessPropertyValues()
,第一个是 Spring 5.1 新加的,后面的是老的,已经被标记为过期;首先会调用 postProcessProperties()
若是返回空调用 postProcessPropertyValues()
,不然直接使用返回的 PropertyValues
;postProcessPropertyValues()
若是返回空会直接跳过属性填充阶段,不为空直接使用返回的 PropertyValues
。app
按照名称依赖注入
AbstractAutowireCapableBeanFactory#autowireByName
protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { // 寻找bw中须要依赖注入的属性名称 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); // 遍历须要注入的bean for (String propertyName : propertyNames) { if (containsBean(propertyName)) { // 调用getBean()方法获取bean Object bean = getBean(propertyName); // 将须要注入bean的实例加入到pvs pvs.add(propertyName, bean); // 注册依赖关系 registerDependentBean(propertyName, beanName); } } }
上面的方法很简单,就是寻找 bean
的非简单类型而且不存在于 mbd.getPropertyValues()
中的属性,而后遍历调用 getBean()
方法去获取实例,完成注入。函数
非简单类型就是指除去8个原始类型、String类型、Number类型、Date类型、URL类型、URI类型的其它类型。post
registerDependentBean()
方法在Spring IoC bean 的加载一文中有分析过,这里再也不赘述。this
按照类型依赖注入
AbstractAutowireCapableBeanFactory#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类型,你细细地品一下 if (Object.class != pd.getPropertyType()) { // 获取属性的可写方法,通常是set方法 MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered); DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); // 依赖解决,最后返回符合条件须要注入的bean实例 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null) { // 须要注入的bean实例不为空,加入到pvc pvs.add(propertyName, autowiredArgument); } for (String autowiredBeanName : autowiredBeanNames) { // 注册依赖关系 registerDependentBean(autowiredBeanName, beanName); } autowiredBeanNames.clear(); } } catch (BeansException ex) { throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex); } } }
上面方法中的 resolveDependency()
方法在Spring IoC bean 的建立一文中介绍过,这里再也不赘述。spa
属性赋值
AbstractAutowireCapableBeanFactory#applyPropertyValues
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { // 属性为空,直接返回 if (pvs.isEmpty()) { return; } if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) { ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); } MutablePropertyValues mpvs = null; List<PropertyValue> original; if (pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues) pvs; // 快捷方式,若是属性已经转换过,直接填充进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()); } TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } // 获取对应的解析器 BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter); // 建立深拷贝,解决引用的问题 List<PropertyValue> deepCopy = new ArrayList<>(original.size()); boolean resolveNecessary = false; // 遍历属性,将属性转换为对应的类型 for (PropertyValue pv : original) { // 若是pv类型转换过,直接添加进deepCopy if (pv.isConverted()) { deepCopy.add(pv); } else { // 进行转换 // 拿到pv原始属性名和属性值 String propertyName = pv.getName(); Object originalValue = pv.getValue(); if (originalValue == AutowiredPropertyMarker.INSTANCE) { Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod(); if (writeMethod == null) { throw new IllegalArgumentException("Autowire marker for property without write method: " + pv); } originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true); } // 进行类型转换 Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); Object convertedValue = resolvedValue; boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName); if (convertible) { // 若是可转换,则转换指定目标属性的给定值 convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter); } // 在合并的BeanDefinition中存储转换后的值,以免为每一个建立的bean实例从新转换 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 { // 填充bean属性值 bw.setPropertyValues(new MutablePropertyValues(deepCopy)); } catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values", ex); } }
上面代码中的 bw.setPropertyValues()
方法最终会调用 BeanWrapperImpl#setVlaue()
方法,以下:debug
public void setValue(final @Nullable Object value) throws Exception { // 这里通常就是set方法 final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ? ((GenericTypeAwarePropertyDescriptor)this.pd).getWriteMethodForActualAccess() : this.pd.getWriteMethod()); // 利用反射调用set方法给属性赋值 ReflectionUtils.makeAccessible(writeMethod); writeMethod.invoke(getWrappedInstance(), value); }
下图是我 debug 时的截图,能够看到基本上就是在调用属性的 setter
方法:code
注意:没有
setter
方法时会抛出异常。
总结
本篇文章主要分析了 Spring IoC 的属性赋值阶段的流程,Spring 在此阶段也提供了2个扩展点;分别是 bean
的实例化后和属性赋值前,即 InstantiationAwareBeanPostProcessor
接口的 postProcessAfterInstantiation()
方法和 postProcessProperties()
方法。须要注意的是在 XML 中配置的 autowire
属性,无论是 byName
仍是 byType
都须要 setter
方法,可是咱们平时在使用 @Autowire
注解时并不须要 settter
方法,缘由会在分析 @Autowire
注解时讲述。