Spring源码分析--@Autowired依赖注入实现原理

  在平常项目开发中,使用@Autowired注解进行字段注入很常用,本篇就通过Spring源码,重点分析这种方式实现依赖注入的过程。

  本篇Spring源码版本为5.1.7.RELEASE。

  在源码中,关键类是AbstractAutowireCapableBeanFactory,这个类继承AbstractBeanFactory,所以在Spring上下文启动的refresh方法中,invokeBeanFactoryPostProcessors方法会调用其createBean方法。这个类的createBean方法可以作为源码分析的切入点。

  一、AbstractAutowireCapableBeanFactory#createBean

  方法的简化版如下:

   

  二、AbstractAutowireCapableBeanFactory#doCreateBean

  doCreateBean方法是核心部分,简化代码如下:

  

  Spring Bean生命周期的4个阶段,实例化-->属性赋值-->初始化--> 销毁,前三个阶段的源码都在doCreateBean方法中。了解Spring Bean生命周期的时候,也是分析这部分源码。

  依赖注入发生在步骤2--属性赋值阶段,即populateBean方法。

  三、AbstractAutowireCapableBeanFactory#populateBean

  

   populateBean方法中,postProcessProperties方法是依赖处理的关键方法。

   InstantiationAwareBeanPostProcessor是一个接口,@Autowired的依赖注入方式有实现类AutowiredAnnotationBeanPostProcessor,对postProcessProperties方法有重写。所以直接看AutowiredAnnotationBeanPostProcessor。

  四、AutowiredAnnotationBeanPostProcessor#postProcessProperties

  

    这个方法中,findAutowiringMetadata方法的目的是确定当前Bean中标注了@Autowired注解的字段或方法。

  InjectionMetadata.inject方法则是进行依赖注入的过程。

  五、AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata

  

    在AutowiredAnnotationBeanPostProcessor中,有两个内部类AutowiredFieldElement和AutowiredMethodElement。findAutowiringMetadata方法返回的InjectionMetadata对象,其injectedElements属性会被包装为AutowiredFieldElement和AutowiredMethodElement

  六、AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata

  

    buildAutowiringMetadata方法做的事情就是通过反射,寻找当前Bean中哪些字段或者方法标注了@Autowired注解,这些字段和方法就是现在这个Bean需要进行依赖注入的对象。这段代码也可以解释为什么@Autowired不能用在static字段和方法上,底层都对static修饰的字段和方法判断为不处理。

  七、AutowiredFieldElement#inject、AutowiredMethodElement#inject

  metadata.inject执行的是当前内部类AutowiredFieldElement和AutowiredMethodElement的inject方法。以AutowiredFieldElement为例,代码如下:

   

    可以看到,其实Spring的依赖处理过程主要是通过DefaultListableBeanFactory#resolveDependency方法来操作。

  源码当中的调用流程为:resolveDependency-->doResolveDependency-->findAutowireCandidates-->addCandidateEntry-->DependencyDescriptor#resolveCandidate-->BeanFactory#getBean

  源码中调用流程很长,有很多的判断逻辑,但最终目的是获取到依赖对象,再通过反射进行依赖注入。

  @Autowired进行依赖注入的流程整体就是如此,这部分源码本身也是Spring Bean生命周期的一部分内容。

   

 

posted @ 2023-05-04 09:54  阳光、大地和诗歌  阅读(150)  评论(0编辑  收藏  举报