Spring是如何依赖注入的?
实现依赖注入的注解有Spring提供的@Autowire
,@Value
,以及Java提供的@Resource
,@Inject
源码追踪
这里使用断点大法,对我们自定义的Bean的创建进行观察。
首先介绍自定义的Bean结构,我定义了一个Controller,里面依赖了CommonState和一个Service。
然后我们在AbstractAutowireCapableBeanFactory
的createBean
方法中打上断点。以DEBUG模式运行。
在经过一通其它Bean的创建后终于到我们要观察的Bean了。
step1 resolveBeanClass()
解析MergedBeanDefinition获取我们需要的Bean类对象
step2 resolveBeforeInstantiation()
从名字看到是在实例化之前进行解析。Bean的创建分为Instantiate(实例化)和Initialize(初始化)。
从图中可以看到会调用applyBeanPostProcessorsBeforeInstantiation()
,内部是给InstantiationAwareBeanPostProcessor
的实现类一个机会执行postProcessBeforeInstantiation()
方法
执行完发现结果为null。
注意这里将beforeInstantiationResolved
设置为false了。然后返回null。
step3 doCreateBean()
看到进入createBeanInstance()
,内部走到instantiateBean()
到这一步就很熟悉了,Spring获取到我们Controller的Class对象,然后通过getDeclaredConstructor()
获取构造器,然后使用工具类BeanUtils::instantiateClass()
实例化我们的对象。工具类内部实现就是调用Constructor
的newInstance()
方法反射获得实例。
在完成实例化后,需要将实例化的对象包装成BeanWrapper
对象,并进行initBeanWrapper
操作,个这个Bean增加Converter功能和注册PropertyEditorRegistrar
。
返回到doCreateBean()
调用applyMergedBeanDefinitionPostProcessor()
,内部是给MergedBeanDefinitionPostProcessor
实现类执行postProcessMergedBeanDefinition()
找到AnnotationAutowireBeanPostProcessor
首先调用findAutowiringMetadata()
,内部调用buildAutowiringMetadata()
通过doWithLocalField()
和doWithLocalMethod()
获取依赖的类
这里发现已经找到state
和paperService
两个属性了,同时type就是类型所在的类名
返回findAutowiringMetadata()
,将刚才解析的依赖元数据添加到ConcurrentHashMap
缓存起来。至此,已经完成对指定类的依赖的扫描,并且将依赖做了检查并放进InjectionMetaData
中。
回到doCreateBean()
populateBean()
AutowiredAnnotationBeanPostProcessor
的postProcessProperties()
拿到了之前处理的InjectionMetadata
,然后inject
注入。
进入inject()
获取依赖的类型
在内部会判断已经解析的依赖中是否存在这个type,如果不存在则尝试addCandidateEntry()
将这个type通过getBean()
获取Bean对象,然后返回这个依赖实例。
在经过刚才的依赖对象获取后,接下来就是注入的过程
最终通过反射Field通过setter进行注入。