Spring-@Resource和@Autowired的分析


​ 从源码分析了@Resource和@Autowired的依赖创建流程和这两个注解的的异同

紧接上篇文章Spring-Bean的字段填充阶段相关处理器

@Resource

​ CommonAnnotationBeanPostProcessor#autowireResource部分核心源码

if (factory instanceof AutowireCapableBeanFactory) {
  AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
  // field依赖会构建成LookupDependencyDescriptor,required只能为true
  DependencyDescriptor descriptor = element.getDependencyDescriptor();
  // byType
  // 当不设置@Resource.name字段值,以字段名作为beanName的Bean不在容器中
  if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
    autowiredBeanNames = new LinkedHashSet<>();
    // 解析依赖bean
    resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
    if (resource == null) {
      throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
    }
  } else { // byName
    resource = beanFactory.resolveBeanByName(name, descriptor);
    autowiredBeanNames = Collections.singleton(name);
  }
}

@Autowired

​ AutowiredFieldElement#resolveFieldValue部分核心源码

// 此时required可由我们定义,表示这个bean不再是必须存在的
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();
Object value;
try {
  // 解析依赖bean,只有byType
  value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
  throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}

公共的解析源码

AutowireCapableBeanFactory#resolveDependency

主要流程:

  1. 判断注入点是否标注了 @Lazy,如有,则返回懒加载代理对象;
  2. 若标注了 @Value,解析其占位符表达式并进行类型转换;
  3. 判断依赖类型,若是集合类型(如 List、Map、Stream 、数组等),则调用 resolveMultipleBeans 获取所有候选
  4. 若为单个 Bean 类型,则根据类型查找候选 Bean,结合 @Qualifier@Primary@Priority 等注解进行筛选;
  5. 若无匹配 Bean,是否抛出异常由 required 属性决定。
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()) { // 处理类型为Optional
    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 {
    // 判断是否有@Lazy注解。使用了@Lazy则在这里直接创建了代理对象并返回
    Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
        descriptor, requestingBeanName);
    if (result == null) {
      // 开始获取依赖bean
      result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
    }
    return result;
  }
}

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

  InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
  try {
    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()));
      }
    }
    // 先进行多bean解析
    Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
    if (multipleBeans != null) { // 多bean解析出来了则直接返回
      return multipleBeans;
    }
    // 将这个type所有的可能bean都解析出来
    Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
    if (matchingBeans.isEmpty()) { // 没找到
      if (isRequired(descriptor)) { 
        // 如过required为true,会直接跑异常
        // 只有@Autowired才可设置required为false
        raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
      }
      return null;
    }

    // ====== 走到这表示这个bean是单个的,需要再根据其他注解来返回一个优先级最高的bean ======

    // 最终的依赖beanName
    String autowiredBeanName;
    // 最终的依赖bean实例
    Object instanceCandidate;

    if (matchingBeans.size() > 1) { // 存在多个候选bean
      // 会先根据@Primary注解筛选,否则根据@Priority筛选出优先级最高的bean
      autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
      if (autowiredBeanName == null) { // 异常处理,根据required选择是否跑异常
        if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
          return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
        }
        else {
          return null;
        }
      }
      instanceCandidate = matchingBeans.get(autowiredBeanName);
    }
    else { // 只有1个候选bean
      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);
  }
}

DefaultListableBeanFactory#resolveMultipleBeans

​ 支持注入类型为 Collection<T>Map<String, T>T[]Stream<T> 的多 Bean 依赖。该方法会查找所有匹配的候选 Bean,按类型筛选、处理限定符(如 @Qualifier),并封装成目标集合类型返回。

