您现在的位置是:首页 >其他 >Spring 依赖注入源码网站首页其他

Spring 依赖注入源码

胡尚 2023-06-30 16:00:03
简介Spring 依赖注入源码

依赖注入

具体代码是在AbstractAutowireCapableBeanFactory类的populateBean()方法,此方法中主要做的事情如下:

  • 实例化之后,调用InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation方法
  • Spring早期通过BY_NAME或BY_TYPE两种方式,并利用set方法进行依赖注入
  • 通过InstantiationAwareBeanPostProcessor接口的postProcessProperties()方法进行依赖注入,典型的代表就是@Autowired等注解的处理
  • 将BeanDefinition中的PropertyValues覆盖@Autowired等注解的值



原始依赖注入方式

在线流程图

在这里插入图片描述


首先分析Spring早期的依赖注入

@Bean(autowire = Autowire.BY_NAME)
public UserService userService(){
   return new UserService();
}

接下来就会遍历UserService中所有的set方法进行依赖注入。

对应的Spring源码是

PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
// 必须是BY_NAME或BY_TYPE
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
   // MutablePropertyValues是PropertyValues具体的实现类
   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;
}

接下来看autowireByName()方法,主要过程就是先根据set方法找出所有的属性名,然后在遍历属性名集合,去单例池中找,再赋值给pvs变量

protected void autowireByName(
      String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

   // 当前Bean中能进行自动注入的属性名,是根据setXXX()方法生成是属性名
   String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
   // 遍历每个属性名,并去获取Bean对象,并设置到pvs中
   for (String propertyName : propertyNames) {
      // 要进行依赖注入的属性在当前容器中是否存在
      if (containsBean(propertyName)) {
         // 从容器中取出来,再存入pvs中
         Object bean = getBean(propertyName);
         pvs.add(propertyName, bean);
         // 记录一下propertyName对应的Bean被beanName给依赖了
         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");
         }
      }
   }
}

autowireByType()方法其实也类似,首先得到属性名集合,再遍历集合,然后得到方法形参的类型,根据resolveDependency()找到bean对象,再存入pvs



注解方式

在线流程图

在这里插入图片描述


我们常用的方式是利用@Autowired等注解的方式实现依赖注入的,在Spring源码AbstractAutowireCapableBeanFactory类的populateBean()方法中对应的实现其实就是利用InstantiationAwareBeanPostProcessor接口的postProcessProperties()方法实现的

for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
   // @Autowired注解 这里会调用AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法,会直接给对象中的属性赋值
   // AutowiredAnnotationBeanPostProcessor内部并不会处理pvs,直接返回了
   PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
   if (pvsToUse == null) {
      if (filteredPds == null) {
         filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      }
      pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
      if (pvsToUse == null) {
         return;
      }
   }
   pvs = pvsToUse;
}

@Autowired@Value注解是通过AutowiredAnnotationBeanPostProcessor类处理的

@Resource注解是通过CommonAnnotationBeanPostProcessor类处理的


实现看AutowiredAnnotationBeanPostProcessor类的定义,它实现了初始化后置处理器以及BeanDefinition后置处理器两个接口,所以该类就会有下面两个方法

InstantiationAwareBeanPostProcessor接口的postProcessProperties()方法

MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition()方法

public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
      MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
          ...
}

根据我们对Bean生命周期的了解可以知道,postProcessMergedBeanDefinition()方法先执行,postProcessProperties()方法后执行



寻找注入点

我们可以先想一想如果要自己实现依赖注入应该要怎么做?首先就是找出类里面所有加了@Autowired注解的属性和Set方法,这个也称为注入点,然后在为这些注入点赋值。接下来看具体的实现,首先的BeanDefinition的后置处理器方法

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
   // 根据类的class对象找到所有的注入点
   InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
   metadata.checkConfigMembers(beanDefinition);
}

先看findAutowiringMetadata()方法逻辑

private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
   // cacheKey其实就beanName
   String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
   // 该类的所有注入点会缓存到injectionMetadataCache中
   InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
   if (InjectionMetadata.needsRefresh(metadata, clazz)) {
      synchronized (this.injectionMetadataCache) {
         metadata = this.injectionMetadataCache.get(cacheKey);
         if (InjectionMetadata.needsRefresh(metadata, clazz)) {
            if (metadata != null) {
               metadata.clear(pvs);
            }
            // 解析注入点并缓存
            metadata = buildAutowiringMetadata(clazz);
            this.injectionMetadataCache.put(cacheKey, metadata);
         }
      }
   }
   return metadata;
}

核心方法就是buildAutowiringMetadata()根据class找到所有的注入点

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
   // 如果一个Bean的类型是java.*包下的类,比如String,那么则根本不需要为该类进行依赖注入
   if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
      return InjectionMetadata.EMPTY;
   }

   List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
   Class<?> targetClass = clazz;

   do {
      final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

      // 遍历targetClass中的所有Field,每个field都去执行第二个参数的lambda表达式
      ReflectionUtils.doWithLocalFields(targetClass, field -> {
         // field上是否存在@Autowired、@Value、@Inject中的其中一个
         MergedAnnotation<?> ann = findAutowiredAnnotation(field);
         if (ann != null) {
            // static filed不是注入点,不会进行自动注入
            if (Modifier.isStatic(field.getModifiers())) {
               if (logger.isInfoEnabled()) {
                  logger.info("Autowired annotation is not supported on static fields: " + field);
               }
               return;
            }

            // 解析@Autowired注解中的required属性的值,判断这个字段是否是必须要进行注入
            boolean required = determineRequiredStatus(ann);
            // 再构造一个 AutowiredFieldElement 对象作为注入点对象存入集合中
            currElements.add(new AutowiredFieldElement(field, required));
         }
      });

      // 遍历targetClass中的所有Method,每个Method对象都去执行后面的lambda表达式
      ReflectionUtils.doWithLocalMethods(targetClass, method -> {

         // 判断当前Method是否是桥接方法,如果是找到原方法
         Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
         if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
            return;
         }
         // method上是否存在@Autowired、@Value、@Inject中的其中一个
         MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
         if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
            // static method不是注入点,不会进行自动注入
            if (Modifier.isStatic(method.getModifiers())) {
               if (logger.isInfoEnabled()) {
                  logger.info("Autowired annotation is not supported on static methods: " + method);
               }
               return;
            }
            // set方法最好有入参
            if (method.getParameterCount() == 0) {
               if (logger.isInfoEnabled()) {
                  logger.info("Autowired annotation should only be used on methods with parameters: " +
                        method);
               }
            }
            // 解析@Autowired注解中的required属性的值
            boolean required = determineRequiredStatus(ann);
            PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
            // 再构造一个 AutowiredMethodElement 对象作为注入点对象存入集合中
            currElements.add(new AutowiredMethodElement(method, required, pd));
         }
      });

      // 把父类要进行依赖注入的属性放前面,直到找到Object类这一层
      elements.addAll(0, currElements);
      targetClass = targetClass.getSuperclass();
   }
   while (targetClass != null && targetClass != Object.class);

   // 将所有的注入点elements集合封装为InjectionMetadata对象返回
   return InjectionMetadata.forElements(elements, clazz);
}


注入点进行注入

注入点进行注入是基于InstantiationAwareBeanPostProcessor接口的postProcessProperties()方法实现的。

所以在AutowiredAnnotationBeanPostProcessor类中的postProcessMergedBeanDefinition()方法中将寻找到的注入点存入injectionMetadataCache集合中。然后在调用postProcessProperties()进行进行实际的属性注入

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
   // 找注入点(所有被@Autowired注解了的Field或Method),此时就能够从injectionMetadataCache获取到值了
   InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
   try {
      // 进行注入
      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;
}

findAutowiringMetadata()方法还是和上面的一样,只是这次就能够从injectionMetadataCache获取到值了。重点看inject()注入的逻辑,这里其实就是遍历上一步寻找注入点时得到的集合,然后再继续调用element.inject(target, beanName, pvs);

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
   Collection<InjectedElement> checkedElements = this.checkedElements;
   // injectedElements属性值就是上一步寻找注入点时的结果
   Collection<InjectedElement> elementsToIterate =
         (checkedElements != null ? checkedElements : this.injectedElements);
   if (!elementsToIterate.isEmpty()) {
      // 遍历每个注入点进行依赖注入
      // @Resource注解才是对应的InjectedElement类;@Autowired注解对应的它的子类AutowiredFieldElement或AutowiredMethodElement,
      for (InjectedElement element : elementsToIterate) {
         element.inject(target, beanName, pvs);
      }
   }
}

所以如果是针对@Autowired注解,那么我们应该要看InjectedElement的子类AutowiredFieldElementAutowiredMethodElementinject()方法

首先是针对属性的依赖注入方法AutowiredFieldElement类的inject()方法,主要就是根据Field对象去BeanFactory中找到具体的值,然后赋值给这个属性

protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {

   Field field = (Field) this.member;
   Object value;
   // 刚开始是没有缓存的,会直接走else语句段
   if (this.cached) {
      // 对于原型Bean,第一次创建的时候,也找注入点,然后进行注入,此时cached为false,注入完了之后cached为true
      // 第二次创建的时候,先找注入点(此时会拿到缓存好的注入点),也就是AutowiredFieldElement对象,此时cache为true,也就进到此处了
      // 注入点内并没有缓存被注入的具体Bean对象,而是beanName,这样就能保证注入到不同的原型Bean对象
      try {
         value = resolvedCachedArgument(beanName, this.cachedFieldValue);
      }
      catch (NoSuchBeanDefinitionException ex) {
         // Unexpected removal of target bean for cached argument -> re-resolve
         value = resolveFieldValue(field, bean, beanName);
      }
   }
   else {
      // 根据filed从BeanFactory中查到的匹配的Bean对象
      // resolveFieldValue()方法中最终会调用到resolveDependency()方法找对象
      value = resolveFieldValue(field, bean, beanName);
   }

   // 反射给filed赋值
   if (value != null) {
      ReflectionUtils.makeAccessible(field);
      field.set(bean, value);
   }
}

其实针对方法的AutowiredMethodElement类的inject()方法具体实现也类似,利用Method方法中的参数去BeanFactory中找到具体的值,然后在执行方法

protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
   // 如果pvs中已经有当前注入点的值了,则跳过注入
   if (checkPropertySkipping(pvs)) {
      return;
   }
   Method method = (Method) this.member;
   Object[] arguments;
   // 缓存中找
   if (this.cached) {
      try {
         arguments = resolveCachedArguments(beanName);
      }
      catch (NoSuchBeanDefinitionException ex) {
         arguments = resolveMethodArguments(method, bean, beanName);
      }
   }
   else {
      // 利用Method对象取BeanFactory中找到相应的值
      arguments = resolveMethodArguments(method, bean, beanName);
   }
   if (arguments != null) {
      try {
         ReflectionUtils.makeAccessible(method);
         // 再执行方法
         method.invoke(bean, arguments);
      }
      catch (InvocationTargetException ex) {
         throw ex.getTargetException();
      }
   }
}

接下来就轮到了怎么根据Field和Method对象去BeanFactory中找值了,也就是resolveFieldValue()方法和resolveMethodArguments()方法,这两个方法最终都会调用resolveDependency()方法去找到最终要注入的对象



从BeanFactory中找注入对象

上面Spring原始依赖注入BY_TYPE方式,以及利用@Autowired注解加载属性或方法上,最终都是调用的DefaultListableBeanFactory类中的resolveDependency方法,去BeanFactory中找到要注入的值。

