主要流程

  1. 当一个 Bean 被构建时,核心包括两个基本步骤:执行 AbstractAutowireCapableBeanFactory#createBeanInstance 方法:通过构造器反射构造出这个 Bean,在此案例中相当于构建出 bean 的实例;
  2. 执行 AbstractAutowireCapableBeanFactory#populate 方法:填充(即设置)这个 Bean,在本案例中,相当于设置 实例中被 @Autowired 标记的 属性成员。

@Autowire填充主要过程


protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
     //省略非关键代码
     for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
           InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
           PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
         //省略非关键代码
        }
    }
  }  
}
  1. 寻找出所有需要依赖注入的字段和方法,参考 AutowiredAnnotationBeanPostProcessor#postProcessProperties 中的代码行​
    InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
  2. 根据依赖信息寻找出依赖并完成注入,以字段注入为例,参考 AutowiredFieldElement#inject 方法​
    @Override
    protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
      Field field = (Field) this.member;
      Object value;
      //省略非关键代码
         try {
             DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
            //寻找“依赖”,desc为”dataService”的DependencyDescriptor
            value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
        }
         
      }
      //省略非关键代码
      if (value != null) {
         ReflectionUtils.makeAccessible(field);
         //装配“依赖”
         field.set(bean, value);
      }
    }
  3. 处理依赖注入DefaultListableBeanFactory#doResolveDependency,选择符合条件的bean注入。如果有多个bean
    • 调用 determineAutowireCandidate 方法来选出优先级最高的依赖,但是发现并没有优先级可依据。具体选择过程可参考 DefaultListableBeanFactory#determineAutowireCandidate:protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
        Class<?> requiredType = descriptor.getDependencyType();
        String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
        if (primaryCandidate != null) {
           return primaryCandidate;
        }
        String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
        if (priorityCandidate != null) {
           return priorityCandidate;
        }
        // Fallback
        for (Map.Entry<String, Object> entry : candidates.entrySet()) {
           String candidateName = entry.getKey();
           Object beanInstance = entry.getValue();
           if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
                 matchesBeanName(candidateName, descriptor.getDependencyName())) {
              return candidateName;
          }
        }
        return null;
      }
      • @Autowired 要求是必须注入的(即 required 保持默认值为 true),或者注解的属性类型并不是可以接受多个 Bean 的类型,例如数组、Map、集合。这点可以参考 DefaultListableBeanFactory#indicatesMultipleBeans 的实现:​
        private boolean indicatesMultipleBeans(Class<?> type) {
          return (type.isArray() || (type.isInterface() &&
                (Collection.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type))));
        }

注意问题

  1. 多个bean符合条件需要标注@primary,或者使用@Qualifier
  2. @Qualifier如果没有指定名称(name=“”),注意大小:如果一个类名是以两个大写字母开头的,则首字母不变,其它情况下默认首字母变成小写

参考 AnnotationBeanNameGenerator#buildDefaultBeanName

  1. 如果 引用内部类,主要添加外部类的名称,类似@Autowired @Qualifier(“studentController.InnerClassDataService”) DataService innerClassDataService;

@Value注解

集合类型注入(spring编程场景问题03节)

  • 收集方式
  • 直接装配方式
  • 支持注入非原生对象 使用#{}
  • 处理过程参考外部配置,有多个数据源,在获取配置的字符串后需要进行converter
    • QualifierAnnotationAutowireCandidateResolver#findValue 寻找@Value

    @Nullable
    protected Object findValue(Annotation[] annotationsToSearch) {
       if (annotationsToSearch.length > 0) {  
          AnnotationAttributes attr = AnnotatedElementUtils.getMergedAnnotationAttributes(
                AnnotatedElementUtils.forAnnotations(annotationsToSearch), this.valueAnnotationType);
          //valueAnnotationType即为@Value
          if (attr != null) {
             return extractValue(attr);
          }
      }
       return null;
    }
    • 解析@Value字符串​
      @Nullable
      protected <T> T getProperty(String key, Class<T> targetValueType, boolean resolveNestedPlaceholders) {
        if (this.propertySources != null) {
           for (PropertySource<?> propertySource : this.propertySources) {
              Object value = propertySource.getProperty(key);
              if (value != null) {
              //查到value即退出  
              return convertValueIfNecessary(value, targetValueType);
              }
          }
        }

        return null;
      }


      源:
       
      [ConfigurationPropertySourcesPropertySource {name=’configurationProperties’},
      StubPropertySource {name=’servletConfigInitParams’}, ServletContextPropertySource {name=’servletContextInitParams’}, PropertiesPropertySource {name=’systemProperties’}, OriginAwareSystemEnvironmentPropertySource {name=’systemEnvironment’}, RandomValuePropertySource {name=’random’},
      OriginTrackedMapPropertySource {name=’applicationConfig: classpath:/application.properties]’},
      MapPropertySource {name=’devtools’}]
    • 将解析结果转换为要装配的对象类型​
      public class UUIDEditor extends PropertyEditorSupport {

        @Override
        public void setAsText(String text) throws IllegalArgumentException         {
           if (StringUtils.hasText(text)) {
              //转化操作
              setValue(UUID.fromString(text.trim()));
          }
           else {
              setValue(null);
          }
        }
        //省略其他非关代码
       
      }

DefaultListableBeanFactory#resolveMultipleBeans


private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
final Class<?> type = descriptor.getDependencyType();
if (descriptor instanceof StreamDependencyDescriptor) {
//装配stream
return stream;
}
else if (type.isArray()) {
//装配数组
return result;
}
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
//装配集合
//获取集合的元素类型
Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
if (elementType == null) {
return null;
}
//根据元素类型查找所有的bean
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
//转化查到的所有bean放置到集合并返回
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
//省略非关键代码
return result;
}
else if (Map.class == type) {
//解析map
return matchingBeans;
}
else {
return null;
}
}

直接装配和收集不能共存,当使用收集装配方式来装配时,能找到任何一个对应的 Bean,则返回,如果一个都没有找到,才会采用直接装配的方式。


Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);