spring依赖注入

fxz大约 68 分钟

spring依赖注入

@Autowired、@Resource、@Value

@Resource、@Autowired、@Value 标注字段、方法,则表示需要依赖注入(就是反射给字段设置值、反射执行方法)

在依赖注入的前提上:

  • 使用@Lazy则表示注入的是代理对象,执行代理对象时才会真正进行依赖的解析
  • 使用@Qualifier("beanName"),匹配了多个注入的值时,遍历每个候选者,找到限定beanName一致的候选者
  • 使用@Primary,匹配了多个注入的值时,有@Primary的候选者作为最终的注入值
  • 使用@Priority,匹配了多个注入的值时,然后没有@Primary的候选者,才会根据@Priority的排序值,找到至最小的作为最终的注入值

注:匹配了多个注入的值时,没有@Qualifier、@Primary、@Primary限定,那就根据字段的名字、或者方法的参数名作为限定名匹配候选者

// 准备一个带泛型的Bean
@Getter
@Setter
@NoArgsConstructor  
@AllArgsConstructor
@ToString
public class GenericBean<T, W> {

    private T t;
    private W w;

}

	// config配置文件中注入两个泛型Bean
    @Bean
    public Parent parentOne() {
        return new Parent();
    }
    @Bean
    public Parent parentTwo() {
        return new Parent();
    }
    @Bean
    public GenericBean<String, String> stringGeneric() {
        return new GenericBean<String, String>("str1", "str2");
    }
    @Bean
    public GenericBean<Object, Object> objectGeneric() {
        return new GenericBean<Object, Object>("obj1", 2);
    }

	// 使用@Autowired注入,测试一下:
    @Autowired
    private GenericBean<Object, Object> objectGenericBean; //GenericBean(t=obj1, w=2)
    @Autowired
    private GenericBean<String, String> stringGenericBean; //GenericBean(t=st   r1, w=str2)
    // 注意,容器里虽然有两个Parent,这里即使不使用@Qualifier也不会报错。
    // 但是需要注意字段名parentOne,必须是容器里存在的,否则就报错了。
    @Autowired
    private Parent parentOne; //com.fsx.bean.Parent@23c98163

    //Spring4.0后的新特性,这样会注入所有类型为(包括子类)GenericBean的Bean(但是顺序是不确定的,可通过Order接口控制顺序)
    @Autowired
    private List<GenericBean> genericBeans; //[GenericBean(t=st   r1, w=str2), GenericBean(t=obj1, w=2)]
    // 这里的key必须是String类型,把GenericBean类型的都拿出来了,beanName->Bean
    @Autowired
    private Map<String, GenericBean> genericBeanMap; //{stringGenericBean=GenericBean(t=st   r1, w=str2), objectGenericBean=GenericBean(t=obj1, w=2)}
    // 这里面,用上泛型也是好使的,就只会拿指定泛型的了
    @Autowired
    private Map<String, GenericBean<Object, Object>> genericBeanObjMap; //{objectGenericBean=GenericBean(t=obj1, w=2)}

    // 普通类型,容器里面没有的Bean类型,注入是会报错的
    //@Autowired
    //private Integer normerValue;

循环依赖

/**
 * 只有单例bean支持循环依赖,原型和Scope是不支持循环依赖的
 * 看
 * { AbstractBeanFactory的doGetBean(String, Clazz, Object[], boolean)}
 * */

/**
 * 循环依赖bean校验逻辑
 * 看 { AbstractAutowireCapableBeanFactory的doCreateBean(String, RootBeanDefinition, Object[])}
 *
 * 这里是为了处理二级缓存中的bean 和 执行了初始化操作的 bean 不一致的校验,不一致说明可能存在
 * 依赖注入的bean 和 实际存入单例池中的bean 不一致的问题。对于不一致,下面的处理是报错
 *
 *
 * 比如 A 注入了 B,B 注入了 A
 * 先是 getBean(A),然后其 populateBean 环节要注入B, 所以会 getBean(B),然后其 populateBean 环节要注入A,所以要 getBean(A)
 * 此时发现A正在创建,所以会读取三级缓存的value,然后执行提前AOP得到一个 proxyBeanA ,并将 proxyBeanA 存入二级缓存,然后将 proxyBeanA 注入到 B中,
 * 然后B就创建完了,然后B就会被注入到A中,所以A的 populateBean 结束了,然后会执行 initializeBean。假设在 initializeBean 生成了 proxyBeanA2 。
 * 这就出现了 注入到B中的A,和实际最终生成的A不一致的问题,对于这中情况,只能直接报错了,下面的逻辑就是为了应付这种情况的,
 *
 * 注:当然 提前AOP 也不一定会创建代理对象,我这里只是举例了 提前AOP和初始化都创建了代理对象的场景,方便说明
 * */


