Spring依赖处理

145 阅读8分钟

本文重点:

  1. Spring 如何挑选合适的方法创建bean
  2. 为什么使用构造注入 注入自己会失败
  3. @Autowired 与 @Resource的区别 、原理

准备工作

准备三个接口 及对应的实现类
public interface IAddress { String getAddress(); }
@Component
@Data
public class AddressA implements IAddress{
    public String getAddress() { return "AddressA";  }
}
 
@Component
@Primary
@Data
public class AddressB implements IAddress{
    public String getAddress() { return "AddressB"; }
}
---------------------
public interface IName {  String getName(); }
@Component
@Data
public class NameA implements IName {
    public String getName() { return "NameA"; }
}
​
@Component
public class NameB implements IName {
    public String getName()   return "NameB";  }
}
----------------------
public interface ISex { String getSex(); }
@Component
@Data
public class SexA implements ISex{
    public String getSex() {  return "SexA"; }
}
​
@Component
@Primary
@Data
public class SexB implements ISex{
    public String getSex() {  return "SexB"; }
}

AddressB ,SexB有 @Primary注解

1.有参构造

现在我们测试一种场景,只有一个构造方法

public TestA(List<IName> names, IAddress iAddress, IName nameA, @Qualifier("sexA") ISex iSex) {
    this.names = names;
    this.iAddress = iAddress;
    this.iName = nameA;
    this.iSex = iSex;
}
@Override
public void afterPropertiesSet() throws Exception {
    log.info("structure:{}",this);
}

structure: TestA(names=[NameA(), NameB()], iAddress=AddressB(), iName=NameA(), iSex=SexA())

这里唯一有歧义的地方是iName的candidate了,先说结论:有@Qualifier的优先,其次@Primary,再之后根据名称查找,最后找不到就抛异常了,下面我们看下依赖是如何注入的

有了上一篇 Spring ioc处理机制 juejin.cn/post/707235… 的基础,我们直接找到创建bean的位置 ,AbstractAutowireCapableBeanFactory#createBeanInstance

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   ...
   if (mbd.getFactoryMethodName() != null) {
      @Bean处理位置
      return instantiateUsingFactoryMethod(beanName, mbd, args);
   }
   ...调用 SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors 筛选出合适的构造器,这里是AutowiredAnnotationBeanPostProcessor 在处理
   Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
            return autowireConstructor(beanName, mbd, ctors, args);
        }
   
   ...反射获取无参给构造 创建对象 到这一步如果没有无参构造就会抛异常了...
   return instantiateBean(beanName, mbd);
}

我们先看下如何决定构造器的

1.1AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
      throws BeanCreationException {
  ...检查带@LookUp注解的方法...
​
   //从缓存中获取 这个类被解析过一遍就不会再解析了
   Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
   if (candidateConstructors == null) {
      synchronized (this.candidateConstructorsCache) {
         candidateConstructors = this.candidateConstructorsCache.get(beanClass);
         if (candidateConstructors == null) {
            Constructor<?>[] rawCandidates;
            try {
               rawCandidates = beanClass.getDeclaredConstructors();
            }
            catch (Throwable ex) {
               ...
            }
            List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
            //遍历构造器数组 上次发现的带@Autowired @Inject的构造器放在这里 做唯一性判断
            Constructor<?> requiredConstructor = null;
            Constructor<?> defaultConstructor = null;
            Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
            int nonSyntheticConstructors = 0;
            for (Constructor<?> candidate : rawCandidates) {
               ...查找@Autowired @Inject 注解...
               MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
               if (ann != null) {
                  //多个带@Autowired @Inject 的构造器就抛异常了
                  }
                  candidates.add(candidate);
               }
               else if (candidate.getParameterCount() == 0) {
                  //无参构造
                  defaultConstructor = candidate;
               }
            }
            if (!candidates.isEmpty()) {
               if (requiredConstructor == null) {
                  //之所以会进这个if 是因为声明了@Autowired(required=false)
                  if (defaultConstructor != null) {
                     //添加无参构造
                     candidates.add(defaultConstructor);
                  }
               }
               candidateConstructors = candidates.toArray(new Constructor<?>[0]);
            }
            else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
               //只有一个有参构造 那就选它了
               candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
            }
            ....
            else {
               candidateConstructors = new Constructor<?>[0];
            }
            this.candidateConstructorsCache.put(beanClass, candidateConstructors);
         }
      }
   }
   //综上 这里能返回基本上 只有一个有参构造 、多个构造包含一个带@Autowired/@Inject注解的构造、多个带@Autowired(required=false)的构造
   return (candidateConstructors.length > 0 ? candidateConstructors : null);
}

