依赖注入

1.源码入口

AbstractAutowireCapableBeanFactory#doCreateBean

        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    //后处理器调用点:合并bd信息,因为接下来就是populate处理依赖了..
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }

        ...

        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            //处理当前实例的依赖数据...依赖注入在这一步完成的。
            populateBean(beanName, mbd, instanceWrapper);
            //生命周期中的初始化方法的调用。
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }

2.applyMergedBeanDefinitionPostProcessors

    protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class beanType, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof MergedBeanDefinitionPostProcessor) {
                //AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition
                //做了一件事:提取出来当前beanType类型整个继承体系内的 @Autowired @Value @Inject 信息 并且包装成一个InjectionMetadata的一个
                //对象,存放到 AutowiredAnnotationBeanPostProcessor 它的缓存中了,key是 beanName。
                MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
                bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
            }
        }
    }

重点看看AutowiredAnnotationBeanPostProcessor,核心逻辑就是

  • 找到所有的注入点,其实就是被@Autowired注解修饰的方法以及字段,同时静态的方法以及字段也会被排除
  • 排除掉被外部管理的注入点
    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) {
        // 找到注入的元数据,第一次是构建,后续可以直接从缓存中拿
        // 注解元数据其实就是当前这个类中的所有需要进行注入的“点”的集合,
        // 注入点(InjectedElement)包含两种,字段/方法
        // 对应的就是AutowiredFieldElement/AutowiredMethodElement
        InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
        // 排除掉被外部管理的注入点
        metadata.checkConfigMembers(beanDefinition);
    }
    private InjectionMetadata findAutowiringMetadata(String beanName, Class clazz, @Nullable PropertyValues pvs) {
        // Fall back to class name as cache key, for backwards compatibility with custom callers.
        String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
        // Quick check on the concurrent map first, with minimal locking.
        InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
        // 可能我们会修改bd中的class属性,那么InjectionMetadata中的注入点信息也需要刷新
        if (InjectionMetadata.needsRefresh(metadata, clazz)) {
            synchronized (this.injectionMetadataCache) {
                metadata = this.injectionMetadataCache.get(cacheKey);
                if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                    if (metadata != null) {
                        metadata.clear(pvs);
                    }
                    // 获取当前clazz关注的@Autowired @Value @Inject注解信息
                    metadata = buildAutowiringMetadata(clazz);
                    this.injectionMetadataCache.put(cacheKey, metadata);
                }
            }
        }
        return metadata;
    }

重点是buildAutowiringMetadata():

    // 我们应用中使用@Autowired注解标注在字段上或者setter方法能够完成属性注入
    // 就是因为这个方法将@Autowired注解标注的方法以及字段封装成InjectionMetadata
    // 在后续阶段会调用InjectionMetadata的inject方法进行注入
    private InjectionMetadata buildAutowiringMetadata(final Class clazz) {
        if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
            return InjectionMetadata.EMPTY;
        }

        List elements = new ArrayList<>();
        Class targetClass = clazz;

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

            // 处理所有的被@AutoWired/@Value注解标注的字段
            ReflectionUtils.doWithLocalFields(targetClass, field -> {
                MergedAnnotation ann = findAutowiredAnnotation(field);
                if (ann != null) {
                    // 静态字段会直接跳过
                    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);
                    currElements.add(new AutowiredFieldElement(field, required));
                }
            });

            // 处理所有的被@AutoWired注解标注的方法,相对于字段而言,这里需要对桥接方法进行特殊处理
            ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
                // 只处理一种特殊的桥接场景,其余的桥接方法都会被忽略
                if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                    return;
                }
                MergedAnnotation ann = findAutowiredAnnotation(bridgedMethod);
                // 处理方法时需要注意,当父类中的方法被子类重写时,如果子父类中的方法都加了@Autowired
                // 那么此时父类方法不能被处理,即不能被封装成一个AutowiredMethodElement
                if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                    if (Modifier.isStatic(method.getModifiers())) {
                        if (logger.isInfoEnabled()) {
                            logger.info("Autowired annotation is not supported on static methods: " + method);
                        }
                        return;
                    }
                    // 当方法的参数数量为0时,虽然不需要进行注入,但是还是会把这个方法作为注入点使用
                    // 这个方法最终还是会被调用
                    if (method.getParameterCount() == 0) {
                        if (logger.isInfoEnabled()) {
                            logger.info("Autowired annotation should only be used on methods with parameters: " +
                                    method);
                        }
                    }
                    boolean required = determineRequiredStatus(ann);
                    // PropertyDescriptor: 属性描述符
                    // 就是通过解析getter/setter方法,例如void getA()会解析得到一个属性名称为a
                    // readMethod为getA的PropertyDescriptor,
                    // 这里之所以来这么一次查找是因为当XML中对这个属性进行了配置后,
                    // 那么就不会进行自动注入了,XML中显示指定的属性优先级高于注解
                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                    // 方法的参数会被自动注入,这里不限于setter方法
                    currElements.add(new AutowiredMethodElement(method, required, pd));
                }
            });

            // 会处理父类中字段上及方法上的@AutoWired注解,并且父类的优先级比子类高
            elements.addAll(0, currElements);
            targetClass = targetClass.getSuperclass();
        }
        while (targetClass != null && targetClass != Object.class);

        return InjectionMetadata.forElements(elements, clazz);
    }