protected Object doCreateBean(String beanName, RootBeanDefinition mbd,
                                  @Nullable Object[] args) throws BeanCreationException {

        // 实例化bean
        bean = createBeanInstance(beanName, mbd, args);

        if (earlySingletonExposure) {
            /**
             * 循环依赖-添加到三级缓存中
             * 把我们的早期对象包装成一个 singletonFactory 对象,该对象提供了一个 getObject方法,该方法内部调用 getEarlyBeanReference(beanName, mbd, bean)
             * 实现提前AOP
             * */
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        // Initialize the bean instance.
        Object exposedObject = bean;
        // 填充bean,就是依赖注入或者给属性设置值
        populateBean(beanName, mbd, instanceWrapper); // getBean()
        // 进行对象初始化操作(在这里可能生成代理对象)
        exposedObject = initializeBean(beanName, exposedObject, mbd);

        /**
         * 这里是为了处理二级缓存中的bean 和 执行了初始化操作的 bean 不一致的校验,不一致说明可能存在
         * 依赖注入的bean 和 实际存入单例池中的bean 不一致的问题。对于不一致,下面的处理是报错
         *
         *
         * 比如 A 注入了 B,B 注入了 A
         * 先是 getBean(A),然后其 populateBean 环节要注入B, 所以会 getBean(B),然后其 populateBean 环节要注入A,所以要 getBean(A)
         * 此时发现A正在创建,所以会读取三级缓存的value,然后执行提前AOP得到一个 proxyBeanA ,并将 proxyBeanA 存入二级缓存,然后将 proxyBeanA 注入到 B中,
         * 然后B就创建完了,然后B就会被注入到A中,所以A的 populateBean 结束了,然后会执行 initializeBean。假设在 initializeBean 生成了 proxyBeanA2 。
         * 这就出现了 注入到B中的A,和实际最终生成的A不一致的问题,对于这中情况,只能直接报错了,下面的逻辑就是为了应付这种情况的,
         *
         * 注:当然 提前AOP 也不一定会创建代理对象,我这里只是举例了 提前AOP和初始化都创建了代理对象的场景,方便说明
         *
         * */
        if (earlySingletonExposure) {
            /**
             * 去缓存中获取到我们的对象,由于传递的 allowEarlyReference 是false要求只能在一级二级缓存中去获取。
             * 说白了,就尝试从二级缓存中获取bean。
             *
             * 注:在这里就能体会到三级缓存的好处了。因为这里是只会从一级缓存和二级缓存中获取内容(其实只可能从二级缓存中拿到,一级缓存是拿不到的,因为此时还未将单例bean存入一级缓存)
             *     如果二级缓存拿到的值不为null,就校验一下 exposedObject(执行了初始化后置处理器返回的值) 和 bean(简单实例化出来的) 是否一致,
             *     若不一致,就需要判断一下,这个bean是否注入给了其他bean对象,若注入给了其他bean对象,那么就只能报错了,因为已经注入给了其他bean的值 和 exposedObject 不一致。
             *
             *     假设我们采用二级缓存来解决循环依赖的问题。思路如下:
             *          一级缓存用来缓存最终完全的bean,二级缓存一开始存入的是 ObjectFactory ,当出现了循环依赖时,读取二级缓存的值,然后回调方法 ObjectFactory的getObject 得到 提前AOP的bean。
             *          将 提前AOP的bean 存入进二级缓存,也就是进行值覆盖。
             *
             *          一级缓存:< beanName,最终的bean >
             *          二级缓存:< beanName, ObjectFactory 或者 提前AOP得到的bean >
             *
             *          这就会出现一个问题,很难确定二级缓存存储得值 是 ObjectFactory 还是 提前AOP得到的bean,
             *          你可能会这么想 `earlySingletonReference instanceof ObjectFactory` 来检验,但这是不靠谱的,因为有可能bean的类型就是 ObjectFactory 的
             *          所以呢,只能使用东西标记二级缓存的值  是 ObjectFactory 还是 提前AOP得到的bean,
             *          比如 这么设计: ThreadLocal< beanName, boolean > earlyLocal : false 表示二级缓存的值是 ObjectFactory,true 表示二级缓存的值是 提前AOP得到的bean
             *
             *          那么下面的 判断逻辑应当改成 ` if ( earlySingletonReference != null && earlyLocal.get().get(beanName) )
             *
             *          所以呢肯定是需要使用东西来标记一下,是否执行了 ObjectFactory 得到 提前AOP得到的bean,Spring是采用的三级缓存来标记,
             *          这就是为啥使用三级缓存
             *
             * */
            Object earlySingletonReference = getSingleton(beanName, false);
            /**
             * 能够获取到,说明是在二级缓存拿到的。也就是这个 beanName 产生了循环依赖的问题,
             * */
            /**
             *  相等,说明初始化操作并没有对bean进行代理,那就没事。二级缓存的值作为最后要存入单例池中的值
             *  不相等,说明对bean进行了代理。这就会导致循环依赖了bean的那些东西,注入的bean是不对的,我们需要判断一下
             *      那些东西是否已经创建完了,创建完,那就没得搞了,只能报错了。
             */
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            }
            /**
             * hasDependentBean(beanName) 说明,这个bean已经注入到其他的bean对象中
             * */
            else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                /**
                 * 获取依赖了 beanName 的bean。其实就是获取哪些bean注入了 beanName这个bean
                 *
                 * 在依赖注入时会记录,比如@Resource的注入逻辑 { org.springframework.context.annotation.CommonAnnotationBeanPostProcessor的autowireResource(BeanFactory, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.LookupElement, String)}
                 * */
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    /**
                     * 尝试挽救一下,如果 dependentBean 还没有创建完成,那就没问题了
                     *
                     * 创建完成的标记,是在这个地方设置的,也就是在 doGetBean 的一开始就设置了
                     * { AbstractBeanFactory的doGetBean(String, Clazz, Object[], boolean)}
                     * { AbstractBeanFactory的markBeanAsCreated(String)}
                     * */
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        /**
                         * 已经创建完了,就记录一下。
                         * */
                        actualDependentBeans.add(dependentBean);
                    }
                }
                // 报错
                if (!actualDependentBeans.isEmpty()) {
                    throw new BeanCurrentlyInCreationException();
                }
            }
        }
        return exposedObject;

    }

AutowiredAnnotationBeanPostProcessor

处理有 @Autowired | @Value 的字段、方法,进行依赖注入

@Autowired 推断构造器

@Lookup 标注的方法,记录到BeanDefinition中,在后面实例化bean的时候会创建代理对象

  • BeanPostProcessor执行过程:实例化前后置 -> 推断构造器后置(hit) --> 实例化bean -> 合并BeanDefinition后置(hit) -> 实例化后后置 -> 属性注入后置(hit )->初始化前后置 -> 初始化后后置 -> 销毁前后置

  • 推断构造器阶段 AutowiredAnnotationBeanPostProcessor的determineCandidateConstructors方法

    • 作用一:解析类中(会递归解析父类)标注了@Lookup的方法,装饰成new LookupOverride(method, lookup.value())对象设置成BeanDefinition的属性。在实例化bean的时候,会获取该属性判断是否需要生成Cglib代理对象。

    • 推断构造器。

       candidateConstructors = new Constructor<?>[0];
      
       存在@Autowired标注的构造器
       @Autowired(required=true) 只能标注一个。candidateConstructors = [这一个]
       @Autowired(required=false) 可以标注多个。candidateConstructors = [多个+无参构造器(如果存在)]
         
       不存在
       只有一个构造器且是有参的。candidateConstructors = [这一个]
        
       return candidateConstructors.length>0 ? candidateConstructors : null
       返回null,就是没有候选的构造器集合,后面的实例化自然会调用无参构造器实例化
      
  • 合并BeanDefinition阶段

    • 拿到bean的InjectionMetadata对象

      • beanName 或者 beanClazz.getName 作为key,从缓存中{ AutowiredAnnotationBeanPostProcessor的injectionMetadataCache方法}取出InjectionMetadata
      • InjectionMetadata 是空 或者需要刷新,就解析beanCass构建 InjectionMetadata 对象
      • do...while 递归解析clazz及其所有父类,拿到其中标注了 @Autowired、@Value 的方法和字段构造成InjectedElement,然后记录在局部变量elements中
      • new AutowiredFieldElement(field, required)
      • new AutowiredMethodElement(method, required, pd)
      • 创建对象 InjectionMetadata.forElements(elements, clazz);
      • InjectionMetadata 对象的属性{ InjectionMetadata的injectedElements}就是记录了标注了 @Autowired、@Value 注解的Method和Field
      • 存入缓存
      • 返回 InjectionMetadata
    • 检查 InjectionMetadata 对象

      • 将 { InjectionMetadata的injectedElements} 记录到BeanDefinition中
      • 将 { InjectionMetadata的injectedElements} 设置到 { InjectionMetadata的checkedElements} 表示已经检查过了
  • 属性注入

    • 拿到bean解析而成的InjectionMetadata
    • 执行

CommonAnnotationBeanPostProcessor