1.2 ConstructorResolver#autowireConstructor

public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
      @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
   ...
   if (constructorToUse == null || argsToUse == null) {
      Constructor<?>[] candidates = chosenCtors;
      ...
      if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
         Constructor<?> uniqueCandidate = candidates[0];
         if (uniqueCandidate.getParameterCount() == 0) {
            //只有一个构造 且无参 直接反射调就好
            bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
            return bw;
         }
      }
      //剩下的就是筛选构造 和获取参数了  
      AutowireUtils.sortConstructors(candidates);
      int minTypeDiffWeight = Integer.MAX_VALUE;
      Set<Constructor<?>> ambiguousConstructors = null;
      LinkedList<UnsatisfiedDependencyException> causes = null;
      
      ...多个构造candidate 调用过程中报错 是会继续执行下一个构造的...
      for (Constructor<?> candidate : candidates) {
         int parameterCount = candidate.getParameterCount();
          if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
              // Already found greedy constructor that can be satisfied ->
              // do not look any further, there are only less greedy constructors left.
              //看源码注释也知道 多个构造方法 在上面根据参数个数排序 优先调用参数多的构造方法 
             break;
          }
         ArgumentsHolder argsHolder;
         Class<?>[] paramTypes = candidate.getParameterTypes();
         //一般resolvedValues就是个空对象
         if (resolvedValues != null) {
            try {
               ...获取参数名  String[] paramNames ...
               argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
                     getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
            }
            catch (UnsatisfiedDependencyException ex) {
               ...
            }
         }
         else {
            ...
         }
         int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
               argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
         if (typeDiffWeight < minTypeDiffWeight) {
            //进入到这里 基本相当于break了 已经决定好了构造 和对应的参数了  除非后续有参数个数一致的构造,那就取后面那个
            constructorToUse = candidate;
            argsHolderToUse = argsHolder;
            argsToUse = argsHolder.arguments;
            minTypeDiffWeight = typeDiffWeight;
            ambiguousConstructors = null;
         }
         ...
      }
     ....
   }
   //反射构造 创建bean
   bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
   return bw;
}

1.3 ConstructorResolver#createArgumentArray

private ArgumentsHolder createArgumentArray(
      String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,
      BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,
     .....
   for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
      Class<?> paramType = paramTypes[paramIndex];
      String paramName = (paramNames != null ? paramNames[paramIndex] : "");
      ....
      else {  
          //一般直接进入这里  记住这个类:MethodParameter ,Spring mvc handler目标方法 invoke前也是基于MethodParameter解析参数的
         MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
        ....
         try {
            //内部调用到doResolveDependency  (ObjectProvider,ObjectFactory会在调用对应方法时是才进行查找注入,这里相当于是注入了函数)
            Object autowiredArgument = resolveAutowiredArgument(
                  methodParam, beanName, autowiredBeanNames, converter, fallback);
             ...
         }
         catch (BeansException ex) {
            ...
         }
      }
   }
   ...
​
   return args;
}

1.4 DefaultListableBeanFactory#doResolveDependency

这个方法是个通用方法 大部分的依赖处理都会走到这 @Value @Autowired..

public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
            @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