2.1 桥接方法

桥接方法的三种情况:

  • 1)子类对父类的方法进行了重写,并且子类方法中的返回值类型跟父类方法的返回值类型不一样。子类生成了一个方法描述符与父类一致的方法,然后又调用子类重写的逻辑。
  • 2)子类重写了父类中带有泛型的方法
  • 3)父类跟子类在同一个包下,父类不是public的,子类会生成一个跟A中的方法描述符(参数+返回值)一模一样的桥接方法,这个桥接方法实际上就是调用父类中的方法
// 第一行
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);

// 第二行
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
    return;
}

// 第三行
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {

}
public static boolean isVisibilityBridgeMethodPair(Method bridgeMethod, Method bridgedMethod) {
    // 说明这个方法本身就不是桥接方法,直接返回true
    if (bridgeMethod == bridgedMethod) {
        return true;
    }
    // 说明是桥接方法,并且方法描述符一致
    // 当且仅当是上面例子中描述的这种桥接的时候这个判断才会满足
    // 正常来说桥接方法跟被桥接方法的返回值+参数类型肯定不一致
    // 所以这个判断会过滤掉其余的所有类型的桥接方法
    // 只会保留第3)情况下产生的桥接方法
    return (bridgeMethod.getReturnType().equals(bridgedMethod.getReturnType()) &&
            Arrays.equals(bridgeMethod.getParameterTypes(), bridgedMethod.getParameterTypes()));
}

3.依赖注入核心流程populateBean()