处理@PostConstruct、@PreDestroy 标注的方法回调。处理@Resource 字段、方法的依赖注入

  • BeanPostProcessor执行过程:实例化前后置 -> 推断构造器后置 -> 实例化bean -> 合并BeanDefinition后置(hit) -> 实例化后后置 -> 属性注入后置(hit) -> 初始化前后置(hit) -> 初始化后后置 -> 销毁前后置(hit)

  • 合并BeanDefinition阶段

    • 回调父类方法

    • 解析class生成 LifecycleMetadata

    • do...while 循环,递归父类,找到有 @PostConstruct、@PreDestroy 的方法 记录成 LifecycleElement,其中@PostConstruct记录在initMethods,@PreDestroy记录在destroyMethods

    • 创建对象new LifecycleMetadata(clazz, initMethods, destroyMethods)

    • 记录有 @Resource 字段、方法的类,解析成 new InjectionMetadata(clazz, elements)),其中elements的类型ResourceElement

    • 解析class生成 InjectionMetadata

    • do...while 递归父类,找到有 @Resource 的字段、方法 装饰成 ResourceElement,记录在局部变量 elements

    • 创建对象InjectionMetadata.forElements(elements, clazz)

    • 注:这里主要是缓存起来,一个类对应一个 LifecycleMetadata、InjectionMetadata 对象,对象的属性是记录 回调的字段、方法

  • 属性注入阶段

    • 拿到bean解析而成的InjectionMetadata
    • 执行
  • 初始化前阶段(父类)

    • 从缓存中拿到类对应的 LifecycleMetadata,拿不到就解析类生成 LifecycleMetadata。
    • 回调init方法metadata.invokeInitMethods;
    • 其实就是遍历 { InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata的initMethods} 属性,反射执行method。一个initMethod就是@PostConstruct标注的方法
  • 销毁前阶段

    • 从缓存中拿到类对应的 LifecycleMetadata,拿不到就解析类生成 LifecycleMetadata。
    • 回调Destroy方法metadata.invokeDestroyMethods;
    • 其实就是遍历 { InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata的destroyMethods} 属性,反射执行method。一个destroyMethod就是@PreDestroy标注的方法

postProcessMergedBeanDefinition

AbstractAutowireCapableBeanFactory:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd,
                              @Nullable Object[] args) throws BeanCreationException {

    // BeanWrapper是对Bean的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装bean的属性描述器
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        // 从没有完成的 FactoryBean中移除
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        /**
         *  推断构造器
         * 创建bean实例化使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化。
         * 该方法很复杂也很重要
         */
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
  
    // 从 beanWrapper中获取我们的早期对象
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                /**
                 *  后置处理器的【第四次】MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition
                 * 进行后置处理 @Autowired @Value的注解的预解析
                 */
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            } catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Post-processing of merged bean definition failed", ex
                );
            }
            mbd.postProcessed = true;
        }
    }

    /**
     *  该对象进行判断是否能够暴露早期对象的条件
     * 单实例 this.allowCircularReferences 默认为true
     * isSingletonCurrentlyInCreation(表示当前的bean对象正在创建singletonsCurrentlyInCreation包含当前正在创建的bean)
     *  举例:
     *    class A { B b;}
     *    class B { A a;}
     *    先实例化A --> singletonsCurrentlyInCreation = {A}
     *    依赖注入B --> singletonsCurrentlyInCreation = {A,B}
     *    依赖注入A --> singletonsCurrentlyInCreation = {A,B} ==> 发现 isSingletonCurrentlyInCreation(a) 满足条件,所以应该暴露A到三级缓存
     *
     *  singletonsCurrentlyInCreation 是在单例bean 创建之前就设置的
     *  @see org.springframework.beans.factory.support.DefaultSingletonBeanRegistry的beforeSingletonCreation(java.lang.String)
     * */
    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(
            beanName));
    // 上述条件满足,允许中期暴露对象
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace(
                    "Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
        }
        /**
         *  循环依赖-添加到三级缓存中
         * 把我们的早期对象包装成一个 singletonFactory 对象,该对象提供了一个 getObject方法,该方法内部调用 getEarlyBeanReference(beanName, mbd, bean)
         * 实现提前AOP
         * */
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
        //  填充bean,就是依赖注入或者给属性设置值
        populateBean(beanName, mbd, instanceWrapper); // getBean()
        //  进行对象初始化操作(在这里可能生成代理对象)
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    } catch (Throwable ex) {
        if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
            throw (BeanCreationException) ex;
        } else {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
        }
    }
    /**
     * 这里是为了处理二级缓存中的bean 和 执行了初始化操作的 bean 不一致的校验,不一致说明可能存在
     * 依赖注入的bean 和 实际存入单例池中的bean 不一致的问题。对于不一致,下面的处理是报错
     *
     *
     * 比如 A 注入了 B,B 注入了 A
     * 先是 getBean(A),然后其 populateBean 环节要注入B, 所以会 getBean(B),然后其 populateBean 环节要注入A,所以要 getBean(A)
     * 此时发现A正在创建,所以会读取三级缓存的value,然后执行提前AOP得到一个 proxyBeanA ,并将 proxyBeanA 存入二级缓存,然后将 proxyBeanA 注入到 B中,
     * 然后B就创建完了,然后B就会被注入到A中,所以A的 populateBean 结束了,然后会执行 initializeBean。假设在 initializeBean 生成了 proxyBeanA2 。
     * 这就出现了 注入到B中的A,和实际最终生成的A不一致的问题,对于这中情况,只能直接报错了,下面的逻辑就是为了应付这种情况的,
     *
     * 注:当然 提前AOP 也不一定会创建代理对象,我这里只是举例了 提前AOP和初始化都创建了代理对象的场景,方便说明
     *
     * */
    if (earlySingletonExposure) {
        /**
         * 去缓存中获取到我们的对象,由于传递的 allowEarlyReference 是false要求只能在一级二级缓存中去获取。
         * 说白了,就尝试从二级缓存中获取bean。
         *
         * 注:在这里就能体会到三级缓存的好处了。因为这里是只会从一级缓存和二级缓存中获取内容(其实只可能从二级缓存中拿到,一级缓存是拿不到的,因为此时还未将单例bean存入一级缓存)
         *     如果二级缓存拿到的值不为null,就校验一下 exposedObject(执行了初始化后置处理器返回的值) 和 bean(简单实例化出来的) 是否一致,
         *     若不一致,就需要判断一下,这个bean是否注入给了其他bean对象,若注入给了其他bean对象,那么就只能报错了,因为已经注入给了其他bean的值 和 exposedObject 不一致。
         *
         *     假设我们采用二级缓存来解决循环依赖的问题。思路如下:
         *          一级缓存用来缓存最终完全的bean,二级缓存一开始存入的是 ObjectFactory ,当出现了循环依赖时,读取二级缓存的值,然后回调方法 ObjectFactory的getObject 得到 提前AOP的bean。
         *          将 提前AOP的bean 存入进二级缓存,也就是进行值覆盖。
         *
         *          一级缓存:< beanName,最终的bean >
         *          二级缓存:< beanName, ObjectFactory 或者 提前AOP得到的bean >
         *
         *          这就会出现一个问题,很难确定二级缓存存储得值 是 ObjectFactory 还是 提前AOP得到的bean,
         *          你可能会这么想 `earlySingletonReference instanceof ObjectFactory` 来检验,但这是不靠谱的,因为有可能bean的类型就是 ObjectFactory 的
         *          所以呢,只能使用东西标记二级缓存的值  是 ObjectFactory 还是 提前AOP得到的bean,
         *          比如 这么设计: ThreadLocal< beanName, boolean > earlyLocal : false 表示二级缓存的值是 ObjectFactory,true 表示二级缓存的值是 提前AOP得到的bean
         *
         *          那么下面的 判断逻辑应当改成 ` if ( earlySingletonReference != null && earlyLocal.get().get(beanName) )
         *
         *          所以呢肯定是需要使用东西来标记一下,是否执行了 ObjectFactory 得到 提前AOP得到的bean,Spring是采用的三级缓存来标记,
         *          这就是为啥使用三级缓存
         *
         * */
        Object earlySingletonReference = getSingleton(beanName, false);
        /**
         * 能够获取到,说明是在二级缓存拿到的。也就是这个 beanName 产生了循环依赖的问题,
         * */
        if (earlySingletonReference != null) {
            /**
             *  相等,说明初始化操作并没有对bean进行代理,那就没事。二级缓存的值作为最后要存入单例池中的值
             *  不相等,说明对bean进行了代理。这就会导致循环依赖了bean的那些东西,注入的bean是不对的,我们需要判断一下
             *      那些东西是否已经创建完了,创建完,那就没得搞了,只能报错了。
             */
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            }
            /**
             * hasDependentBean(beanName) 说明,这个bean已经注入到其他的bean对象中
             * */
            else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                /**
                 * 获取依赖了 beanName 的bean。其实就是获取哪些bean注入了 beanName这个bean
                 *
                 * 在依赖注入时会记录,比如@Resource的注入逻辑 { org.springframework.context.annotation.CommonAnnotationBeanPostProcessor的autowireResource(BeanFactory, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.LookupElement, String)}
                 * */
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    /**
                     * 尝试挽救一下,如果 dependentBean 还没有创建完成,那就没问题了
                     *
                     * 创建完成的标记,是在这个地方设置的,也就是在 doGetBean 的一开始就设置了
                     * { AbstractBeanFactory的doGetBean(String, Clazz, Object[], boolean)}
                     * { AbstractBeanFactory的markBeanAsCreated(String)}
                     * */
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        /**
                         * 已经创建完了,就记录一下。
                         * */
                        actualDependentBeans.add(dependentBean);
                    }
                }
                // 报错
                if (!actualDependentBeans.isEmpty()) {
                    throw new BeanCurrentlyInCreationException(beanName,
                            "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(
                                    actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example."
                    );
                }
            }
        }
    }

    // Register bean as disposable.
    try {
        /**
         * 注册一次性bean 的销毁接口
         * */
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}
AutowiredAnnotationBeanPostProcessor:
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Clazz<?> beanType, String beanName) {
    InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
    metadata.checkConfigMembers(beanDefinition);
}
AutowiredAnnotationBeanPostProcessor:
private InjectionMetadata findAutowiringMetadata(String beanName, Clazz<?> 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);
    /**
     * metadata 是空 或者 metadata的属性{ InjectionMetadata的targetClass} != clazz
     * 就需要刷新
     * */
    if (InjectionMetadata.needsRefresh(metadata, clazz)) {
        synchronized (this.injectionMetadataCache) {
            metadata = this.injectionMetadataCache.get(cacheKey);
            if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                if (metadata != null) {
                    // 从 pvs 里面清空 metadata 的数据
                    metadata.clear(pvs);
                }
                /**
                 * 构建 InjectionMetadata 对象。
                 * 主要是解析clazz及其所有父类,拿到其中标注了 @Autowired、@Value 的 方法和字段
                 *  字段会包装成`new AutowiredFieldElement(field, required);`
                 *  方法会包装成`new AutowiredMethodElement(method, required, pd);`
                 * */
                metadata = buildAutowiringMetadata(clazz);
                // 存入缓存
                this.injectionMetadataCache.put(cacheKey, metadata);
            }
        }
    }
    return metadata;
}
AutowiredAnnotationBeanPostProcessor:
/**
 * 解析clazz及其所有父类,拿到其中标注了 @Autowired、@Value 的 方法和字段构造成InjectionMetadata对象
 * @param clazz
 * @return
 */