​
        InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
        try {
            ...
            //提取出@Value 中的值   
            Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
            if (value != null) {
                if (value instanceof String) {
                    //基于 PropertySourcesPropertyResolver 解析 ${}占位符 返回 解析出来的值或默认值     OriginTrackedMapPropertySource解析yml中配置的变量
                    String strVal = resolveEmbeddedValue((String) value);
                    BeanDefinition bd = (beanName != null && containsBean(beanName) ?
                            getMergedBeanDefinition(beanName) : null);
                    //如果是类似 #{${}} spel表达式 还会进一步解析
                    value = evaluateBeanDefinitionString(strVal, bd);
                }
                TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
                //基于Converter进行类型转换 比如String -> Enum,Date (Date没有默认的converter,是基于Object->Object,用的是构造方法,需要的话可以自己实现,mvc的的非RequestBody的参数绑定也是基于converter转换的),List等
                return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
            }
            //复数依赖 集合类型走这里 
            Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
            if (multipleBeans != null) {
                return multipleBeans;
            }
            Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
            ..required=true matchingBeans为空抛异常..  
            String autowiredBeanName;
            Object instanceCandidate;
            if (matchingBeans.size() > 1) {
                //多个candidate  找到带有@Primary的 多个@Primary会报错 ,如果没有,就根据 找到的bean名称/别名 和形参名称对比,一致就返回
                autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
                if (autowiredBeanName == null) {
                    // required=true 或者是要单实例  那就只能抛异常了
                    if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
                        return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
                    }
                }
                instanceCandidate = matchingBeans.get(autowiredBeanName);
            }
            else {
                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) {
                //如果是class类型 就进行实例化 获得实例   注意:在构造注入时 如果注入了自己 在调用getBean时,会重新触发创建过程,在doGetBean阶段,DefaultSingletonBeanRegistry#beforeSingletonCreation 内部,bean创建之初会将beanName存入singletonsCurrentlyInCreation set中,并判断是否存放成功,如果存放失败,代表之前存在,那就是循环依赖了。 而非构造阶段注入自己,因为已经完成创建过程,bean已存在,直接返回注入自己就好了。不会进入这个if
                instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
            }
            ...
            return result;
        }
        finally {
            ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
        }
    }

1.4.1 PropertyPlaceholderHelper#parseStringValue

protected String parseStringValue(
      String value, PlaceholderResolver placeholderResolver, @Nullable Set<String> visitedPlaceholders) {
 
   //placeholderPrefix: ${
   int startIndex = value.indexOf(this.placeholderPrefix);
   if (startIndex == -1) {
      return value;
   }
   StringBuilder result = new StringBuilder(value);
   while (startIndex != -1) {
      int endIndex = findPlaceholderEndIndex(result, startIndex);
      if (endIndex != -1) {
         //去除 ${ } ,如${test.num:123}  placeholder=test.num:123
         String placeholder= = result.substring(startIndex + this.placeholderPrefix.length(), endIndex);
         String originalPlaceholder = placeholder;
         if (visitedPlaceholders == null) {
            visitedPlaceholders = new HashSet<>(4);
         }
         //防止重复解析
         if (!visitedPlaceholders.add(originalPlaceholder)) {
            throw new IllegalArgumentException(
                  "Circular placeholder reference '" + originalPlaceholder + "' in property definitions");
         }
         //递归解析 防止嵌套 正常人也不会这么干
         placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
         //按key查找 Value 实例中的key就是 test.num:123
         String propVal = placeholderResolver.resolvePlaceholder(placeholder);
         if (propVal == null && this.valueSeparator != null) {
            int separatorIndex = placeholder.indexOf(this.valueSeparator);
            if (separatorIndex != -1) {
               //找不到就将key  按:拆分  :右边的是默认值,左边的真正的key 示例是:123  真正的key是 test.num
               String actualPlaceholder = placeholder.substring(0, separatorIndex);
               String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
               //拿真正的key再找一遍
               propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
               if (propVal == null) {
                  //找不到 返回默认值
                  propVal = defaultValue;
               }
            }
         }
         if (propVal != null) {
            // 再来一次 防止默认值是 ${}
            propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
            result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
             ...
            startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length());
         }
      ...
   }
   return result.toString();
}

1.4.1.1 PropertySourcesPropertyResolver#getProperty

protected <T> T getProperty(String key, Class<T> targetValueType, boolean resolveNestedPlaceholders) {
   if (this.propertySources != null) {
      for (PropertySource<?> propertySource : this.propertySources) {
         //CompositePropertySource:ConfigPropertySource:DefaultConifg解析apollo的配置   OriginTrackedMapPropertySource解析yml的配置 
         Object value = propertySource.getProperty(key);
         if (value != null) {
            if (resolveNestedPlaceholders && value instanceof String) {
               //看是不是对应的值也是 ${...} 是的话继续解析
               value = resolveNestedPlaceholders((String) value);
            }
            logKeyFound(key, propertySource, value);
            return convertValueIfNecessary(value, targetValueType);
         }
      }
   }
   return null;
}

1.5 DefaultListableBeanFactory#resolveMultipleBeans