核心流程分为三个部分:

  • 处理自动注入
  • 处理属性注入(主要指处理@Autowired注解),最重要
  • 处理依赖检查
    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        // 处理空实例
        if (bw == null) {
            if (mbd.hasPropertyValues()) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            }
            else {
                // Skip property population phase for null instance.
                return;
            }
        }

        // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
        // state of the bean before properties are set. This can be used, for example,
        // to support styles of field injection.
        // 满足两个条件,不是合成类 && 存在InstantiationAwareBeanPostProcessor
        // 其中InstantiationAwareBeanPostProcessor主要作用就是作为Bean的实例化前后的钩子
        // 外加完成属性注入,对于三个方法就是
        // postProcessBeforeInstantiation  创建对象前调用
        // postProcessAfterInstantiation   对象创建完成,@AutoWired注解解析后调用
        // postProcessPropertyValues(已过期,被postProcessProperties替代) 进行属性注入
        // 下面这段代码的主要作用就是我们可以提供一个InstantiationAwareBeanPostProcessor
        // 提供的这个后置处理如果实现了postProcessAfterInstantiation方法并且返回false
        // 那么可以跳过Spring默认的属性注入,但是这也意味着我们要自己去实现属性注入的逻辑
        // 所以一般情况下,我们也不会这么去扩展
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            //后处理器调用点:AfterInstantiation  实例化之后的后处理器调用。
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    //postProcessAfterInstantiation 返回值将决定当前实例是否需要再进行 依赖注入处理。
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        return;
                    }
                }
            }
        }

        //
        //
        //
        // 这里其实就是判断XML是否提供了属性相关配置
        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

        // 确认注入模型
        int resolvedAutowireMode = mbd.getResolvedAutowireMode();
        // 主要处理byName跟byType两种注入模型,byConstructor这种注入模型在创建对象的时候已经处理过了
        // 这里都是对自动注入进行处理,byName跟byType两种注入模型均是依赖setter方法
        // byName,根据setter方法的名字来查找对应的依赖,例如setA,那么就是去容器中查找名字为a的Bean
        // byType,根据setter方法的参数类型来查找对应的依赖,例如setXx(A a),就是去容器中查询类型为A的bean
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
            // Add property values based on autowire by name if applicable.
            if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
                //byName 应该怎么处理呢?
                //根据字段名称 去 查找依赖bean 然后完成注入
                autowireByName(beanName, mbd, bw, newPvs);
            }
            // Add property values based on autowire by type if applicable.
            if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }
            //newPvs 相当于处理了 依赖数据后的 pvs。
            pvs = newPvs;
        }

        //表示 当前是否拥有InstantiationAware系列的后处理器 需要调用。
        // 这个后置处理器就是来完成属性注入的
        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        //  是否需要依赖检查,默认是不会进行依赖检查的
        boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

        PropertyDescriptor[] filteredPds = null;
        if (hasInstAwareBpps) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    //后处理器调用点:调用InstantiationAwareBeanPostProcessor postProcessProperties
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    //典型的应用:@Autowired 注解的注入!
                    PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        if (filteredPds == null) {
                            // 得到需要进行依赖检查的属性的集合
                            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                        }
                        //  这个方法已经过时了,放到这里就是为了兼容老版本
                        pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvsToUse == null) {
                            return;
                        }
                    }
                    pvs = pvsToUse;
                }
            }
        }
        // 需要进行依赖检查
        if (needsDepCheck) {
            if (filteredPds == null) {
                // 得到需要进行依赖检查的属性的集合
                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }
            // 对需要进行依赖检查的属性进行依赖检查
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }

        if (pvs != null) {
            //将依赖注入合并后的pvs 应用到 真实的Bean实例中。
            //到这一步解析出来的属性主要有三个来源
           // 1)XML中配置的
           // 2)通过byName的方式自动注入的
           // 3)通过byType的方式自动注入的
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }

3.1 自动注入autowireByName和autowireByType

autowireByName直接通过beanName调用getBean。

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

        // 得到符合下面条件的属性名称
        // 1.有setter方法
        // 2.需要进行依赖检查
        // 3.不包含在XML配置中
        // 4.不是简单类型(基本数据类型,枚举,日期等)
        // 这里可以看到XML配置优先级高于自动注入的优先级
        // 不进行依赖检查的属性,也不会进行属性注入
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
        //遍历并且完成依赖注入..
        for (String propertyName : propertyNames) {
            //条件成立:说明beanFactory中存在当前propertyName的bean实例。说明找到对应的依赖数据了
            if (containsBean(propertyName)) {
                //拿到 propertyName 的 bean实例。
                Object bean = getBean(propertyName);
                //追加一个property。将自动注入的属性添加到pvs中去
                pvs.add(propertyName, bean);
                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:

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

        // 这个类型转换器,主要是在处理@Value时需要使用
        TypeConverter converter = getCustomTypeConverter();
        if (converter == null) {
            converter = bw;
        }

        Set autowiredBeanNames = new LinkedHashSet<>(4);
        // 得到符合下面条件的属性名称
        // 1.有setter方法
        // 2.需要进行依赖检查
        // 3.不包含在XML配置中
        // 4.不是简单类型(基本数据类型,枚举,日期等)
        // 这里可以看到XML配置优先级高于自动注入的优先级
        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 != pd.getPropertyType()) {
                    // 这里获取到的就是setter方法的参数,因为我们需要按照类型进行注入嘛
                    MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
                    // Do not allow eager init for type matching in case of a prioritized post-processor.
                    // 如果是PriorityOrdered在进行类型匹配时不会去匹配factoryBean
                    // 如果不是PriorityOrdered,那么在查找对应类型的依赖的时候会会去匹factoryBean
                    // 这就是Spring的一种设计理念,实现了PriorityOrdered接口的Bean被认为是一种
                    // 最高优先级的Bean,这一类的Bean在进行为了完成装配而去检查类型时,
                    // 不去检查factoryBean
                    // 具体可以参考PriorityOrdered接口上的注释文档
                    boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
                    // 将参数封装成为一个依赖描述符
                    // 依赖描述符会通过:依赖所在的类,字段名/方法名,依赖的具体类型等来描述这个依赖
                    DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
                    // 解析依赖,这里会处理@Value注解
                    // 另外,通过指定的类型到容器中查找对应的bean
                    Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
                    if (autowiredArgument != null) {
                        // 将查找出来的依赖属性添加到pvs中,后面会将这个pvs应用到bean上
                        pvs.add(propertyName, autowiredArgument);
                    }
                    // 注册bean直接的依赖关系
                    for (String autowiredBeanName : autowiredBeanNames) {
                        registerDependentBean(autowiredBeanName, beanName);
                        if (logger.isTraceEnabled()) {
                            logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
                                    propertyName + "' to bean named '" + autowiredBeanName + "'");
                        }
                    }
                    autowiredBeanNames.clear();
                }
            }
            catch (BeansException ex) {
                throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
            }
        }
    }