@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
      @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
   // 往descriptor中初始化方法参数名字发现器 用来获取方法入参名字的
   descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());

   // 所需要的类型是Optional,如果字段的类型或方法参数的类型是Optional会有一个单独了处理逻辑
   if (Optional.class == descriptor.getDependencyType()) {
      return createOptionalDependency(descriptor, requestingBeanName);
   }
   // 所需要的的类型是ObjectFactory,或ObjectProvider,也会有一个单独的处理逻辑
   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语句段
   else {
      // 在属性或set方法参数前使用了@Lazy注解,那么则构造一个代理对象并返回,真正使用该代理对象时才进行类型筛选Bean
      Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
            descriptor, requestingBeanName);

      if (result == null) {
         // descriptor表示某个属性或某个set方法
         // requestingBeanName表示正在进行依赖注入的Bean
         result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
      }
      return result;
   }
}

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

   InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
   try {
      // 如果当前descriptor之前做过依赖注入了,则可以直接取shortcut了,相当于缓存
      Object shortcut = descriptor.resolveShortcut(this);
      if (shortcut != null) {
         return shortcut;
      }

      // 字段的类型或方法形参的类型
      Class<?> type = descriptor.getDependencyType();
      // 下面这个if逻辑是处理@Value注解的。获取@Value所指定的值
      Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
      if (value != null) {
         if (value instanceof String) {
            // 占位符填充(${XXX}) 就是用XXX作为key,去Environment对象中找对应的value,如果没有找到就直接返回${XXX}字符串
            String strVal = resolveEmbeddedValue((String) value);
            BeanDefinition bd = (beanName != null && containsBean(beanName) ?
                  getMergedBeanDefinition(beanName) : null);
            // 解析Spring表达式(#{})
            value = evaluateBeanDefinitionString(strVal, bd);
         }
         // 将value转化为descriptor所对应的类型
         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()));
         }
      }

      // 如果descriptor所对应的类型是数组、集合、Map这些,就将descriptor对应的类型所匹配的所有bean方法,不用进一步再根据beanName做筛选了
      Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
      if (multipleBeans != null) {
         return multipleBeans;
      }

      
      // 根据type去找bean。找到所有Bean,key是beanName, value有可能是bean对象,有可能是beanClass
      Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
      if (matchingBeans.isEmpty()) {
         // 根据type一个bean都没有找到, 同时required还为true,则抛异常
         if (isRequired(descriptor)) {
            raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
         }
         return null;
      }

      String autowiredBeanName;
      Object instanceCandidate;

      if (matchingBeans.size() > 1) {
         // 根据类型找到了多个Bean,进一步筛选出某一个, @Primary-->优先级最高--->name
         autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
         if (autowiredBeanName == null) {
            // 如果没有找打bean,同时required还为true,则抛异常
            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 {
         // 表示根据type只找到了一个bean对象
         // We have exactly one match.
         Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
         autowiredBeanName = entry.getKey();
         instanceCandidate = entry.getValue();
      }

      // 记录匹配过的beanName
      if (autowiredBeanNames != null) {
         autowiredBeanNames.add(autowiredBeanName);
      }
      // 有可能筛选出来的是某个bean的类型,此处就进行实例化,调用getBean
      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);
   }
}

接下来再来看看调用findAutowireCandidates()方法是如何根据type找bean对象的

protected Map<String, Object> findAutowireCandidates(
      @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {

   // 从BeanFactory中找出和requiredType所匹配的beanName,仅仅是beanName
   // 这些bean不一定经过了实例化,只有到最终确定某个Bean了,如果这个Bean还没有实例化才会真正进行实例化
   String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
         this, requiredType, true, descriptor.isEager());
   Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);

   // 根据类型从resolvableDependencies中匹配Bean,resolvableDependencies中存放的是类型:Bean对象,比如BeanFactory.class:BeanFactory对象,在Spring启动时设置
   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;
         }
      }
   }

   // 依赖注入 注入自己这种情况下,如果一个type存在多个bean对象,优先考虑的是其他的bean对象
   for (String candidate : candidateNames) {
      // 如果不是自己,则判断该candidate到底能不能用来进行自动注入。isAutowireCandidate()采用了责任链设计模式
      // 因为我们可以使用@Bean注解的autowireCandidate=false来指定当前bean不能参与依赖注入
      if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
         // bean对象添加进result集合中
         addCandidateEntry(result, candidate, descriptor, requiredType);
      }
   }

   // 为空要么是真的没有匹配的,要么是匹配的自己
   if (result.isEmpty()) {
      // 需要匹配的类型是不是Map、数组之类的
      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);
         }
      }

      // 匹配的是自己,被自己添加到result中
      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;
}


总结

  • Spring早期依赖注入的两种方式:BY_NAME 和 BY_TYPE

  • 寻找所有的注入点,AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition()

  • 为注入点赋值,入口

    AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement.inject()

    AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement.inject()

  • 处理@Value注解,DefaultListableBeanFactory.doResolveDependency()

  • 根据type,然后遍历所有的BeanDefinition,找到匹配的beanName集合。DefaultListableBeanFactory.findAutowireCandidates()

  • 判断1,处理@Bean注解的autowireCandidate=false,判断BeanDefinition中的autowireCandidate属性值

    SimpleAutowireCandidateResolver.isAutowireCandidate()

  • 判断2,处理泛型的情况 GenericTypeAwareAutowireCandidateResolver.isAutowireCandidate()

  • 判断3,处理@Qualifier注解,QualifierAnnotationAutowireCandidateResolver.isAutowireCandidate()

  • 如果经过上面三个筛选之后还剩下多个bean,进一步筛选@Primary–>优先级最高—>name DefaultListableBeanFactory.determineAutowireCandidate()

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。