Class<?> type = descriptor.getDependencyType();
​
   if (descriptor instanceof StreamDependencyDescriptor) {
      ...
      return stream;
   }
   else if (type.isArray()) {
      ...
      return result;
   }
   //这里我们只关注 例子中的场景List<Interface>
   else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
      //获取接口类型
      Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
      Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
            new MultiElementDescriptor(descriptor));
      ...排序返回...
      return result;
   }
   else if (Map.class == type) {
      ...
   }
   else {
      return null;
   }
}

1.6 DefaultListableBeanFactory#findAutowireCandidates

protected Map<String, Object> findAutowireCandidates(
      @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
  //这里根据容器持有的beanDefinitionNames 遍历 如果bean已经实例化 根据实例类型进行比较 否则根据beanDefintion targetType比较,其中FactoryBean类型需要实例化调用方法进行比较
   String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
         this, requiredType, true, descriptor.isEager());
   Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
    ...
   for (String candidate : candidateNames) {
      //不是自己注入自己   如果属性上标注了@Qualifier 则必须beanName符合    ,如果属性上没有标明@Qualifier则都符合
      if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
         //如果bean被创建了 返回bean实例 否则返回对应class类型
         addCandidateEntry(result, candidate, descriptor, requiredType);
      }
   }
   if (result.isEmpty()) {
      ...
      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形式实例化ConstructorResolver#instantiateUsingFactoryMethod 和上述ConstructorResolver#autowireConstructor获取依赖方式一致,

只是筛选调用方法的形式不同,以及调用方法不同,一个是反射调用@Configuration对象的目标方法 ,一个是反射构造器。

另外一点区别就是 autowireConstructor beanDefinition的 autowireMode是 AUTOWIRE_NO ,而 instantiateUsingFactoryMethod的是 AUTOWIRE_CONSTRUCTOR

2.@Autowired

ioc处理机制篇已提过 @Autowired 是populateBean阶段 由AutowiredAnnotationBeanPostProcessor处理,

AbstractAutowireCapableBeanFactory#doCreateBean applyMergedBeanDefinitionPostProcessors方法是 预处理 @Value @Resoure @Inject @Autowired @PostContruct @PreDestroy... ,而applyMergedBeanDefinitionPostProcessors就是调用 MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition方法,我们直接看AutowiredAnnotationBeanPostProcessor的

postProcessMergedBeanDefinitionpostProcessProperties方法 。

AutowiredAnnotationBeanPostProcessor实现PriorityOrdered ,属于最高优先级BeanPostProcessor

现在new 一个 TestB

public class TestB{
    @Resource
    private List<IName> names;
​
    @Resource
    private IAddress iAddress;
​
    @Resource
    public void setName(IName nameB){
        log.info("name:{}",nameB);
    }
​
    @Autowired
    ISex iSex;
​
    @Value("${test.num:123}")
    private Integer num;
​
    private Date date;
​
    @Value("${test.date}")  //  2020/02/02
    public void testDate(Date date){
        this.date = date;
    }
​
    @Value("#{${test.strs}}")   // "1,2"
    private List<String> strs;
​
    @PostConstruct
    public void init(){
        log.info("structure:{}",this);
    }
}

2.1 postProcessMergedBeanDefinition

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
   扫描@Autowired @Value @Inject属性、方法并保存为Element
   InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
   去重
   metadata.checkConfigMembers(beanDefinition);
}

2.1.1 findAutowiringMetadata

private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
   String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
   InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
   //基本上就是判断 metadata == null  一般只要处理过就不会处理了
   if (InjectionMetadata.needsRefresh(metadata, clazz)) {
      ...
      metadata = buildAutowiringMetadata(clazz);
      ...
   }
   return metadata;
}

2.1.2 buildAutowiringMetadata

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
   List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
   Class<?> targetClass = clazz;
   do {
      final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
      //处理属性
      ReflectionUtils.doWithLocalFields(targetClass, field -> {
         //找到@Autowired @Value @Inject 注解  找到一个就返回
         MergedAnnotation<?> ann = findAutowiredAnnotation(field);
         if (ann != null) {
            ...静态属性忽略...
            //注解的required字段为true 或者没有required字段(@Inject)
            boolean required = determineRequiredStatus(ann);
            currElements.add(new AutowiredFieldElement(field, required));
         }
      });
      //处理方法
      ReflectionUtils.doWithLocalMethods(targetClass, method -> {
         //和上面处理属性一样 忽略静态方法  不同的是将方法包装成 AutowiredMethodElement
      });
      elements.addAll(0, currElements);
      //一直向上查找父类 直到Object停止
      targetClass = targetClass.getSuperclass();
   }
   while (targetClass != null && targetClass != Object.class);
   //根据elements是否为空 返回空对象
   return InjectionMetadata.forElements(elements, clazz);
}