resolveDependency解析依赖分为五种情况:

  • 1) Optional
  • 2)ObjectFactory、ObjectProvider
  • 3)javax.inject.Provider
  • 4)@Lazy
  • 5)正常情况:doResolveDependency()
    public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
            @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

        // descriptor代表当前需要注入的那个字段,或者方法的参数,也就是注入点
        // ParameterNameDiscovery用于解析方法参数名称
        descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
        // 1. Optional
        if (Optional.class == descriptor.getDependencyType()) {
            return createOptionalDependency(descriptor, requestingBeanName);
        }
        // 2. ObjectFactory、ObjectProvider
        else if (ObjectFactory.class == descriptor.getDependencyType() ||
                ObjectProvider.class == descriptor.getDependencyType()) {
            return new DependencyObjectProvider(descriptor, requestingBeanName);
        }
        // 3. javax.inject.Provider
        else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
            return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
        }
        else {
            // 4. @Lazy
            Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
                    descriptor, requestingBeanName);
            if (result == null) {
                // 5. 正常情况
                result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
            }
            return result;
        }
    }

正常情况下,doResolveDependency()的处理,先类型后名称:

  • 通过依赖类型查询到所有的类型匹配的bean的名称
  • 如果找到了多个的话,再根据依赖的名称匹配对应的Bean的名称
  • 调用getBean得到这个需要被注入的Bean
  • 最后反射调用字段的set方法完成属性注入
    public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
            @Nullable Set 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注解,这里得到的时候@Value中的值
            Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
            if (value != null) {
                if (value instanceof String) {
                    // 解析@Value中的占位符
                    String strVal = resolveEmbeddedValue((String) value);
                    // 获取到对应的bd
                    BeanDefinition bd = (beanName != null && containsBean(beanName) ?
                            getMergedBeanDefinition(beanName) : null);
                    // 处理EL表达式
                    value = evaluateBeanDefinitionString(strVal, bd);
                }
                // 通过解析el表达式可能还需要进行类型转换
                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()));
                }
            }

            // 对map,collection,数组类型的依赖进行处理
            // 最终会根据集合中的元素类型,调用findAutowireCandidates方法
            Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
            if (multipleBeans != null) {
                return multipleBeans;
            }

            // 根据指定类型可能会找到多个bean
            // 这里返回的既有可能是对象,也有可能是对象的类型
            // 这是因为到这里还不能明确的确定当前bean到底依赖的是哪一个bean
            // 所以如果只会返回这个依赖的类型以及对应名称,最后还需要调用getBean(beanName)
            // 去创建这个Bean
            Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
            // 一个都没找到并且必须要注入,则抛出异常。否则返回null。
            if (matchingBeans.isEmpty()) {
                if (isRequired(descriptor)) {
                    raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
                }
                return null;
            }

            String autowiredBeanName;
            Object instanceCandidate;

            // 通过类型找到了多个
            if (matchingBeans.size() > 1) {
                // 根据是否是主Bean
                // 是否是最高优先级的Bean
                // 是否是名称匹配的Bean
                // 来确定具体的需要注入的Bean的名称
                // 到这里可以知道,Spring在查找依赖的时候遵循
                // 先类型再名称的原则(没有@Qualifier注解情况下)
                autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
                if (autowiredBeanName == null) {
                    // 无法推断出具体的名称
                    // 如果依赖是必须的,直接抛出异常
                    // 如果依赖不是必须的,但是这个依赖类型不是集合或者数组,那么也抛出异常
                    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).
                        // 依赖不是必须的,但是依赖类型是集合或者数组,那么返回一个null
                        return null;
                    }
                }
                instanceCandidate = matchingBeans.get(autowiredBeanName);
            }
            else {
                // 直接找到了一个对应的Bean
                // We have exactly one match.
                Map.Entry entry = matchingBeans.entrySet().iterator().next();
                autowiredBeanName = entry.getKey();
                instanceCandidate = entry.getValue();
            }

            if (autowiredBeanNames != null) {
                autowiredBeanNames.add(autowiredBeanName);
            }
            // 前面已经说过了,这里可能返回的是Bean的类型,所以需要进一步调用getBean
            if (instanceCandidate instanceof Class) {
                instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
            }
            // 做一些检查,如果依赖是必须的,查找出来的依赖是一个null,那么报错
            // 查询处理的依赖类型不符合,也报错
            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:

    protected Map findAutowireCandidates(
            @Nullable String beanName, Class requiredType, DependencyDescriptor descriptor) {

        // 简单来说,这里就是到容器中查询requiredType类型的所有bean的名称的集合
        // 这里会根据descriptor.isEager()来决定是否要匹配factoryBean类型的Bean
        // 如果isEager()为true,那么会匹配factoryBean,反之,不会
        String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                this, requiredType, true, descriptor.isEager());
        Map result = new LinkedHashMap<>(candidateNames.length);

        // 第一步会到resolvableDependencies这个集合中查询是否已经存在了解析好的依赖
        // 像我们之所以能够直接在Bean中注入applicationContext对象
        // 就是因为Spring之前就将这个对象放入了resolvableDependencies集合中
        for (Map.Entry, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
            Class autowiringType = classObjectEntry.getKey();
            if (autowiringType.isAssignableFrom(requiredType)) {
                Object autowiringValue = classObjectEntry.getValue();
                // 如果resolvableDependencies放入的是一个ObjectFactory类型的依赖
                // 那么在这里会生成一个代理对象
                // 例如,我们可以在controller中直接注入request对象
                // 就是因为,容器启动时就在resolvableDependencies放入了一个键值对
                // 其中key为:Request.class,value为:ObjectFactory
                // 在实际注入时放入的是一个代理对象
                autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
                if (requiredType.isInstance(autowiringValue)) {
                    // 这里放入的key不是Bean的名称
                    // value是实际依赖的对象
                    result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
                    break;
                }
            }
        }
        // 接下来开始对之前查找出来的类型匹配的所有BeanName进行处理
        for (String candidate : candidateNames) {
            // 不是自引用,什么是自引用?
            // 1.候选的Bean的名称跟需要进行注入的Bean名称相同,意味着,自己注入自己
            // 2.或者候选的Bean对应的factoryBean的名称跟需要注入的Bean名称相同,
            // 也就是说A依赖了B但是B的创建又需要依赖A
            // 要符合注入的条件
            if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
                // 调用addCandidateEntry,加入到返回集合中
                addCandidateEntry(result, candidate, descriptor, requiredType);
            }
        }
        // 排除自引用的情况下,没有找到一个合适的依赖
        if (result.isEmpty()) {
            boolean multiple = indicatesMultipleBeans(requiredType);
            // Consider fallback matches if the first pass failed to find anything...
            // 1.先走fallback逻辑,Spring提供的一个扩展吧,感觉没什么卵用
            // 默认情况下fallback的依赖描述符就是自身
            DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
            for (String candidate : candidateNames) {
                if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
                        (!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
                    addCandidateEntry(result, candidate, descriptor, requiredType);
                }
            }
            // fallback还是失败
            if (result.isEmpty() && !multiple) {
                // Consider self references as a final pass...
                // but in the case of a dependency collection, not the very same bean itself.
                // 处理自引用
                // 从这里可以看出,自引用的优先级是很低的,只有在容器中真正的只有这个Bean能作为
                // 候选者的时候,才会去处理,否则自引用是被排除掉的
                for (String candidate : candidateNames) {
                    if (isSelfReference(beanName, candidate) &&
                            (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
                            isAutowireCandidate(candidate, fallbackDescriptor)) {
                        addCandidateEntry(result, candidate, descriptor, requiredType);
                    }
                }
            }
        }
        return result;
    }
    /**
     * Add an entry to the candidate map: a bean instance if available or just the resolved
     * type, preventing early bean initialization ahead of primary candidate selection.
     * // candidates:就是findAutowireCandidates方法要返回的候选集合
     * // candidateName:当前的这个候选Bean的名称
     * // descriptor:依赖描述符
     * // requiredType:依赖的类型
     */
    private void addCandidateEntry(Map candidates, String candidateName,
            DependencyDescriptor descriptor, Class requiredType) {

        // 如果依赖是一个集合,或者容器中已经包含这个单例了
        // 那么直接调用getBean方法创建或者获取这个Bean
        if (descriptor instanceof MultiElementDescriptor) {
            Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
            if (!(beanInstance instanceof NullBean)) {
                candidates.put(candidateName, beanInstance);
            }
        }
        else if (containsSingleton(candidateName) || (descriptor instanceof StreamDependencyDescriptor &&
                ((StreamDependencyDescriptor) descriptor).isOrdered())) {
            Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
            candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance));
        }
        else {
            // 如果依赖的类型不是一个集合,这个时候还不能确定到底要使用哪个依赖,
            // 所以不能将这些Bean创建出来,所以这个时候,放入candidates是Bean的名称以及类型
            candidates.put(candidateName, getType(candidateName));
        }
    }

3.2 属性注入@Autowired

AutowiredAnnotationBeanPostProcessor#postProcessProperties

    // 在applyMergedBeanDefinitionPostProcessors方法执行的时候,
    // 已经解析过了@Autowired注解(buildAutowiringMetadata方法)
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        // 这里获取到的是解析过的缓存好的注入元数据
        InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
        try {
            // 直接调用inject方法
            // 存在两种InjectionMetadata
            // 1.AutowiredFieldElement
            // 2.AutowiredMethodElement
            // 分别对应字段的属性注入以及方法的属性注入
            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;
    }

AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject

        @Override
        protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
            Field field = (Field) this.member;
            Object value;
            if (this.cached) {
                // 第一次注入的时候肯定没有缓存
                // 这里也是对原型情况的处理
                value = resolvedCachedArgument(beanName, this.cachedFieldValue);
            }
            else {
                DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
                desc.setContainingClass(bean.getClass());
                Set autowiredBeanNames = new LinkedHashSet<>(1);
                Assert.state(beanFactory != null, "No BeanFactory available");
                TypeConverter typeConverter = beanFactory.getTypeConverter();
                try {
                    // 这里可以看到,对@Autowired注解在字段上的处理
                    // 跟byType下自动注入的处理是一样的,就是调用resolveDependency方法
                    value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
                }
                catch (BeansException ex) {
                    throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
                }
                synchronized (this) {
                    // 没有缓存过的话,这里需要进行缓存
                    if (!this.cached) {
                        if (value != null || this.required) {
                            this.cachedFieldValue = desc;
                            // 注册Bean之间的依赖关系
                            registerDependentBeans(beanName, autowiredBeanNames);
                            // 如果这个类型的依赖只存在一个的话,我们就能确定这个Bean的名称
                            // 那么直接将这个名称缓存到ShortcutDependencyDescriptor中
                            // 第二次进行注入的时候就可以直接调用getBean(beanName)得到这个依赖了
                            // 实际上正常也只有一个,多个就报错了
                            // 另外这里会过滤掉@Vlaue得到的依赖
                            if (autowiredBeanNames.size() == 1) {
                                String autowiredBeanName = autowiredBeanNames.iterator().next();
                                // 通过resolvableDependencies这个集合找的依赖不满足containsBean条件
                                // 不会进行缓存,因为缓存实际还是要调用getBean,而resolvableDependencies
                                // 是没法通过getBean获取的
                                if (beanFactory.containsBean(autowiredBeanName) &&
                                        beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
                                    this.cachedFieldValue = new ShortcutDependencyDescriptor(
                                            desc, autowiredBeanName, field.getType());
                                }
                            }
                        }
                        else {
                            this.cachedFieldValue = null;
                        }
                        this.cached = true;
                    }
                }
            }
            if (value != null) {
                // 反射调用Field.set方法
                ReflectionUtils.makeAccessible(field);
                field.set(bean, value);
            }
        }
    }

AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement#inject

        protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
            // 判断XML中是否配置了这个属性,如果配置了直接跳过
            // 换而言之,XML配置的属性优先级高于@Autowired注解
            if (checkPropertySkipping(pvs)) {
                return;
            }
            Method method = (Method) this.member;
            Object[] arguments;
            if (this.cached) {
                // Shortcut for avoiding synchronization...
                arguments = resolveCachedArguments(beanName);
            }
            else {
                // 通过方法参数类型构造依赖描述符
                // 逻辑基本一样的,最终也是调用beanFactory.resolveDependency方法
                int argumentCount = method.getParameterCount();
                arguments = new Object[argumentCount];
                DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
                Set autowiredBeans = new LinkedHashSet<>(argumentCount);
                Assert.state(beanFactory != null, "No BeanFactory available");
                TypeConverter typeConverter = beanFactory.getTypeConverter();
                for (int i = 0; i < arguments.length; i++) {
                    MethodParameter methodParam = new MethodParameter(method, i);
                    DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
                    currDesc.setContainingClass(bean.getClass());
                    descriptors[i] = currDesc;
                    try {
                        // 还是要调用这个方法
                        Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
                        if (arg == null && !this.required) {
                            arguments = null;
                            break;
                        }
                        arguments[i] = arg;
                    }
                    catch (BeansException ex) {
                        throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
                    }
                }
                synchronized (this) {
                    if (!this.cached) {
                        if (arguments != null) {
                            DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);
                            registerDependentBeans(beanName, autowiredBeans);
                            // 跟字段注入差不多,存在@Value注解,不进行缓存
                            if (autowiredBeans.size() == argumentCount) {
                                Iterator it = autowiredBeans.iterator();
                                Class[] paramTypes = method.getParameterTypes();
                                for (int i = 0; i < paramTypes.length; i++) {
                                    String autowiredBeanName = it.next();
                                    if (beanFactory.containsBean(autowiredBeanName) &&
                                            beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
                                        cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
                                                descriptors[i], autowiredBeanName, paramTypes[i]);
                                    }
                                }
                            }
                            this.cachedMethodArguments = cachedMethodArguments;
                        }
                        else {
                            this.cachedMethodArguments = null;
                        }
                        this.cached = true;
                    }
                }
            }
            if (arguments != null) {
                try {
                    // 反射调用方法
                    // 像我们的setter方法就是在这里调用的
                    ReflectionUtils.makeAccessible(method);
                    method.invoke(bean, arguments);
                }
                catch (InvocationTargetException ex) {
                    throw ex.getTargetException();
                }
            }
        }

