Autowire的实现原理分析,以及Spring如何处理一个Bean的注入

Spring是如何依赖注入的?

实现依赖注入的注解有Spring提供的@Autowire@Value,以及Java提供的@Resource@Inject
在这里插入图片描述

源码追踪

这里使用断点大法,对我们自定义的Bean的创建进行观察。
首先介绍自定义的Bean结构,我定义了一个Controller,里面依赖了CommonState和一个Service。
在这里插入图片描述
然后我们在AbstractAutowireCapableBeanFactorycreateBean方法中打上断点。以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()实例化我们的对象。工具类内部实现就是调用ConstructornewInstance()方法反射获得实例。
在这里插入图片描述
在完成实例化后,需要将实例化的对象包装成BeanWrapper对象,并进行initBeanWrapper操作,个这个Bean增加Converter功能和注册PropertyEditorRegistrar
在这里插入图片描述
返回到doCreateBean()
在这里插入图片描述
调用applyMergedBeanDefinitionPostProcessor(),内部是给MergedBeanDefinitionPostProcessor实现类执行postProcessMergedBeanDefinition(),其中要注意的是CommonAnnotationBeanPostProcessor这个类是用来处理Java提供的依赖注入注解比如@ResourceAutowireAnnotationBeanPostProcessor是用来处理Spring提供的@Autowire,@Value等注解的。
在这里插入图片描述
在这里插入图片描述
找到AnnotationAutowireBeanPostProcessor
在这里插入图片描述
在这里插入图片描述
首先调用findAutowiringMetadata(),内部调用buildAutowiringMetadata()
在这里插入图片描述
通过doWithLocalField()doWithLocalMethod()获取依赖的类
在这里插入图片描述
这里发现已经找到statepaperService两个属性了,同时type就是类型所在的类名
在这里插入图片描述
在这里插入图片描述
返回findAutowiringMetadata(),将刚才解析的依赖元数据添加到ConcurrentHashMap缓存起来。至此,已经完成对指定类的依赖的扫描,并且将依赖做了检查并放进InjectionMetaData中。

回到doCreateBean()

populateBean()

在这里插入图片描述
AutowiredAnnotationBeanPostProcessorpostProcessProperties()
在这里插入图片描述
拿到了之前处理的InjectionMetadata,然后inject注入。
在这里插入图片描述
进入inject()
在这里插入图片描述
在这里插入图片描述
获取依赖的类型
在这里插入图片描述
在这里插入图片描述
在内部会判断已经解析的依赖中是否存在这个type,如果不存在则尝试addCandidateEntry()将这个type通过getBean()获取Bean对象,然后返回这个依赖实例。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在经过刚才的依赖对象获取后,接下来就是注入的过程
在这里插入图片描述
在这里插入图片描述
最终通过反射Field通过setter进行注入。
在这里插入图片描述

总结

在这里插入图片描述

发布了23 篇原创文章 · 获赞 8 · 访问量 2346

猜你喜欢

转载自blog.csdn.net/Crazy_xym/article/details/105019886