2.2 postProcessProperties

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
   InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
 //内部就是遍历上面 解析来的  checkedElements/injectedElements 调用 InjectedElement.inject方法 从上面的解析过程看到有两种element,属性和方法
   metadata.inject(bean, beanName, pvs);
   return pvs;
}

2.2.1 AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject

protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
   Field field = (Field) this.member;
   value = resolveFieldValue(field, bean, beanName);
   ReflectionUtils.makeAccessible(field);
   field.set(bean, value);
}

2.2.1.1 resolveFieldValue

private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {
   ...
   try {
      // 里面基本调向了  doResolveDependency  
      value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
   }
   catch (BeansException ex) {
      throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
   }
   ...如果这次注入的是单实例 将拿到的值缓存起来...
   return value;
}

2.2.2 AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement#inject

protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
   if (checkPropertySkipping(pvs)) {
      return;
   }
   Method method = (Method) this.member;
   Object[] arguments;
   //后面解析也是一样的了 将每个参数包装成MethodParameter 进而调用 doResolveDependency
   arguments = resolveMethodArguments(method, bean, beanName);
   ReflectionUtils.makeAccessible(method);
   method.invoke(bean, arguments);
}

3.@Resource + @PostContruct、@PreDestroy

3.1 postProcessMergedBeanDefinition

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        //缓存带@PostConstruct  PreDestroy注解 方法
        super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
         //扫描@Resource属性 方法 并保存为 ResourceElement
        InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
        metadata.checkConfigMembers(beanDefinition);
}

3.1.1 InitDestroyAnnotationBeanPostProcessor#buildLifecycleMetadata

private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
   if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
      return this.emptyLifecycleMetadata;
   }
   //保存带有@PostContruct注解的方法 所以@PostContruct 这样的方法有多少个调多少个
   List<LifecycleElement> initMethods = new ArrayList<>();
   //保存带有@PreDestroy注解的方法
   List<LifecycleElement> destroyMethods = new ArrayList<>();
   Class<?> targetClass = clazz;
​
   do {
      final List<LifecycleElement> currInitMethods = new ArrayList<>();
      final List<LifecycleElement> currDestroyMethods = new ArrayList<>();
      ReflectionUtils.doWithLocalMethods(targetClass, method -> {
         if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
            LifecycleElement element = new LifecycleElement(method);
            currInitMethods.add(element);
         }
         if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
            currDestroyMethods.add(new LifecycleElement(method));
         }
      });
      initMethods.addAll(0, currInitMethods);
      destroyMethods.addAll(currDestroyMethods);
      targetClass = targetClass.getSuperclass();
   }
   while (targetClass != null && targetClass != Object.class);
   return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
         new LifecycleMetadata(clazz, initMethods, destroyMethods));
}

3.1.2 CommonAnnotationBeanPostProcessor#buildResourceMetadata

private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
   if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) {
      return InjectionMetadata.EMPTY;
   }
​
   List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
   Class<?> targetClass = clazz;
​
   do {
      final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
      ReflectionUtils.doWithLocalFields(targetClass, field -> {
            ...
         else if (field.isAnnotationPresent(Resource.class)) {
            if (Modifier.isStatic(field.getModifiers())) {
               //@Resource不能放在静态属性上 这里比@Autowired更严格 直接抛异常了
               throw new IllegalStateException("@Resource annotation is not supported on static fields");
            }
          ...
         }
      });
​
      ReflectionUtils.doWithLocalMethods(targetClass, method -> {
         //处理方法 和@Autowired不同的是 这里都封装成ResourceElement了 在inject方法中用if区分开了
      });
​
      elements.addAll(0, currElements);
      targetClass = targetClass.getSuperclass();
   }
   while (targetClass != null && targetClass != Object.class);
​
   return InjectionMetadata.forElements(elements, clazz);
}

3.2 InjectionMetadata.InjectedElement#inject

protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
      throws Throwable {
   if (this.isField) {
      Field field = (Field) this.member;
      ReflectionUtils.makeAccessible(field);
      //getResourceToInject 内部直接调向了 autowireResource
      field.set(target, getResourceToInject(target, requestingBeanName));
   }
   else {
       Method method = (Method) this.member;
       ReflectionUtils.makeAccessible(method);
       method.invoke(target, getResourceToInject(target, requestingBeanName));
   }
}