private InjectionMetadata buildAutowiringMetadata(final AutowiredAnnotationBeanPostProcessor的buildAutowiringMetadata<?> clazz) {
    /**
     * 不是后候选的类,就返回空对象
     *
     * 只要clazz不是java包下的类,不是Ordered类 就是 候选类
     * */
    if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
        return InjectionMetadata.EMPTY;
    }

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

    /**
     * 先处理clazz,再循环 clazz 所有的父类
     *
     * 处理class里面所有的Field、Method
     * */
    do {
        final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

        // 遍历当前类声明的字段
        ReflectionUtils.doWithLocalFields(targetClass, field -> {
            // 找到 @Autowired、@Value、@javax.inject.Inject 其中一个,就返回,否则返回null
            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;
                }
                /**
                 * 返回注解的 `required` 属性的值。如果没有就返回true(比如@Value)
                 * */
                boolean required = determineRequiredStatus(ann);
                // 构造成 `AutowiredFieldElement` 对象
                currElements.add(new AutowiredFieldElement(field, required));
            }
        });
        // 遍历当前类声明的方法
        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
            // 不是桥接方法,桥接方法指的是jvm生成的方法。反正我们自己定义的方法不是
            if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                return;
            }
            // 找到 @Autowired、@Value、@javax.inject.Inject 其中一个,就返回,否则返回null
            MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
            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;
                }
                // 方法没有参数,不记录
                if (method.getParameterCount() == 0) {
                    if (logger.isInfoEnabled()) {
                        logger.info("Autowired annotation should only be used on methods with parameters: " +
                                method);
                    }
                }
                // 不是静态方法、方法参数列表个数大于0的才记录
                // 返回注解的 `required` 属性的值。如果没有就返回true(比如@Value)
                boolean required = determineRequiredStatus(ann);
                PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                // 装饰成 AutowiredMethodElement 对象
                currElements.add(new AutowiredMethodElement(method, required, pd));
            }
        });

        // 存起来
        elements.addAll(0, currElements);
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    return InjectionMetadata.forElements(elements, clazz);
}
CommonAnnotationBeanPostProcessor:
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Clazz<?> beanType, String beanName) {
    /**
     * 找到有 @PostConstruct、@PreDestroy 的方法 记录成 LifecycleElement,然后属于 LifecycleMetadata
     * */
    super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
    /**
     * 找到有 @Resource 的方法、字段的类 记录成 ResourceElement,然后属于 InjectionMetadata
     * */
    InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
    metadata.checkConfigMembers(beanDefinition);
}
CommonAnnotationBeanPostProcessor:
private InjectionMetadata findResourceMetadata(String beanName, final 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);
    if (InjectionMetadata.needsRefresh(metadata, clazz)) {
        synchronized (this.injectionMetadataCache) {
            metadata = this.injectionMetadataCache.get(cacheKey);
            if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                if (metadata != null) {
                    metadata.clear(pvs);
                }
                /**
                 * 递归父类,将字段和方法上有 @Resource注解记录成 ResourceElement对象,所以是一个集合,
                 * 这个集合属于 InjectionMetadata 对象
                 * */
                metadata = buildResourceMetadata(clazz);
                // 缓存起来
                this.injectionMetadataCache.put(cacheKey, metadata);
            }
        }
    }
    return metadata;
}
CommonAnnotationBeanPostProcessor:
private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
    /**
     * 就是有@Resource注解
     * */
    if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) {
        return InjectionMetadata.EMPTY;
    }

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

    /**
     * do...while 递归父类,找到有 @Resource 的字段、方法 装饰成 ResourceElement,记录在 elements
     * 这个集合属于 InjectionMetadata 的,也就是说 InjectionMetadata 对应的就是一个类
     * */
    do {
        final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
        ReflectionUtils.doWithLocalFields(targetClass, field -> {
            if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
                if (Modifier.isStatic(field.getModifiers())) {
                    throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
                }
                currElements.add(new WebServiceRefElement(field, field, null));
            } else if (ejbClass != null && field.isAnnotationPresent(ejbClass)) {
                if (Modifier.isStatic(field.getModifiers())) {
                    throw new IllegalStateException("@EJB annotation is not supported on static fields");
                }
                currElements.add(new EjbRefElement(field, field, null));
            } else if (field.isAnnotationPresent(Resource.class)) {
                if (Modifier.isStatic(field.getModifiers())) {
                    throw new IllegalStateException("@Resource annotation is not supported on static fields");
                }
                if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
                    currElements.add(new ResourceElement(field, field, null));
                }
            }
        });

        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
            if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                return;
            }
            if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) {
                    if (Modifier.isStatic(method.getModifiers())) {
                        throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
                    }
                    /**
                     * @Resouce 标注的方法,只允许有一个参数
                     * */
                    if (method.getParameterCount() != 1) {
                        throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
                    }
                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                    currElements.add(new WebServiceRefElement(method, bridgedMethod, pd));
                } else if (ejbClass != null && bridgedMethod.isAnnotationPresent(ejbClass)) {
                    if (Modifier.isStatic(method.getModifiers())) {
                        throw new IllegalStateException("@EJB annotation is not supported on static methods");
                    }
                    if (method.getParameterCount() != 1) {
                        throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
                    }
                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                    currElements.add(new EjbRefElement(method, bridgedMethod, pd));
                } else if (bridgedMethod.isAnnotationPresent(Resource.class)) {
                    if (Modifier.isStatic(method.getModifiers())) {
                        throw new IllegalStateException("@Resource annotation is not supported on static methods");
                    }
                    Class<?>[] paramTypes = method.getParameterTypes();
                    if (paramTypes.length != 1) {
                        throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
                    }
                    if (!this.ignoredResourceTypes.contains(paramTypes[0].getName())) {
                        PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                        currElements.add(new ResourceElement(method, bridgedMethod, pd));
                    }
                }
            }
        });

        elements.addAll(0, currElements);
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    return InjectionMetadata.forElements(elements, clazz);
}

postProcessProperties

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    // 若bw为nul1的话,则说明对象没有实例化
    if (bw == null) {
        if (mbd.hasPropertyValues()) {
            // 进入if 说明对象有属性,bw为空,不能为他设置属性,那就在下面就执行抛出异常
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        } else {
            // Skip property population phase for null instance.
            return;
        }
    }

    /**
     * 在属性被填充前,给 InstantiationAwareBeanPostProcessor 类型的后置处理器一个修改
     * bean状态的机会。官方的解释是:让用户可以自定义属性注入。比如用户实现一
     * 个 InstantiationAwareBeanPostProcessor 类型的后置处理器,并通过
     * postProcessAfterInstantiation 方法向bean的成员变量注入自定义的信息
     * 当时我们发现系统中的的 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 没有进行任何处理
     * 若我们自己实现了这个接口可以自定义处理.... spring留给我们自已扩展接口的
     * 特殊需求,直接使用配置中的信息注入即可
     * */
    // 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.
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            /**
             *  后置处理器的【第五次】InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation
             * @see cn.haitaoss.javaconfig.beanpostprocessor.MyInstantiationAwareBeanPostProcessor的postProcessAfterInstantiation(Object, String)
             *
             * 若存在后置处理器给我们属性赋值了,那么返回fale可以来修改我们的开关变量,就不会走下面的逻辑了
             * */
            if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                /**
                 * 返回值为是否继续填充bean
                 * postProcessAfterInstantiation:如果应该在bean上面设置属性则返回true,否则返回 false
                 * 一般情况下,应该是返回true。
                 * 返回 false的话,将会阻止在此Bean实例上调用任何后续的 InstantiationAwareBeanPostProcessor
                 */
                return;
            }
        }
    }

    // 获取bean定义的属性
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    /**
     * 判断我们的bean的属性注入模型
     * AUTOWIRE_BY_NAME 根据名称注入
     * AUTOWIRE_BY_TYPE 根据类型注入
     *
     * 可以这样子指定:@Bean(autowire = Autowire.BY_NAME)
     * */
    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
        // 把 PropertyValues 封装成为 MutablePropertyValues
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        // 根据bean的属性名称注入
        // Add property values based on autowire by name if applicable.
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
            /**
             * 这里主要是会判断 有没有 { BeanWrapper的getPropertyDescriptor(String)} 是要给 { AbstractAutowireCapableBeanFactory的ignoredDependencyInterfaces}
             * 的接口方法设置值的,排除掉这些 PropertyDescriptor。
             * */
            autowireByName(beanName, mbd, bw, newPvs);
        }
        // 根据bean的类型进行注入
        // Add property values based on autowire by type if applicable.
        if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            /**
             * 这里主要是会判断 有没有 { BeanWrapper的getPropertyDescriptor(String)} 是要给 { AbstractAutowireCapableBeanFactory的ignoredDependencyInterfaces}
             * 的接口方法设置值的,排除掉这些 PropertyDescriptor。
             * */
            autowireByType(beanName, mbd, bw, newPvs);
        }
        // 把处理过的属性覆盖原来的
        pvs = newPvs;
    }

    /**
     * 这里又是一种后置处理,用于在 Spring 填充属性到bean对象前,对属性的值进行相应的处理
     * 比如可以修改某些属性的值。这时注入到bean中的值就不是配置文件中的内容了,
     * 而是经过后置处理器修改后的内容
     * */
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    // 判断是否需要检查依赖
    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

    // 退出当前正在创建的 beanWrapper依赖的对象
    PropertyDescriptor[] filteredPds = null;
    if (hasInstAwareBpps) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            /**
             *  后置处理器的【第六次】InstantiationAwareBeanPostProcessor的postProcessProperties
             * 进行字段和方法的依赖注入{ cn.haitaoss.javaconfig.beanpostprocessor.MyInstantiationAwareBeanPostProcessor的postProcessProperties(PropertyValues, Object, String)}
             */
            PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
                if (filteredPds == null) {
                    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                }
                /**
                 *  后置处理器的【第七次】cn.haitaoss.javaconfig.beanpostprocessor.MyInstantiationAwareBeanPostProcessor的postProcessPropertyValues(org.springframework.beans.PropertyValues, java.beans.PropertyDescriptor[], java.lang.Object, java.lang.String)
                 * 过时方法了,不建议使用
                 * @see cn.haitaoss.javaconfig.beanpostprocessor.MyInstantiationAwareBeanPostProcessor的postProcessPropertyValues(PropertyValues, Object, String)
                 */
                pvsToUse = bp.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);
    }

    /**
     * 其实,上面只是完成了所有注入属性的获取,将获取的属性封装在 PropertyValues的实例对象pvs中,
     * 并没有应用到已经实例化的bean中。而
     * @see org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory的applyPropertyValues(java.lang.String, org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.BeanWrapper, org.springframework.beans.PropertyValues)
     * 则是完成这一步骤的
     * */
    if (pvs != null) {
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}
AutowiredAnnotationBeanPostProcessor:
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    /**
     * 拿到要注入member信息,有缓存机制。
     * 在 { AutowiredAnnotationBeanPostProcessor的postProcessMergedBeanDefinition} 就解析过了。
     * */
    InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
    try {
        /**
         * 会根据 InjectionMetadata 需要注入的信息,
         * 往 PropertyValues 中设置
         * */
        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;
}
CommonAnnotationBeanPostProcessor:
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    /**
     * 找到类里面有 @Resource 的字段、方法 包装成 ResourceElement 对象,然后属于 InjectionMetadata。
     * */
    InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
    try {
        /**
         * 就是遍历 { InjectionMetadata的injectedElements} 进行注入
         * */
        metadata.inject(bean, beanName, pvs);
    } catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
    }
    return pvs;
}