/**
处理依赖bean的type是一个容器的情况。可能为 数组、集合、Map甚至Stream
*/
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
    @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {

  Class<?> type = descriptor.getDependencyType();

  if (descriptor instanceof StreamDependencyDescriptor) { // type = Stream
    Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
    if (autowiredBeanNames != null) {
      autowiredBeanNames.addAll(matchingBeans.keySet());
    }
    Stream<Object> stream = matchingBeans.keySet().stream()
        .map(name -> descriptor.resolveCandidate(name, type, this))
        .filter(bean -> !(bean instanceof NullBean));
    if (((StreamDependencyDescriptor) descriptor).isOrdered()) {
      stream = stream.sorted(adaptOrderComparator(matchingBeans));
    }
    return stream;
  }
  else if (type.isArray()) { // type = 数组
    Class<?> componentType = type.getComponentType();
    ResolvableType resolvableType = descriptor.getResolvableType();
    Class<?> resolvedArrayType = resolvableType.resolve(type);
    if (resolvedArrayType != type) {
      componentType = resolvableType.getComponentType().resolve();
    }
    if (componentType == null) {
      return null;
    }
    Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
        new MultiElementDescriptor(descriptor));
    if (matchingBeans.isEmpty()) {
      return null;
    }
    if (autowiredBeanNames != null) {
      autowiredBeanNames.addAll(matchingBeans.keySet());
    }
    TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
    Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType);
    if (result instanceof Object[]) {
      Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
      if (comparator != null) {
        Arrays.sort((Object[]) result, comparator);
      }
    }
    return result;
  }
  else if (Collection.class.isAssignableFrom(type) && type.isInterface()) { // type = 集合
    // 解析出这个bean的范型type
    Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
    if (elementType == null) {
      return null;
    }
    // 找出匹配范型type的候选bean
    Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
        new MultiElementDescriptor(descriptor));
    if (matchingBeans.isEmpty()) {
      return null;
    }
    if (autowiredBeanNames != null) {
      autowiredBeanNames.addAll(matchingBeans.keySet());
    }
    TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
    Object result = converter.convertIfNecessary(matchingBeans.values(), type);
    if (result instanceof List) {
      if (((List<?>) result).size() > 1) {
        Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
        if (comparator != null) {
          ((List<?>) result).sort(comparator);
        }
      }
    }
    return result;
  }
  else if (Map.class == type) {  // type = Map
    ResolvableType mapType = descriptor.getResolvableType().asMap();
    Class<?> keyType = mapType.resolveGeneric(0);
    if (String.class != keyType) {
      return null;
    }
    // 解析出Map中value的type
    Class<?> valueType = mapType.resolveGeneric(1);
    if (valueType == null) {
      return null;
    }
    // 对value type进行bean搜索,返回
    Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
        new MultiElementDescriptor(descriptor));
    if (matchingBeans.isEmpty()) {
      return null;
    }
    if (autowiredBeanNames != null) {
      autowiredBeanNames.addAll(matchingBeans.keySet());
    }
    return matchingBeans;
  }
  else {
    return null;
  }
}

DefaultListableBeanFactory#findAutowireCandidates

DefaultListableBeanFactory#findAutowireCandidates 用于查找参数中 beanName(如 Bean A)所依赖的、类型为 requiredType 的所有候选 Bean(如 Bean B)。返回结果为一个 Map<String, Object>,其中 key 是候选 Bean 的名称,value 是对应的实例。

​ 方法内部会先在 BeanFactory 中找出所有类型匹配 requiredType 的 Bean 名称,然后根据限定注解(如 @Qualifier)等条件进行筛选。筛选通过的候选 Bean 会被递归创建并作为依赖返回。

protected Map<String, Object> findAutowireCandidates(
    @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
  // 找出这个type所有的beanName
  // 内部就是遍历BeanFactory中所有的BeanDefinition,依次进行type匹配判断,在收集结果并缓存
  String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
      this, requiredType, true, descriptor.isEager());
  Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
  // 一些特殊bean的处理,比如ApplicationContext之类的bean
  for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
    Class<?> autowiringType = classObjectEntry.getKey();
    if (autowiringType.isAssignableFrom(requiredType)) {
      Object autowiringValue = classObjectEntry.getValue();
      autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
      if (requiredType.isInstance(autowiringValue)) {
        result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
        break;
      }
    }
  }
  // 依次判断每个候选beanName,看其是否有资格成为真正的目标bean
  for (String candidate : candidateNames) {
    // 非自引用,isAutowireCandidate最终会调用到QualifierAnnotationAutowireCandidateResolver#isAutowireCandidate方法,根据@Qualifier注解来判断是否是目标bean
    if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) { 
      // 目标bean,会使用BeanFactory来获取这个bean。实现递归创建bean
      addCandidateEntry(result, candidate, descriptor, requiredType);
    }
  }
  if (result.isEmpty()) { // 上面的流程没找到,则进行fallback放宽条件继续找
    boolean multiple = indicatesMultipleBeans(requiredType);
    DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
    for (String candidate : candidateNames) {
      if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
          (!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
        addCandidateEntry(result, candidate, descriptor, requiredType);
      }
    }
    if (result.isEmpty() && !multiple) { // 继续放宽条件
      for (String candidate : candidateNames) {
        if (isSelfReference(beanName, candidate) &&
            (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
            isAutowireCandidate(candidate, fallbackDescriptor)) {
          addCandidateEntry(result, candidate, descriptor, requiredType);
        }
      }
    }
  }
  return result;
}

两个注解总结

共同点

  • 都支持容器类型的Bean解析(比如Stream,数组,集合,Map
  • 都支持@Lazy@Qualifier@Value等注解
  • 都支持字段、方法参数

不同点

  • @Autowired可以设置required为false,即不强制需要这个bean。而@Resource则必须要对应的bean存在
  • @Resource由javax提供,是集byName和byType为一体的注解。框架无关,属于 Java 官方对 IOC 容器的通用约定。在Spring中,当没设置@Resource的name,并且由框架解析出来的name(字段名or去掉set的方法名)不在容器中才会使用byType
  • @Autowired本身只能byType,搭配@Qualifier才可实现byName