3.3 依赖检查

AbstractAutowireCapableBeanFactory#checkDependencies

    protected void checkDependencies(
            String beanName, AbstractBeanDefinition mbd, PropertyDescriptor[] pds, @Nullable PropertyValues pvs)
            throws UnsatisfiedDependencyException {

        int dependencyCheck = mbd.getDependencyCheck();
        for (PropertyDescriptor pd : pds) {
            // 有set方法但是在pvs中没有对应属性,那么需要判断这个属性是否要进行依赖检查
            // 如果需要进行依赖检查的话,就需要报错了
            // pvs中保存的是自动注入以及XML配置的属性
            if (pd.getWriteMethod() != null && (pvs == null || !pvs.contains(pd.getName()))) {
                // 是否是基本属性,枚举/日期等也包括在内
                boolean isSimple = BeanUtils.isSimpleProperty(pd.getPropertyType());
                // 如果DEPENDENCY_CHECK_ALL,对任意属性都开启了依赖检查,报错
                // DEPENDENCY_CHECK_SIMPLE,对基本属性开启了依赖检查并且是基本属性,报错
                // DEPENDENCY_CHECK_OBJECTS,对非基本属性开启了依赖检查并且是非基本属性,报错
                boolean unsatisfied = (dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_ALL) ||
                        (isSimple && dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_SIMPLE) ||
                        (!isSimple && dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_OBJECTS);
                if (unsatisfied) {
                    throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, pd.getName(),
                            "Set this property value or disable dependency checking for this bean.");
                }
            }
        }
    }

你可能感兴趣的:(依赖注入)