InjectionMetadata.inject

/**
 * 就是遍历其 injectedElements 属性,执行 { InjectedElement的inject(Object, String, PropertyValues)}
 * @param target
 * @param beanName
 * @param pvs
 * @throws Throwable
 */
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    Collection<InjectedElement> checkedElements = this.checkedElements;
    Collection<InjectedElement> elementsToIterate =
            (checkedElements != null ? checkedElements : this.injectedElements);
    if (!elementsToIterate.isEmpty()) {
        /**
         * 遍历 elementsToIterate。
         *
         * 比如 AutowiredAnnotationBeanPostProcessor 生成的 InjectionMetadata,其中的
         * injectedElements 属性的值,其实就是 标注了@Autowired、@Value注解的字段和方法
         * */
        for (InjectedElement element : elementsToIterate) {
            /**
             * target 是 bean对象
             * Field 的注入  { AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement的inject(Object, String, PropertyValues)}
             * Method 的注入 { AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement的inject(Object, String, PropertyValues)}
             *
             * 如果是 ResourceElement 执行的是 { InjectedElement的inject(Object, String, PropertyValues)}
             * */
            element.inject(target, beanName, pvs);
        }
    }
}

InjectedElement的inject

/**
 * 依赖注入:@Resource标注的字段、方法是执行父类方法 { InjectionMetadata.InjectedElement的inject(Object, String, PropertyValues)}
 *
 * 是字段,直接反射设置值
 *      `field.set(target, getResourceToInject(target, requestingBeanName));`
 *
 * 是方法,先判断是否应该跳过,不跳过就反射执行方法
 *      - 检查是否跳过 { InjectionMetadata.InjectedElement的checkPropertySkipping(PropertyValues)}
 *          就是判断 PropertyValues 中有没有这个方法的信息,存在就跳过
 *      - 反射执行方法 `method.invoke(target, getResourceToInject(target, requestingBeanName));`
 *
 * 获取注入的值,会在这里判断是否创建代理对象 { CommonAnnotationBeanPostProcessor.ResourceElement的getResourceToInject(Object, String)}
 *      - element没有@Lazy注解,直接获取注入值 { CommonAnnotationBeanPostProcessor的getResource(CommonAnnotationBeanPostProcessor.LookupElement, String)}
 *      - element有@Lazy注解,构建代理对象作为注入值 { CommonAnnotationBeanPostProcessor的buildLazyResourceProxy(CommonAnnotationBeanPostProcessor.LookupElement, String)}
 *          1. 定义内部类TargetSource
 *              TargetSource ts = new TargetSource() {
 *                  @Override
 *                  public Object getTarget() {
 *                      // 执行代理对象的方法时,会调`getTarget`得到被代理对象,所以是在执行代理对象的方法时才会执行依赖的解析
 *                      // 这就是@Lazy的原理哦,延时创建
 *                      return getResource(element, requestingBeanName);
 *                  }
 *              };
 *
 *          2. return 创建的代理对象
 *              ProxyFactory pf = new ProxyFactory();
 *              pf.setTargetSource(ts);
 *              return pf.getProxy(classLoader);
 * getResource
 *  { CommonAnnotationBeanPostProcessor的getResource(CommonAnnotationBeanPostProcessor.LookupElement, String)}
 *  { CommonAnnotationBeanPostProcessor的autowireResource(BeanFactory, CommonAnnotationBeanPostProcessor.LookupElement, String)}
 *      - BeanFactory中没有依赖的名字`!factory.containsBean(name)`
 *          构造 { CommonAnnotationBeanPostProcessor.LookupElement的getDependencyDescriptor()} 
 *              字段使用这个`new LookupDependencyDescriptor((Field) this.member, this.lookupType);`
 *              方法使用这个`new LookupDependencyDescriptor((Method) this.member, this.lookupType);`
 *          通过 DependencyDescriptor 从BeanFactory得到依赖值 { DefaultListableBeanFactory的resolveDependency(DependencyDescriptor, String, Set, TypeConverter)}
 *      - BeanFactory中有依赖的名字
 *          通过name从BeanFactory得到依赖值 { AbstractBeanFactory的getBean(String, Clazz)}
 *      - 记录依赖关系 { ConfigurableBeanFactory的registerDependentBean(String, String)} 
 * 			Tips:所以说@Resource 是byName再byType
 * */

AutowiredFieldElement的inject

/**
 * 依赖注入:@Autowired、@Value 标注的字段会执行这个 { AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement的inject(Object, String, PropertyValues)}
 *  - 解析字段值 `value = resolveFieldValue(field, bean, beanName);`
 *  - 反射给字段设置值 `field.set(bean, value);`
 *
 * 解析字段值 { AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement的resolveFieldValue(Field, Object, String)}
 *      - 构造`new DependencyDescriptor(field, this.required);`
 *      - 通过 DependencyDescriptor 从BeanFactory得到依赖值 { DefaultListableBeanFactory的resolveDependency(DependencyDescriptor, String, Set, TypeConverter)}
 *      - 记录依赖关系 { ConfigurableBeanFactory的registerDependentBean(String, String)}
 *      - 缓存起来 `this.cachedFieldValue = cachedFieldValue;`
 * */

AutowiredMethodElement的inject

/**
 * 依赖注入:@Autowired、@Value 标注的方法会执行这个{ AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement的inject(Object, String, PropertyValues)}
 *      - 解析方法参数列表的值 `arguments = resolveMethodArguments(method, bean, beanName);`
 *      - 反射执行方法 `method.invoke(bean, arguments);`
 *
 * 解析参数列表的值 { AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement的resolveMethodArguments(Method, Object, String)}
 *      - 遍历方法参数列表,挨个解析 `for (int i = 0; i < arguments.length; i++) {}`
 *      - 构造,也就是一个参数是一个DependencyDescriptor
 *          MethodParameter methodParam = new MethodParameter(method, i);
 *          DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
 *      - 通过 DependencyDescriptor 从BeanFactory得到依赖值 { DefaultListableBeanFactory的resolveDependency(DependencyDescriptor, String, Set, TypeConverter)}
 *      - 记录依赖关系 { ConfigurableBeanFactory的registerDependentBean(String, String)}
 *      - 缓存起来 `this.cachedMethodArguments = cachedMethodArguments;`
 * */
 * 

DefaultListableBeanFactory的resolveDependency

