SpringloC容器的依赖注入源码解析(10)—— populateBean的剩余逻辑

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 {
				// 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);
		}
	}

复制代码

完成了按名字或按类型自动装配后,来到脑图里第三步,对解析完但还未设置的属性进行再处理。

请添加图片描述 这里需要关注AutowiredAnnotationBeanPostProcessor实现的postProcessProperties方法

@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
   // 获取指定类中@Autowired相关注解的元信息
   InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
   try {
      // 对Bean的属性进行自动注入
      metadata.inject(bean, beanName, pvs);
   }
   catch (BeanCreationException ex) {
      throw ex;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
   }
   return pvs;
}
复制代码

首先会去尝试获取InjectionMetadata对象,findAutowiringMetadata方法之前在分析该类的postProcessMergedBeanDefinition方法时,已经获取到了存储有该bean实例里被@Autowired或@Value标签修饰的属性列表的InjectionMetaData对象,并且将其已经放置到了缓存中。再次进入findAutowiringMetadata

请添加图片描述 在此次调用时,相关的InjectionMetadata实例已经从缓存中获取到了,不需要再进到if里面去解析bean了,此时又回到postProcessProperties方法里,取到了InjectionMetadata实例之后直接对bean注入属性

metadata.inject(bean, beanName, pvs);
复制代码
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
   Collection<InjectedElement> checkedElements = this.checkedElements;
   // 要注入的字段集合
   Collection<InjectedElement> elementsToIterate =
         (checkedElements != null ? checkedElements : this.injectedElements);
   if (!elementsToIterate.isEmpty()) {
      // 遍历每个字段并进行注入
      for (InjectedElement element : elementsToIterate) {
         if (logger.isTraceEnabled()) {
            logger.trace("Processing injected element of bean '" + beanName + "': " + element);
         }
         element.inject(target, beanName, pvs);
      }
   }
}
复制代码

该方法遍历每一个属性元素去调用元素的inject方法,进入inject发现又回到了AutowiredAnnotationBeanPostProcessor类里:

@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
     // 获取要注入的成员变量
     Field field = (Field) this.member;
     Object value;
     // 如果成员变量的值先前缓存过
     if (this.cached) {
        // 从缓存中获取成员变量的值
        value = resolvedCachedArgument(beanName, this.cachedFieldValue);
     }
     // 没有缓存
     else {
        // 创建一个成员变量的依赖描述符实例
        DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
        desc.setContainingClass(bean.getClass());
        Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
        Assert.state(beanFactory != null, "No BeanFactory available");
        // 获取容器的类型转换器
        TypeConverter typeConverter = beanFactory.getTypeConverter();
        try {
           // 获取注入的值
           value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
        }
        catch (BeansException ex) {
           throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
        }
        synchronized (this) {
           if (!this.cached) {
              if (value != null || this.required) {
                 this.cachedFieldValue = desc;
                 registerDependentBeans(beanName, autowiredBeanNames);
                 if (autowiredBeanNames.size() == 1) {
                    String autowiredBeanName = autowiredBeanNames.iterator().next();
                    if (beanFactory.containsBean(autowiredBeanName) &&
                          beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
                       this.cachedFieldValue = new ShortcutDependencyDescriptor(
                             desc, autowiredBeanName, field.getType());
                    }
                 }
              }
              else {
                 this.cachedFieldValue = null;
              }
              this.cached = true;
           }
        }
     }
     if (value != null) {
        ReflectionUtils.makeAccessible(field);
        field.set(bean, value);
     }
  }
}
复制代码

在调用的过程中复用了其他类的装配能力,此时是给boyfriend装配上girlfriend实例,首先去缓存里看下之前是否解析过girlfriend,第一次执行会进入到else里,先用DependencyDescriptor包装一下属性field

DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
复制代码

之后给desc注册上宿主的类名(Boyfriend):

desc.setContainingClass(bean.getClass());
复制代码

之后会尝试获取之前容器初始化时注册上去的转换器TypeConverter

TypeConverter typeConverter = beanFactory.getTypeConverter();
复制代码

converter用来做类型转换,默认获取spring自带的simpleTypeConverter用来处理简单类型的转换,之后执行

// 获取注入的值
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
复制代码

进入resolveDependency方法里:

@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
      @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

   descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
   if (Optional.class == descriptor.getDependencyType()) {
      return createOptionalDependency(descriptor, requestingBeanName);
   }
   else if (ObjectFactory.class == descriptor.getDependencyType() ||
         ObjectProvider.class == descriptor.getDependencyType()) {
      return new DependencyObjectProvider(descriptor, requestingBeanName);
   }
   else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
      return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
   }
   else {
      Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
            descriptor, requestingBeanName);
      if (result == null) {
         result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
      }
      return result;
   }
}
复制代码

在方法里会依据依赖描述符的不同类型进行不同的处理,但是最终都会到else里,真正起作用的是doResolveDependency方法

@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
      @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

   InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
   try {
      // 该方法最终调用了beanFactory.getBean(String, Class),从容器中获取依赖
      Object shortcut = descriptor.resolveShortcut(this);
      // 如果容器缓存中存在所需依赖,这里进行短路路操作,提前结束依赖解析逻辑
      if (shortcut != null) {
         return shortcut;
      }

      Class<?> type = descriptor.getDependencyType();
      // 处理@Value注解
      Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
      if (value != null) {
         if (value instanceof String) {
            String strVal = resolveEmbeddedValue((String) value);
            BeanDefinition bd = (beanName != null && containsBean(beanName) ?
                  getMergedBeanDefinition(beanName) : null);
            value = evaluateBeanDefinitionString(strVal, bd);
         }
         TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
         try {
            return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
         }
         catch (UnsupportedOperationException ex) {
            // A custom TypeConverter which does not support TypeDescriptor resolution...
            return (descriptor.getField() != null ?
                  converter.convertIfNecessary(value, type, descriptor.getField()) :
                  converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
         }
      }
      // 如果标识@Autowired注解的成员变量是复合类型,如Array,Collection,Map
      // 从这个方法获取@Autowired里的值
      Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
      if (multipleBeans != null) {
         return multipleBeans;
      }

      Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
      if (matchingBeans.isEmpty()) {
         if (isRequired(descriptor)) {
            raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
         }
         return null;
      }

      String autowiredBeanName;
      Object instanceCandidate;

      if (matchingBeans.size() > 1) {
         autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
         if (autowiredBeanName == null) {
            if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
               return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
            }
            else {
               // In case of an optional Collection/Map, silently ignore a non-unique case:
               // possibly it was meant to be an empty collection of multiple regular beans
               // (before 4.3 in particular when we didn't even look for collection beans).
               return null;
            }
         }
         instanceCandidate = matchingBeans.get(autowiredBeanName);
      }
      else {
         // We have exactly one match.
         Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
         autowiredBeanName = entry.getKey();
         instanceCandidate = entry.getValue();
      }

      if (autowiredBeanNames != null) {
         autowiredBeanNames.add(autowiredBeanName);
      }
      if (instanceCandidate instanceof Class) {
         instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
      }
      Object result = instanceCandidate;
      if (result instanceof NullBean) {
         if (isRequired(descriptor)) {
            raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
         }
         result = null;
      }
      if (!ClassUtils.isAssignableValue(type, result)) {
         throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
      }
      return result;
   }
   finally {
      ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
   }
}
复制代码

首先尝试调用依赖描述符实例的resolveShortcut方法,尝试从容器缓存里获取属性名对应的bean实例

@Nullable
public Object resolveShortcut(BeanFactory beanFactory) throws BeansException {
   return null;
}
复制代码

相对于注解的这种情况,并没有实现该方法。


之后尝试从依赖描述符实例里面去获取目标实例的属性

Class<?> type = descriptor.getDependencyType();
复制代码

这里的目标实例是girlfriend,之后就会调用注解候选解析器的getSuggestedValue方法尝试获取属性值,但是对于@Autowired修饰的属性来说,这一步无法获取到值

@Override
@Nullable
public Object getSuggestedValue(DependencyDescriptor descriptor) {
   Object value = findValue(descriptor.getAnnotations());
   if (value == null) {
      MethodParameter methodParam = descriptor.getMethodParameter();
      if (methodParam != null) {
         value = findValue(methodParam.getMethodAnnotations());
      }
   }
   return value;
}
复制代码

该方法调用findValue方法

@Nullable
protected Object findValue(Annotation[] annotationsToSearch) {
   if (annotationsToSearch.length > 0) {   // qualifier annotations have to be local
      AnnotationAttributes attr = AnnotatedElementUtils.getMergedAnnotationAttributes(
            AnnotatedElementUtils.forAnnotations(annotationsToSearch), this.valueAnnotationType);
      if (attr != null) {
         return extractValue(attr);
      }
   }
   return null;
}
复制代码

该方法主要是提取@Value修饰的属性值的


回到doResolveDependency方法

猜你喜欢

转载自juejin.im/post/7035090054380781581