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生命周期的一部分内容。