Spring Bean的实例化之属性注入源码剖析过程
这一章节我们来讨论创建Bean过程中的属性注入,在Spring的IOC容器启动过程中,会把定义的Bean封装成BeanDefinition注册到一个ConcurrentHashMap中,Bean注册完成后,就会对单利的且lazy-init=false 的Bean进行实例化。创建Bean的代码在 AbstractAutowireCapableBeanFactory#doCreateBean 中,当Bean创建成功之后,会调用AbstractAutowireCapableBeanFactory#populateBean 方法进行属性注入。本篇文章主要就是分析该方法是如何实现Bean的属性注入的。
这里先上一个属性注入的流程图,待会儿可以根据这个图来看代码
属性注入:AbstractAutowireCapableBeanFactory#populateBeanAbstractAutowireCapableBeanFactory#populateBean 方法的主要功能就是属性填充,源码如下
//使用 bean 定义中的属性值填充给定 BeanWrapper 中的 bean 实例。@SuppressWarnings('deprecation') // for postProcessPropertyValuesprotected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {if (bw == null) {//判断是否有property属性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的状态if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;}}}}//从 RootBeanDefinition 获取所有的PropertyValuesPropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);int resolvedAutowireMode = mbd.getResolvedAutowireMode();//根据名字获取根据type注入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();//是否要检查依赖,默认falseboolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);PropertyDescriptor[] filteredPds = null;if (hasInstAwareBpps) {if (pvs == null) {pvs = mbd.getPropertyValues();}//获取后置处理器for (BeanPostProcessor bp : getBeanPostProcessors()) {//如果是Bean实例化后置处理器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);if (pvsToUse == null) {return;}}pvs = pvsToUse;}}}if (needsDepCheck) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}checkDependencies(beanName, mbd, filteredPds, pvs);}if (pvs != null) {//依赖注入入口,讲属性应用到Bean中applyPropertyValues(beanName, mbd, bw, pvs);}}
方法中的重要代码
autowireByName : 根据属性名进行注入 autowireByType:根据类型注入Bean InstantiationAwareBeanPostProcessor.postProcessPropertyValues :该方法是在工厂将给定的属性值应用于给定的 bean 之前对给定的属性值进行处理,比如:RequiredAnnotationBeanPostProcessor类中对属性的验证。 applyPropertyValues:属性的填充autowireByName是根据名字注入,源码如下
protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {//寻找BeanWrapper中需要依赖的属性String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);for (String propertyName : propertyNames) {if (containsBean(propertyName)) {//递归实例化的BeanObject bean = getBean(propertyName);pvs.add(propertyName, bean);//注册依赖的Bean,加入 dependentBeanMap 中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');}}}}
这个方法很简单,就是先找到依赖的Bean,递归初始化,然后加入 pvs中
//定义“按类型自动装配”(按类型的 bean 属性)行为的抽象方法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);//找到需要注入的属性String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);for (String propertyName : propertyNames) {try {//属性描述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.if (Object.class != pd.getPropertyType()) {//获取对象的set方法MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);// Do not allow eager init for type matching in case of a prioritized post-processor.boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);//依赖描述DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);//【重要】得到依赖的属性的值,存储到 autowiredBeanNames 集合中//提供了对集合如:@Autowired private List<A> as; 支持,根据类型走到所有的Bean注入其中Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);if (autowiredArgument != null) {//添加到pvspvs.add(propertyName, autowiredArgument);}for (String autowiredBeanName : autowiredBeanNames) {//注入依赖的BeanregisterDependentBean(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);}}}
看到这,我们大概清楚了,其实在populateBean 方法中会先从RootBeanDefinition 中获取 Bean的属性(PropertyValues),同时也会根据RootBeanDefinition的autowireMode自动注入模式来根据name或者type寻主Bean的依赖的属性。
根据类型注入和根据名字注入都是先从BeanWrapper 中找到Bean的依赖的属性,然后根据属性类型找到匹配的Bean,实现依赖注入。还提供了对集合如:@Autowired private List<A> as; 集合注入的支持。
属性寻找好之后都会封装成 PropertyValues,然后传给applyPropertyValues应用到Bean身上。
AbstractAutowireCapableBeanFactory#applyPropertyValues我们可以认为前面的代码是在为当前Bean寻找依赖的的属性,封装到 PropertyValues中,在applyPropertyValues中才是把属性应用到当前Bean。
//处理对象之间的引用,使用深拷贝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;//判断mpvs中的值是否已经转成了对应的类型,已经转了就可以直接设置值到 BeanWrapper了if (mpvs.isConverted()) {// Shortcut: use the pre-converted values as-is.try {//为实例化对象设置属性bw.setPropertyValues(mpvs);return;}catch (BeansException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, 'Error setting property values', ex);}}//获取属性值的原始类型original = mpvs.getPropertyValueList();}else {//如果类型不是MutablePropertyValues , 就使用原生属性获取方法original = Arrays.asList(pvs.getPropertyValues());}//获取用户自定义的型转换器TypeConverter converter = getCustomTypeConverter();if (converter == null) {converter = bw;}//解析器:用于 bean 工厂实现的 Helper 类,将 bean 定义对象中包含的值,解析为应用于目标 bean 实例的实际值。BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);// Create a deep copy, resolving any references for values.//存放类型转换过的属性,把Bean的属性解析值新建拷贝,把拷贝的数据注入到对象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();//原始属性值,它的类型是一个 如: RuntimeBeanReference<otherBean> 引用类型Object originalValue = pv.getValue();//转换属性值,将引用转换为 IOC 容器中实例化对象引用 OtherBeanObject resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);Object convertedValue = resolvedValue;boolean convertible = bw.isWritableProperty(propertyName) &&!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);if (convertible) {//使用用户自定义的转换器转换convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);}// Possibly store converted value in merged bean definition,// in order to avoid re-conversion for every created bean instance.if (resolvedValue == originalValue) {if (convertible) {//设置转换之后的值到PV ,把依赖的Bean设置给PropertyValuepv.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;//转换好的依赖的属性最终放到一个ArrayList中deepCopy.add(new PropertyValue(pv, convertedValue));}}}if (mpvs != null && !resolveNecessary) {mpvs.setConverted();}// Set our (possibly massaged) deep copy.try {//把解析好的属性 设置到 BeanWrapper 中bw.setPropertyValues(new MutablePropertyValues(deepCopy));}catch (BeansException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, 'Error setting property values', ex);}}
这里主要进行属性转换,然后应用到Bean身上,这里的属性转换比如: 在BeanDefinition中属性可能是用字符串类型来描述的,需要把属性转成真实的原始属性类型。
首先判断属性是否需要转换类型,如果不需要转直接应用于Bean。比如:<property name='otherBean' ref='otherBean' /> 这种属性值其实是个字符串“otherBean” ,需要解析成容器中的OtherBean实例的引用。 如果属性值需要类型转换,比如:属性值是容器中的另外一个Bean,则需要根据属性值解析出引用的对象然后注入到对象的属性上,应用到Bean。通过 BeanDefinitionValueResolver 类中的 resolveValueIfNecessary()方法中进行属性值的解析, 对属性值的注入是通过 bw.setPropertyValues()方法完成
解析: BeanDefinitionValueResolver#resolveValueIfNecessary给定一个 PropertyValue根据属性值进行类型解析,必要时解析对工厂中其他 bean 的引用
@Nullablepublic Object resolveValueIfNecessary(Object argName, @Nullable Object value) {// We must check each value to see whether it requires a runtime reference// to another bean to be resolved.//对属性值是引用类型的解析if (value instanceof RuntimeBeanReference) {//比如:<property name='xx' ref='xxBean' 就是引用类型,会走这里RuntimeBeanReference ref = (RuntimeBeanReference) value;//对引用类型属性进行解析return resolveReference(argName, ref);}///对属性值是引用容器中另一个 Bean 名称的解析else if (value instanceof RuntimeBeanNameReference) {String refName = ((RuntimeBeanNameReference) value).getBeanName();refName = String.valueOf(doEvaluate(refName));//判断容器中是否有这个Beanif (!this.beanFactory.containsBean(refName)) {throw new BeanDefinitionStoreException('Invalid bean name ’' + refName + '’ in bean reference for ' + argName);}return refName;}else if (value instanceof BeanDefinitionHolder) {// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.//解析 BeanDefinitionHolder:包含带有名称和别名的 BeanDefinitionBeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;//解析内部 Beanreturn resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());}else if (value instanceof BeanDefinition) {// Resolve plain BeanDefinition, without contained name: use dummy name.//解析纯 BeanDefinition,不包含名称BeanDefinition bd = (BeanDefinition) value;String innerBeanName = '(inner bean)' + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +ObjectUtils.getIdentityHexString(bd);return resolveInnerBean(argName, innerBeanName, bd);}//对数组类型解析else if (value instanceof ManagedArray) {// May need to resolve contained runtime references.ManagedArray array = (ManagedArray) value;Class<?> elementType = array.resolvedElementType;if (elementType == null) {String elementTypeName = array.getElementTypeName();if (StringUtils.hasText(elementTypeName)) {try {elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());array.resolvedElementType = elementType;}catch (Throwable ex) {// Improve the message by showing the context.throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,'Error resolving array type for ' + argName, ex);}}else {elementType = Object.class;}}return resolveManagedArray(argName, (List<?>) value, elementType);}//对集合类型解析else if (value instanceof ManagedList) {// May need to resolve contained runtime references.return resolveManagedList(argName, (List<?>) value);}//对Set类型解析else if (value instanceof ManagedSet) {// May need to resolve contained runtime references.return resolveManagedSet(argName, (Set<?>) value);}//对Map类型解析else if (value instanceof ManagedMap) {// May need to resolve contained runtime references.return resolveManagedMap(argName, (Map<?, ?>) value);}//对Properties解析else if (value instanceof ManagedProperties) {Properties original = (Properties) value;Properties copy = new Properties();original.forEach((propKey, propValue) -> {if (propKey instanceof TypedStringValue) {propKey = evaluate((TypedStringValue) propKey);}if (propValue instanceof TypedStringValue) {propValue = evaluate((TypedStringValue) propValue);}if (propKey == null || propValue == null) {throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,'Error converting Properties key/value pair for ' + argName + ': resolved to null');}copy.put(propKey, propValue);});return copy;}//解析字符串类型的属性值else if (value instanceof TypedStringValue) {// Convert value to target type here.TypedStringValue typedStringValue = (TypedStringValue) value;Object valueObject = evaluate(typedStringValue);try {//目标类型Class<?> resolvedTargetType = resolveTargetType(typedStringValue);if (resolvedTargetType != null) {//目标类型进行解析return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);}else {//类型没获取到,就返回Object类型return valueObject;}}catch (Throwable ex) {// Improve the message by showing the context.throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,'Error converting typed String value for ' + argName, ex);}}else if (value instanceof NullBean) {return null;}else {return evaluate(value);}}
这个方法中就是根据属性的值的类型进行解析,如:String,Array,List,Set,Map的类型,比较复杂的就是属性值依赖的是一个Bean,那么就需要根据依赖的Bean的名字找到容器中的Bean的实例,查找如下:
/** * Resolve a reference to another bean in the factory. */ //关联对象的解析@Nullableprivate Object resolveReference(Object argName, RuntimeBeanReference ref) {try {Object bean;//引用对象的名称String refName = ref.getBeanName();refName = String.valueOf(doEvaluate(refName));//如果对象在父容器中,从父容器获取if (ref.isToParent()) {if (this.beanFactory.getParentBeanFactory() == null) {throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,'Can’t resolve reference to bean ’' + refName +'’ in parent factory: no parent factory available');}//如果对象在父容器中,从父容器获取bean = this.beanFactory.getParentBeanFactory().getBean(refName);}else {//[重要]根据依赖的Bean的名字,从当前容器中获取Beanbean = this.beanFactory.getBean(refName);//把依赖的Bean的实例和当前对象建议依赖关系,使用 dependentBeanMap 去维护关系this.beanFactory.registerDependentBean(refName, this.beanName);}if (bean instanceof NullBean) {bean = null;}return bean;}catch (BeansException ex) {throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,'Cannot resolve reference to bean ’' + ref.getBeanName() + '’ while setting ' + argName, ex);}} * For each element in the managed array, resolve reference if necessary. */ //解析数组private Object resolveManagedArray(Object argName, List<?> ml, Class<?> elementType) {Object resolved = Array.newInstance(elementType, ml.size());for (int i = 0; i < ml.size(); i++) {Array.set(resolved, i, resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));}return resolved;}/** * For each element in the managed list, resolve reference if necessary. */ //解析Listprivate List<?> resolveManagedList(Object argName, List<?> ml) {List<Object> resolved = new ArrayList<>(ml.size());for (int i = 0; i < ml.size(); i++) {resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));}return resolved;}/** * For each element in the managed set, resolve reference if necessary. */ //解析setprivate Set<?> resolveManagedSet(Object argName, Set<?> ms) {Set<Object> resolved = new LinkedHashSet<>(ms.size());int i = 0;for (Object m : ms) {resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), m));i++;}return resolved;}/** * For each element in the managed map, resolve reference if necessary. */ //解析Mapprivate Map<?, ?> resolveManagedMap(Object argName, Map<?, ?> mm) {Map<Object, Object> resolved = new LinkedHashMap<>(mm.size());mm.forEach((key, value) -> {Object resolvedKey = resolveValueIfNecessary(argName, key);Object resolvedValue = resolveValueIfNecessary(new KeyedArgName(argName, key), value);resolved.put(resolvedKey, resolvedValue);});return resolved;}
属性值解析完成之后 是封装成一个 MutablePropertyValues,通过 BeanWrapperImpl.setPropertyValues()方法完成值的注入,BeanWrapperImpl中注入方法又是由AbstractPropertyAccessor#setPropertyValue(java.lang.String, java.lang.Object)去完成。
AbstractPropertyAccessor#setPropertyValue@Overridepublic void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)throws BeansException {List<PropertyAccessException> propertyAccessExceptions = null;//拿到所有的属性列表List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));for (PropertyValue pv : propertyValues) {try {// This method may throw any BeansException, which won’t be caught// here, if there is a critical failure such as no matching field.// We can attempt to deal only with less serious exceptions.//设置属性值setPropertyValue(pv);}...省略...@Overridepublic void setPropertyValue(String propertyName, @Nullable Object value) throws BeansException {//属性访问器AbstractNestablePropertyAccessor nestedPa;try {nestedPa = getPropertyAccessorForPropertyPath(propertyName);}catch (NotReadablePropertyException ex) {throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,'Nested property in path ’' + propertyName + '’ does not exist', ex);}//属性助手PropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedPa, propertyName));//通过属性访问器为属性设置值nestedPa.setPropertyValue(tokens, new PropertyValue(propertyName, value));}
这里看到,属性的注入交给了 AbstractNestablePropertyAccessor 属性访问器去完成
protected void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {if (tokens.keys != null) {processKeyedProperty(tokens, pv);}else {//走这里processLocalProperty(tokens, pv);}}private void processLocalProperty(PropertyTokenHolder tokens, PropertyValue pv) {//属性处理器PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);if (ph == null || !ph.isWritable()) {if (pv.isOptional()) {if (logger.isDebugEnabled()) {logger.debug('Ignoring optional value for property ’' + tokens.actualName +'’ - property not found on bean class [' + getRootClass().getName() + ']');}return;}else {throw createNotWritablePropertyException(tokens.canonicalName);}}Object oldValue = null;try {//原生值Object originalValue = pv.getValue();Object valueToApply = originalValue;...省略...//这是重点,通过 PropertyHandler 把属性值设置给对象ph.setValue(valueToApply);}catch (TypeMismatchException ex) {throw ex;}
这里的属性值通过 PropertyHandler去设置
@Overridepublic void setValue(@Nullable Object value) throws Exception {//得到属性的set方法Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :this.pd.getWriteMethod());if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {ReflectionUtils.makeAccessible(writeMethod);return null;});try {AccessController.doPrivileged((PrivilegedExceptionAction<Object>)() -> writeMethod.invoke(getWrappedInstance(), value), acc);}catch (PrivilegedActionException ex) {throw ex.getException();}}else {//设置访问权限ReflectionUtils.makeAccessible(writeMethod);//调用set方法把属性值设置进去writeMethod.invoke(getWrappedInstance(), value);}}
这里就是得到属性的set方法,然后调用set方法把值注入进去。
构造器注入参数在之前分析Bean的创建的时候我们就说到,在 AbstractAutowireCapableBeanFactory#createBeanInstance 中会通过反射获取到Bean的构造器,如果是有参构造就会走autowireConstructor 方法,通过有参构造创建实例
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// Make sure bean class is actually resolved at this point.Class<?> beanClass = resolveBeanClass(mbd, beanName);...省略...// Need to determine the constructor...Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if (ctors != null ||mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {//【重要】构造器注入参数return autowireConstructor(beanName, mbd, ctors, args);}// No special handling: simply use no-arg constructor.return instantiateBean(beanName, mbd);}
在autowireConstructor方法中会通过 ConstructorResolver 对构造器参数进行解析
protected BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {//构造器解析器,注入return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);}public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,@Nullable Constructor<?>[] chosenCtors, @Nullable final Object[] explicitArgs) {...省略...else {//得到构造器参数ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();//得到构造器参数值resolvedValues = new ConstructorArgumentValues();//解析参数值【重要】minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);}...省略...try {//实例化策略final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();Object beanInstance;if (System.getSecurityManager() != null) {final Constructor<?> ctorToUse = constructorToUse;final Object[] argumentsToUse = argsToUse;beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),beanFactory.getAccessControlContext());}else {//实例化对象,根据有参构造器,使用反射创建实例beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);}bw.setBeanInstance(beanInstance);return bw;}
resolveConstructorArguments 方法中又通过 BeanDefinitionValueResolver来解析属性值,有参数的值了,就会走反射,根据有参构造器创建实例返回。
private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();TypeConverter converter = (customConverter != null ? customConverter : bw);//属性值的解析器BeanDefinitionValueResolver valueResolver =new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);...省略...for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {if (valueHolder.isConverted()) {resolvedValues.addGenericArgumentValue(valueHolder);}else {//为构造器参数值做解析,这里和之前分析的set注入的属性值解析就一样了Object resolvedValue =valueResolver.resolveValueIfNecessary('constructor argument', valueHolder.getValue());ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());resolvedValueHolder.setSource(valueHolder);resolvedValues.addGenericArgumentValue(resolvedValueHolder);}}return minNrOfArgs;}
因为之前 resolveValueIfNecessary方法已经分析过了,这里就不多说了。
总结到这里属性注入的流程就分析完了,总结都在这个图上
喜欢的话就给个好评吧,你的肯定是我坚持写作最大的动力,来吧兄弟们,给我一点动力
以上就是Spring Bean的实例化之属性注入源码剖析过程的详细内容,更多关于Spring Bean 实例化属性注入的资料请关注好吧啦网其它相关文章!
相关文章: