返回介绍

5.7.3 属性注入

发布于 2025-04-22 22:09:11 字数 18253 浏览 0 评论 0 收藏

在了解循环依赖的时候,我们曾经反复提到了 populateBean 这个函数,也多少了解了这个函数的主要功能就是属性填充,那么究竟是如何实现填充的呢?

protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {

  PropertyValues pvs = mbd.getPropertyValues();

  if (bw == null) {

   if (!pvs.isEmpty()) {

    throw new BeanCreationException(

    mbd.getResourceDescription(), beanName, "Cannot apply property

    values to null instance");

  }

   else {

   //没有可填充的属性

   return;

  }

 }

 //给 InstantiationAwareBeanPostProcessors 最后一次机会在属性设置前来改变 bean

 //如:可以用来支持属性注入的类型

  boolean continueWithPropertyPopulation = true;

  if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {

   for (BeanPostProcessor bp : getBeanPostProcessors()) {

    if (bp instanceof InstantiationAwareBeanPostProcessor) {

     PostProcessor) bp;

     InstantiationAwareBeanPostProcessor ibp = (Instantiation AwareBean

    //返回值为是否继续填充 bean

     if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(),

    beanName)) {

     continueWithPropertyPopulation = false;

    break;

   }

  }

 }

}

//如果后处理器发出停止填充命令则终止后续的执行

if (!continueWithPropertyPopulation) {

 return;

}

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||

mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {

  MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

  // Add property values based on autowire by name if applicable.

 //根据名称自动注入

  if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {

  autowireByName(beanName, mbd, bw, newPvs);

 }

  // Add property values based on autowire by type if applicable.

 //根据类型自动注入

  if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {

  autowireByType(beanName, mbd, bw, newPvs);

 }

  pvs = newPvs;

}

//后处理器已经初始化

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();

//需要依赖检查

boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.

DEPENDENCY_CHECK_NONE);

if (hasInstAwareBpps || needsDepCheck) {

  PropertyDescriptor[] filteredPds = filterPropertyDescriptors ForDependency

Check(bw);

  if (hasInstAwareBpps) {

   for (BeanPostProcessor bp : getBeanPostProcessors()) {

    if (bp instanceof InstantiationAwareBeanPostProcessor) {

     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBean

     PostProcessor) bp;

    //对所有需要依赖检查的属性进行后处理

     pvs = ibp.postProcessPropertyValues(pvs, filteredPds,

     bw.getWrappedInstance(), beanName);

     if (pvs == null) {

     return;

    }

   }

  }

 }

   if (needsDepCheck) {

   //依赖检查,对应 depends-on 属性,3.0 已经弃用此属性

    checkDependencies(beanName, mbd, filteredPds, pvs);

  }

 }

 //将属性应用到 bean 中

 applyPropertyValues(beanName, mbd, bw, pvs);

}

在 populateBean 函数中提供了这样的处理流程。

(1)InstantiationAwareBeanPostProcessor 处理器的 postProcessAfterInstantiation 函数的应用,此函数可以控制程序是否继续进行属性填充。

(2)根据注入类型(byName/byType),提取依赖的 bean,并统一存入 PropertyValues 中。

(3)应用 InstantiationAwareBeanPostProcessor 处理器的 postProcessPropertyValues 方法,对属性获取完毕填充前对属性的再次处理,典型应用是 RequiredAnnotationBeanPostProcessor 类中对属性的验证。

(4)将所有 PropertyValues 中的属性填充至 BeanWrapper 中。

在上面的步骤中有几个地方是我们比较感兴趣的,它们分别是依赖注入( autowire ByName/autowireByType)以及属性填充,那么,接下来进一步分析这几个功能的实现细节。

1.autowireByName

上文提到根据注入类型(byName/byType),提取依赖的 bean,并统一存入 PropertyValues 中,那么我们首先了解下 byName 功能是如何实现的。

protected void autowireByName(

String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutableProperty

Values pvs) {

 //寻找 bw 中需要依赖注入的属性

  String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);

  for (String propertyName : propertyNames) {

   if (containsBean(propertyName)) {

   //递归初始化相关的 bean

    Object bean = getBean(propertyName);

    pvs.add(propertyName, bean);

   //注册依赖

    registerDependentBean(propertyName, beanName);

    if (logger.isDebugEnabled()) {

     logger.debug("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");

   }

  }

 }

}

如果读者之前了解了 autowire 的使用方法,相信理解这个函数的功能不会太困难,无非是在传入的参数 pvs 中找出已经加载的 bean,并递归实例化,进而加入到 pvs 中。

2.autowireByType

autowireByType 与 autowireByName 对于我们理解与使用来说复杂程度都很相似,但是其实现功能的复杂度却完全不一样。

protected void autowireByType(

String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutableProperty Values pvs) {

  TypeConverter converter = getCustomTypeConverter();

  if (converter == null) {

   converter = bw;

 }

  Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);

 //寻找 bw 中需要依赖注入的属性

  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.equals(pd.getPropertyType())) {

    //探测指定属性的 set 方法

     MethodParameter methodParam = BeanUtils.getWriteMethod Parameter(pd);

     boolean eager = !PriorityOrdered.class. isAssignableFrom (bw.get

    WrappedClass());

     DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor

     (methodParam, eager);

    //解析指定 beanName 的属性所匹配的值,并把解析到的属性名称存储在

    autowiredBeanNames 中,当属性存在多个封装 bean 时如:

     //@Autowired private List<A> aList; 将会找到所有匹配 A 类型的 bean 并

    将其注入

     Object autowiredArgument = resolveDependency(desc, beanName,

     autowiredBeanNames, converter);

     if (autowiredArgument != null) {

      pvs.add(propertyName, autowiredArgument);

    }

     for (String autowiredBeanName : autowiredBeanNames) {

     //注册依赖

      registerDependentBean(autowiredBeanName, beanName);

      if (logger.isDebugEnabled()) {

       beanName + "' via property '" +

       logger.debug("Autowiring by type from bean name '" +

       propertyName + "' to bean named '" +

       autowiredBeanName + "'");

     }

    }

    autowiredBeanNames.clear();

   }

  }

   catch (BeansException ex) {

    throw new UnsatisfiedDependencyException(mbd.getResourceDescription(),

    beanName, propertyName, ex);

  }

 }

}

实现根据名称自动匹配的第一步就是寻找 bw 中需要依赖注入的属性,同样对于根据类型自动匹配的实现来讲第一步也是寻找 bw 中需要依赖注入的属性,然后遍历这些属性并寻找类型匹配的 bean,其中最复杂的就是寻找类型匹配的 bean。同时,Spring 中提供了对集合的类型注入的支持,如使用注解的方式:

@Autowired

  private List<Test> tests;

Spring 将会把所有与 Test 匹配的类型找出来并注入到 tests 属性中,正是由于这一因素,所以在 autowireByType 函数中,新建了局部遍历 autowiredBeanNames,用于存储所有依赖的 bean,如果只是对非集合类的属性注入来说,此属性并无用处。

对于寻找类型匹配的逻辑实现封装在了 resolveDependency 函数中。

DefaultListableBeanFactory.java

public Object resolveDependency(DependencyDescriptor descriptor, String beanName,

Set<String> autowiredBeanNames, TypeConverter typeConverter) throws

BeansException {

 descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());

  if (descriptor.getDependencyType().equals(ObjectFactory.class)) {

  //ObjectFactory 类注入的特殊处理

   return new DependencyObjectFactory(descriptor, beanName);

 }

  else if (descriptor.getDependencyType().equals(javaxInjectProviderClass)) {

  //javaxInjectProviderClass 类注入的特殊处理

  beanName);

   return new DependencyProviderFactory().createDependencyProvider (descriptor,

 }

  else {

  //通用处理逻辑

   return doResolveDependency(descriptor, descriptor.getDependencyType(),

   beanName, autowiredBeanNames, typeConverter);

 }

}

protected Object doResolveDependency(DependencyDescriptor descriptor, Class<?> type,

String beanName,

Set<String> autowiredBeanNames, TypeConverter typeConverter) throws

BeansException {

 /*

  * 用于支持 Spring 中新增的注解 @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());

   return converter.convertIfNecessary(value, type);

 }

 //如果解析器没有成功解析,则需要考虑各种情况

 //属性是数组类型

  if (type.isArray()) {

   Class<?> componentType = type.getComponentType();

  //根据属性类型找到 beanFacotry 中所有类型的匹配 bean,

  //返回值的构成为:key=匹配的 beanName,value=beanName 对应的实例化后的 bean(通过

  getBean(beanName) 返回)

   Map<String, Object> matchingBeans = findAutowireCandidates(beanName,

   componentType, descriptor);

   if (matchingBeans.isEmpty()) {

   //如果 autowire 的 require 属性为 true 而找到的匹配项却为空则只能抛出异常

    if (descriptor.isRequired()) {

     raiseNoSuchBeanDefinitionException(componentType, "array of " +

     componentType.getName(), descriptor);

   }

    return null;

  }

   if (autowiredBeanNames != null) {

   autowiredBeanNames.addAll(matchingBeans.keySet());

  }

   TypeConverter converter = (typeConverter != null ? typeConverter :

  getTypeConverter());

  //通过转换器将 bean 的值转换为对应的 type 类型

   return converter.convertIfNecessary(matchingBeans.values(), type);

 }

 //属性是 Collection 类型

  else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {

   Class<?> elementType = descriptor.getCollectionType();

   if (elementType == null) {

    if (descriptor.isRequired()) {

     throw new FatalBeanException("No element type declared for

     collection [" + type.getName() + "]");

   }

    return null;

  }

    Map<String, Object> matchingBeans = findAutowireCandidates(beanName,

    elementType, descriptor);

    if (matchingBeans.isEmpty()) {

     if (descriptor.isRequired()) {

      raiseNoSuchBeanDefinitionException(elementType, "collection of "

      + elementType.getName(), descriptor);

    }

     return null;

   }

    if (autowiredBeanNames != null) {

    autowiredBeanNames.addAll(matchingBeans.keySet());

   }

    TypeConverter converter = (typeConverter != null ? typeConverter :

   getTypeConverter());

    return converter.convertIfNecessary(matchingBeans.values(), type);

  }

  //属性是 Map 类型

   else if (Map.class.isAssignableFrom(type) && type.isInterface()) {

    Class<?> keyType = descriptor.getMapKeyType();

    if (keyType == null || !String.class.isAssignableFrom(keyType)) {

     if (descriptor.isRequired()) {

      throw new FatalBeanException("Key type [" + keyType + "] of map

      [" + type.getName() +

      "] must be assignable to [java.lang.String]");

    }

     return null;

   }

    Class<?> valueType = descriptor.getMapValueType();

    if (valueType == null) {

     if (descriptor.isRequired()) {

      throw new FatalBeanException("No value type declared for map ["

      + type.getName() + "]");

    }

     return null;

   }

    Map<String, Object> matchingBeans = findAutowireCandidates(beanName,

    valueType, descriptor);

    if (matchingBeans.isEmpty()) {

     if (descriptor.isRequired()) {

      raiseNoSuchBeanDefinitionException(valueType, "map with value

      type " + valueType.getName(), descriptor);

    }

     return null;

   }

    if (autowiredBeanNames != null) {

    autowiredBeanNames.addAll(matchingBeans.keySet());

   }

    return matchingBeans;

   }else {

    Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type,

   descriptor);

    if (matchingBeans.isEmpty()) {

     if (descriptor.isRequired()) {

      raiseNoSuchBeanDefinitionException(type, "", descriptor);

    }

     return null;

   }

    if (matchingBeans.size() > 1) {

     String primaryBeanName = determinePrimaryCandidate(matchingBeans,

    descriptor);

     if (primaryBeanName == null) {

      matching bean but found " +

      throw new NoSuchBeanDefinitionException(type, "expected single

      matchingBeans.size() + ": " + matchingBeans.keySet());

    }

     if (autowiredBeanNames != null) {

     autowiredBeanNames.add(primaryBeanName);

    }

     return matchingBeans.get(primaryBeanName);

   }

   //已经可以确定只有一个匹配项

   next();

    Map.Entry<String, Object> entry = matchingBeans.entrySet(). iterator().

    if (autowiredBeanNames != null) {

    autowiredBeanNames.add(entry.getKey());

   }

    return entry.getValue();

  }

 }

寻找类型的匹配执行顺序时,首先尝试使用解析器进行解析,如果解析器没有成功解析,那么可能是使用默认的解析器没有做任何处理,或者是使用了自定义的解析器,但是对于集合等类型来说并不在解析范围之内,所以再次对不同类型进行不同情况的处理,虽说对于不同类型处理方式不一致,但是大致的思路还是很相似的,所以函数中只对数组类型进行了详细地注释。

3.applyPropertyValues

程序运行到这里,已经完成了对所有注入属性的获取,但是获取的属性是以 PropertyValues 形式存在的,还并没有应用到已经实例化的 bean 中,这一工作是在 applyPropertyValues 中。

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw,

PropertyValues pvs) {

  if (pvs == null || pvs.isEmpty()) {

  return;

 }

  MutablePropertyValues mpvs = null;

  List<PropertyValue> original;

  if (System.getSecurityManager()!= null) {

   if (bw instanceof BeanWrapperImpl) {

    ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());

  }

 }

  if (pvs instanceof MutablePropertyValues) {

   mpvs = (MutablePropertyValues) pvs;

  //如果 mpvs 中的值已经被转换为对应的类型那么可以直接设置到 beanwapper 中

   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 {

  //如果 pvs 并不是使用 MutablePropertyValues 封装的类型,那么直接使用原始的属性获取方法

   original = Arrays.asList(pvs.getPropertyValues());

 }

  TypeConverter converter = getCustomTypeConverter();

  if (converter == null) {

   converter = bw;

 }

 //获取对应的解析器

 BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this,

  beanName, mbd, converter);

  // Create a deep copy, resolving any references for values.

  List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());

  boolean resolveNecessary = false;

 //遍历属性,将属性转换为对应类的对应属性的类型

  for (PropertyValue pv : original) {

   if (pv.isConverted()) {

   deepCopy.add(pv);

   }else {

    String propertyName = pv.getName();

    Object originalValue = pv.getValue();

    Object resolvedValue = valueResolver.resolveValueIfNecessary(pv,

   originalValue);

    Object convertedValue = resolvedValue;

    boolean convertible = bw.isWritableProperty(propertyName) &&

    !PropertyAccessorUtils.isNestedOrIndexedProperty

    (propertyName);

    if (convertible) {

     bw, converter);

     convertedValue = convertForProperty(resolvedValue, propertyName,

   }

    if (resolvedValue == originalValue) {

     if (convertible) {

     pv.setConvertedValue(convertedValue);

    }

    deepCopy.add(pv);

   }

    else if (convertible && originalValue instanceof TypedStringValue &&

     !((TypedStringValue) originalValue).isDynamic() &&

     (convertedValue))) {

     !(convertedValue instanceof Collection || ObjectUtils.isArray

    pv.setConvertedValue(convertedValue);

    deepCopy.add(pv);

   }

    else {

     resolveNecessary = true;

     deepCopy.add(new PropertyValue(pv, convertedValue));

   }

  }

 }

  if (mpvs != null && !resolveNecessary) {

  mpvs.setConverted();

 }

  try {

   bw.setPropertyValues(new MutablePropertyValues(deepCopy));

 }

  catch (BeansException ex) {

   throw new BeanCreationException(

   values", ex);

   mbd.getResourceDescription(), beanName, "Error setting property

 }

}

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。