3.2.1 CommonAnnotationBeanPostProcessor#autowireResource

protected Object autowireResource(BeanFactory factory, LookupElement element, @Nullable String requestingBeanName)
      throws NoSuchBeanDefinitionException {
​
   Object resource;
   Set<String> autowiredBeanNames;
   String name = element.name;
​
   if (factory instanceof AutowireCapableBeanFactory) {
      AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
      DependencyDescriptor descriptor = element.getDependencyDescriptor();
      //不包含这个beanName就和@Autowired 一样 按类型查找
      if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
         autowiredBeanNames = new LinkedHashSet<>();
         resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
         if (resource == null) {
            throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
         }
      }
      else {
         //包含名称就 直接 调getBean方法了
         resource = beanFactory.resolveBeanByName(name, descriptor);
         autowiredBeanNames = Collections.singleton(name);
      }
   }
   else {
      resource = factory.getBean(name, element.lookupType);
      autowiredBeanNames = Collections.singleton(name);
   }
   ...
   return resource;
}

综上 @Autowired 和 @Resource 并不仅仅是按类型 按名称查找的简单区别,他们在查找依赖上的功能已经相差无二,不过是作用的处理器不同罢了。

@Resource可以写上随便写个beanName,他就会按类型查找。@Autowired按类型找到多个candidate,他还会再根据beanName再比对一次。

4.AUTOWIRE_BY_NAME,AUTOWIRE_BY_TYPE + AbstractBeanDefinition#propertyValues

现在我们创建一个TestC

public class TestC {
    private IAddress iAddress;
    private ISex sexA;
    private MyImportBeanDefinitionRegistrar.Dummy dummy;
}

一个 ImportBeanDefinitionRegistrar 手动帮我们注册definition

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Data
    @AllArgsConstructor
    public static class Dummy{
        private String name;
    }
​
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        BeanDefinitionBuilder builder = BeanDefinitionBuilder
                .genericBeanDefinition(TestC.class);
        builder.addPropertyValue("dummy",new Dummy("from definition"));
        builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
        registry.registerBeanDefinition(
                "testC",
                builder.getBeanDefinition());
    }
}

然后在任意一个被spring接管的类上 添加 @Import(MyImportBeanDefinitionRegistrar.class) ,然后testC就会被Spring实例化了,这里我们设置的是 AUTOWIRE_BY_NAME

然后我们在testC 的 populateBean阶段打上断点

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
   ....
   int resolvedAutowireMode = mbd.getResolvedAutowireMode();
   if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
      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;
   }
   ....
   if (pvs != null) {
       //调用set方法赋值
      applyPropertyValues(beanName, mbd, bw, pvs);
   }
}

4.1 AbstractAutowireCapableBeanFactory#autowireByName

protected void autowireByName(
      String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
   //pvs中不存在  且具备set方法的属性
   String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
   for (String propertyName : propertyNames) {
      //singletonObjects or beanDefinitionMap存在 beanName
      if (containsBean(propertyName)) {
         Object bean = getBean(propertyName);
         //收集起来 在populateBean 方法末尾统一调用
         pvs.add(propertyName, bean);
         registerDependentBean(propertyName, beanName);
 
      }
      else {
         if (logger.isTraceEnabled()) {
            logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
                  "' by name: no matching bean found");
         }
         //autowireByName 找不到对应的依赖 并不会报错 
      }
   }
}

4.2 AbstractAutowireCapableBeanFactory#autowireByType

protected void autowireByType(
      String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
  ...
   Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
   String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
   for (String propertyName : propertyNames) {
      try {
         PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
         if (Object.class != pd.getPropertyType()) {
            MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
            boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
            DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
             //同理 又调到了  doResolveDependency
            Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
            if (autowiredArgument != null) {
               pvs.add(propertyName, autowiredArgument);
            }
            autowiredBeanNames.clear();
         }
      }
      catch (BeansException ex) {
          //可以看到 autowireByType 比 autowireByName 更严格
         throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
      }
   }
}

以上 就是Spring 注入bean及查找依赖的几种方式,还有一种FactoryBean。注意 ,基于FactoryBean创建的bean没有populateBean阶段,只会调用BeanPostProcessor.postProcessAfterInitialization,让其有代理化的可能。