/**
 * 解析依赖 { DefaultListableBeanFactory的resolveDependency(DependencyDescriptor, String, Set, TypeConverter)}
 *  1. 有@Lazy就创建代理对象快速返回 `Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);`
 *      - 使用BeanFactory的AutowireCandidateResolver 解析 { ContextAnnotationAutowireCandidateResolver的getLazyResolutionProxyIfNecessary(DependencyDescriptor, String)}
 *          - 是否有@Lazy注解 { ContextAnnotationAutowireCandidateResolver的isLazy(DependencyDescriptor)}
 *              字段 DependencyDescriptor:字段是否有@Lazy注解
*              方法的参数 DependencyDescriptor:参数是否有@Lazy注解,没有在接着看其Method是否有@Lazy注解
 *          - 有就创建代理对象 { ContextAnnotationAutowireCandidateResolver的buildLazyResolutionProxy(DependencyDescriptor, String)}
 *                  TargetSource ts = new TargetSource() {
 *                       public Object getTarget() {
 *                           // 执行代理对象的方法时,会调`getTarget`得到被代理对象,所以是在执行代理对象的方法时才会执行依赖的解析
 *                           // 这就是@Lazy的原理哦,延时解析依赖
 *                           return dlbf.doResolveDependency(descriptor, beanName, autowiredBeanNames, null);
 *                       }
 *                   };
 *                   ProxyFactory pf = new ProxyFactory();
 *                   pf.setTargetSource(ts);
 *                   return pf.getProxy();
 *
 *      - 解析的值不是null,就return
 *
 *  2. 开始解析依赖 { DefaultListableBeanFactory的doResolveDependency(DependencyDescriptor, String, Set, TypeConverter)}
 * */

DefaultListableBeanFactory的doResolveDependency

/**
* 开始解析依赖 { DefaultListableBeanFactory的doResolveDependency(DependencyDescriptor, String, Set, TypeConverter)}
*
*  标记一下,正在进行依赖解析 `InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);`
*
*  处理有@Value的情况,没有@Value就会往下判断了
*      - 拿到@Value注解的值。查找顺序: 字段、方法参数没有@Value() -> 如果是方法参数依赖,就看看方法上有没有@Value
*          `Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);`
*          { QualifierAnnotationAutowireCandidateResolver的getSuggestedValue(DependencyDescriptor)}
*
*      - value是String类型
*          - 解析占位符 { AbstractBeanFactory的resolveEmbeddedValue(String)}
*              `String strVal = resolveEmbeddedValue((String) value);`
*          - 进行SpEL的解析,这里就会从容器中获取bean
*              `value = evaluateBeanDefinitionString(strVal, bd);`
*              { AbstractBeanFactory的evaluateBeanDefinitionString(String, BeanDefinition)}
*
*      - 拿到 TypeConverter `TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());`
*              SimpleTypeConverter typeConverter = new SimpleTypeConverter();
*              typeConverter.setConversionService(getConversionService()); // 从容器中获取一个name 是 conversionService 的bean
*              registerCustomEditors(typeConverter); // 使用BeanFactory的ResourceEditorRegistrar对typeConverter进行加工,默认是有这个`ResourceEditorRegistrar`
*              return typeConverter;
*      - 使用 TypeConverter,直接return 完成依赖的解析 `return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());`
*
*  依赖类型是多个的情况 `Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);` { DefaultListableBeanFactory的resolveMultipleBeans(DependencyDescriptor, String, Set, TypeConverter)}
*      - 就是依赖的类型是 数组、Collection、Map的时候才会处理
*      - 查找AutowireCandidates { DefaultListableBeanFactory的findAutowireCandidates(String, Clazz, DependencyDescriptor)}
*      - 使用converter转换 `Object result = converter.convertIfNecessary(matchingBeans.values(), type);`
*      - 使用依赖排序器,对结果进行排序 { DefaultListableBeanFactory的adaptDependencyComparator(Map)}
*      - multipleBeans!=null 直接`return multipleBeans;`
*
*  查找AutowireCandidates `Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);` { DefaultListableBeanFactory的findAutowireCandidates(String, Clazz, DependencyDescriptor)}
*      - 没有匹配的bean,这个依赖还是必须的,那就直接抛出异常 `matchingBeans.isEmpty() && isRequired(descriptor) `
*
*  存在多个候选bean,需要确定唯一一个。因为到这一步的依赖肯定是单个对象的,所以要从多个候选者中确定唯一的一个 `matchingBeans.size() > 1`
*      - { DefaultListableBeanFactory的determineAutowireCandidate(Map, DependencyDescriptor)}
*
*  拿到唯一的bean `instanceCandidate = matchingBeans.get(autowiredBeanName);`
*
*  是否需要实例化,
*      if (instanceCandidate instanceof Class)
*          instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this); // 这个就是 `getBean()`
*
*  返回依赖的值 `return instanceCandidate;`
*
*  移除标记 `ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);`
*
*  Tips:先判断是不是@Value的自动注入,解析结果不为null直接return;再看看依赖类型是不是多个(数组、集合、Map) 解析到值就return;最后就是依赖类型是单个对象的情况咯,
*  单个对象的依赖就需要从多个候选者中确定唯一一个,确定不了就报错咯
* */

DefaultListableBeanFactory的findAutowireCandidates

/**
 * { DefaultListableBeanFactory的findAutowireCandidates(String, Clazz, DependencyDescriptor)}
 *
 *  - 局部变量,记录候选bean,key是beanName,value是bean对象或者是beanClass `Map<String, Object> result = CollectionUtils.newLinkedHashMap();`
 *
 *  - 通过类型从BeanFactory找到匹配的candidateNames { BeanFactoryUtils的beanNamesForTypeIncludingAncestors(ListableBeanFactory, Clazz, boolean, boolean)}
 *      { DefaultListableBeanFactory的getBeanNamesForType(Clazz, boolean, boolean)}
 *      { DefaultListableBeanFactory的doGetBeanNamesForType(ResolvableType, boolean, boolean)}
 *          - 先从 BeanDefinitionMap 中找,根据依赖的类型进行匹配
 *          - 再从 manualSingletonNames 中找,根据依赖的类型进行匹配。这种是 { DefaultListableBeanFactory的registerSingleton(String, Object)} 这样子注册的,直接就放到单例池不会在BeanDefinitionMap中有记录
 *
 *  - 再从 resolvableDependencies 找到类型匹配的候选者。因为依赖是已经实例化好了,所以直接记录到result中。
 *      `result.put(beanName, autowiringValue);`
 *      Tips:resolvableDependencies 也叫bean伪装,因为这些依赖值是直接new出来的,不是通过`getBean()` 创建出来的。相当于扩展了BeanFactory可以注入的依赖类型。
 *
 *  - 遍历 candidateNames,是自动注入候选者就 `getBean()` 创建出bean对象,然后存到result中
 *      是自动注入候选者 { QualifierAnnotationAutowireCandidateResolver的isAutowireCandidate(BeanDefinitionHolder, DependencyDescriptor)}
 *          1. 先检查 这个就是检查BeanDefinition的属性值 { AbstractBeanDefinition的isAutowireCandidate()}
 *          2. 匹配了,再检查字段依赖@Qualifier校验,和方法依赖其参数@Qualifier校验
 *          3. 匹配了,是方法依赖且方法返回值不是Void,再才进行方法@Qualifier的匹配
 *          Tips:就是看看 @Qualifier("name") 与 candidateName 一致,就是true
 *
 *      是,就记录到result中 { DefaultListableBeanFactory的addCandidateEntry(Map, String, DependencyDescriptor, Clazz)}
 *          分为三种情况:
 *          1. 依赖类型是 数组、集合、Map等 `descriptor instanceof MultiElementDescriptor`
 *              依赖类型是多个,所以需要把类型的bean都通过BeanFactory创建出来
 *              - 通过BeanFactory得到bean实例 { DependencyDescriptor的resolveCandidate(String, Clazz, BeanFactory)}
 *              - 记录 `result.put(candidateName, beanInstance);`
 *
 *          2. candidateName 已经在单例池创建好了,所以可以直接拿
 *              - 通过BeanFactory得到bean实例 { DependencyDescriptor的resolveCandidate(String, Clazz, BeanFactory)}
 *              - 记录 `result.put(candidateName, beanInstance);`
 *
 *          3. 依赖类型不是多个,且单例池没有,那么只记录其Clazz,目的是防止不依赖的bean也被创建了
 *              - 从BeanFactory中 通过beanName拿到其类型, { AbstractBeanFactory的getType(String)}
 *              - 记录 `result.put(candidateName, getType(candidateName));`
 *              Tips:确定好唯一一个beanName的时候才会在实例化的。
 *
 *          Tips: `DependencyDescriptor的resolveCandidate` 其实就是 `beanFactory.getBean(beanName)`
 *
 *  - 返回 result
 * */

DefaultListableBeanFactory的determineAutowireCandidate

/**
 * 确定自动注入候选者 { DefaultListableBeanFactory的determineAutowireCandidate(Map, DependencyDescriptor)}
 *
 * 先通过@Primary查找 { DefaultListableBeanFactory的determinePrimaryCandidate(Map, Clazz)}
 *   如果 candidateName 有@Primary就返回。这里是会有判断的存在多个候选者有@Primary就抛出异常,所以说一个依赖类型只能有一个@Primary注解标注
 *  `return candidateName;`
 *
 * 没有找到@Primary,在通过beanClass的@Priority(1) { DefaultListableBeanFactory的determineHighestPriorityCandidate(Map, Clazz)}
 *   返回排序值小的结果。这个是为了处理依赖类型是父类,然后容器中有多个子类实现的时候,可以通过@Priority(1) 来决定那个子类优先级搞。
 *  `return candidateName;`
 *      Tips:如果容器存在同一类型的bean有多个,就会报错,因为@Primary()的值都一样,无法确定,只能报错咯
 *
 * 兜底方法,bean实例是resolvableDependencies里面的 或者 beanName是(字段名 或者 方法参数名),也能确定出唯一的候选者
 *  `return candidateName;`
 *
 * 都没得,就``return null``
 * 
 * Tips: 如果依赖类型不是多个的会通过 @Primary -> @Priority -> bean实例是resolvableDependencies里面的 -> beanName是(字段名 或者 方法参数名) 确定出唯一的候选者
 * */

AbstractBeanFactory的evaluateBeanDefinitionString

/**
 * 比如 @Value("的{beanA}")
 *
 * { AbstractBeanFactory的evaluateBeanDefinitionString(String, BeanDefinition)}
 *
 * 使用 `StandardBeanExpressionResolver` 进行计算 { StandardBeanExpressionResolver的evaluate(String, BeanExpressionContext)}
 *      `return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));`
 *
 *      // value 就是 "的{beanA}" ,而beanExpressionParserContext 就是替换掉 的{}。也就是变成了 beanA ,也就是要访问 beanA这个属性
 *      Expression expr = new SpelExpressionParser().parseExpression(value, this.beanExpressionParserContext);
 *      StandardEvaluationContext sec = new StandardEvaluationContext(evalContext);
 *      // 设置属性访问器,就是用来解析 beanA 属性时,会调用这个访问器来获取值
 *      sec.addPropertyAccessor(new BeanExpressionContextAccessor());
 *      // 返回SpEL解析的结果
 *      expr.getValue(sec);
 *
 * 通过属性访问器,读取 beanA 属性值 { BeanExpressionContextAccessor的read(EvaluationContext, Object, String)}
 *      `(BeanExpressionContext) target).getObject(name)` { BeanExpressionContext的getObject(String)}
 *      而 BeanExpressionContext 包装了BeanFactory和Scope。所以`getObject`
 *
 *      if (this.beanFactory.containsBean(key)) {
 * 			return this.beanFactory.getBean(key);
 *      }
 * 		else if (this.scope != null) {
 * 			return this.scope.resolveContextualObject(key);
 *      }
 * 		else {
 * 			return null;
 *      }
 * */

TypeConverterSupport的convertIfNecessary

对依赖进行转换是执行`TypeConverterSupport的convertIfNecessary`。

`TypeConverterSupport` 其实是聚合了 `PropertyEditor` 和 `ConversionService`,这两个才是真正干活的东西。

`ConversionService`真正干活是使用`GenericConverter`,`ConversionService`只是聚合了多个`GenericConverter`而已。

`PropertyEditorRegistrar` 是用来加工 `PropertyEditorRegistry`的,就是用来给其设置`PropertyEditor`的。

扩展`PropertyEditorRegistrar` 是通过 `CustomEditorConfigurer`

`PropertyEditorSupport` 是JDK提供的,`ConversionService`是Spring提供的。


/**
 * 依赖注入时,会拿到TypeConverter { AbstractBeanFactory的getTypeConverter()} ,进行转换
 *      SimpleTypeConverter typeConverter = new SimpleTypeConverter();
 *      // 从容器中获取一个name是 conversionService 的bean
 *      typeConverter.setConversionService(getConversionService());
 *      // 使用BeanFactory的ResourceEditorRegistrar对typeConverter进行加工
 *      // 主要是设置这个属性 { PropertyEditorRegistrySupport的overriddenDefaultEditors}
 *      registerCustomEditors(typeConverter);
 *
 * 执行转换 { TypeConverterSupport的convertIfNecessary(Object, Clazz, MethodParameter)}
 *
 * 拿到自定义的PropertyEditor `PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName);`
 *      先使用 propertyName + requiredType 从这个属性找 { PropertyEditorRegistrySupport的customEditorsForPath}
 *      找不到在使用 requiredType 从这个属性找 { PropertyEditorRegistrySupport的customEditors}
 *      Tips: 可以通过往容器中注入 CustomEditorConfigurer 来扩展这两个属性值
 *
 * 没有自定义的 PropertyEditor 但是有 ConversionService
 *      通过值类型 和 要赋值的对象 类型,判断是否可以转换。 { ConversionService的canConvert(TypeDescriptor, TypeDescriptor)}
 *          其实就是遍历 ConversionService 的属性 { GenericConversionService.Converters} 找到合适的 GenericConverter
 *              { GenericConversionService.Converters的find(TypeDescriptor, TypeDescriptor)}
 *                  { GenericConversionService.Converters的getRegisteredConverter(TypeDescriptor, TypeDescriptor, GenericConverter.ConvertiblePair)}
 *
 *      可以,就使用converter转换 { ConversionService的convert(Object, TypeDescriptor, TypeDescriptor)}
 *
 *      return 装换的结果
 *
 * 执行转换 { TypeConverterDelegate的doConvertValue(Object, Object, Clazz, PropertyEditor)}
 *      没有自定义的PropertyEditor 那就找默认的,先从这里面找 { PropertyEditorRegistrySupport的overriddenDefaultEditors}
 *      找不到在重这里面找 { PropertyEditorRegistrySupport的defaultEditors}
 *
 * return 装换的结果
 *
 * Tips: 具体的转换功能是有 PropertyEditor 和 ConversionService 实现的,而 ConversionService 的具体转换功能是由 GenericConverter 实现的。
 * */