springboot自动装配原理源码分析

最近在看springboot的自动装配过程,跟着源码分析了一遍,就记下笔记方便自己以后查阅,很多人可能都是从@SpringBootApplication注解直接点进去,然后找到自动装配的两个类去看源码,今天我就从启动开始一步一步分析。

我们在启动main方法的时候,会将我们的启动类的Class作为参数进行传参,spring启动会将我们的启动类作为bean加载进容器中
在这里插入图片描述
deduceFromClasspath方法会从类路径推断出web应用类型,判断是REACTIVE还是SERVLET
在这里插入图片描述
方法加载完毕会将webApplicationType属性赋值为SERVLET
deduceMainApplicationClass方法会推导出主应用程序类,将mainApplicationClass属性赋值为我们的启动类
在这里插入图片描述
接下来会进入到run方法来配置应用程序上下文
会准备加载一下环境等参数
在这里插入图片描述
createApplicationContext方法会创建应用上下文,创建基于注解的web应用程序上下文
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
会创建个一个注解BeanDefinition的读取器
然后调用AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);这个方法,这个方法的作用是 在给定的注册表中注册所有相关的注释后处理器。
在这里插入图片描述
后面我们在beanFactory中看到的这些bean定义都是在这个类里面声明的,像ConfigurationClassPostProcessor,AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor
等的几个后置处理器的都是在这一步声明的,名称类似"org.springframework.context.annotation.internalConfigurationAnnotationProcessor";这样的名字internalxxxx
在这里插入图片描述在这里插入图片描述
在执行完这个方法后,spring容器中会会多出5个bean的定义,就是上面我们所看到的那个名称
在这里插入图片描述
run方法的setApplicationStartup方法就是 设置应用程序启动,
prepareContext方法就是 将我们的启动类加载到spring容器中。

在这里插入图片描述
点进load方法
在这里插入图片描述
最终会来到这个方法,将我们的启动类加入到beanDefinitionMap中
在这里插入图片描述
在执行完prepareContext方法后我们会看到beanDefinitionMap中已经存在我们的启动类了
在这里插入图片描述
接下来会调用refreshContext方法,这个方法很重要,使我们spring容器加载所有bean并完成创建容器的过程,会调用到AbstractApplicationContext类中的refresh方法,我们主要研究
invokeBeanFactoryPostProcessors(beanFactory)这个方法,因为这个方法里有实现自动装配的原理,其他的方法大家可自行百度在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面这3大类基本逻辑都差不多,只是一个是实现了PriorityOrdered接口的,一个是实现Ordered接口的,最后是啥也没实现的,spring将他们做了排序依次加载
在这里插入图片描述
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);这个方法获取BeanDefinitionRegistryPostProcessor类型的bean,拿到一个数组,遍历我们拿到的postProcessorNames,去创建bean。然后再添加到currentRegistryProcessors
在这里插入图片描述
这个时候我们会发现容器中已经存在这个bean了,类型是ConfigurationClassPostProcessor,他实现了BeanDefinitionRegistryPostProcessor这个接口
在这里插入图片描述
接下来我们重点关注
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup())这个方法
在这里插入图片描述
他会遍历当前方法传入的所有的postProcessors,调用postProcessBeanDefinitionRegistry方法,本质就是调用ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry方法
在这里插入图片描述
然后调用processConfigBeanDefinitions方法
调用getBeanDefinitionNames获取已经定义好的bean,然后遍历所有定义好的bean,判断类上是不是有@Configuration,有的话添加到configCandidates中,最终会发现我们的启动类添加进来了
在这里插入图片描述
接下来会解析每一个@Configuration的类,也就是解析我们的启动类
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最终会执行doProcessConfigurationClass方法
在这里插入图片描述
在这个方法中会处理带@PropertySource,@ComponentScan , @Import,@ImportResource, @Bean这些注解的方法或类,自动装配主要是@Import这个注解,我们主要研究这一块
在这里插入图片描述
点进getImports方法中,这个方法会返回所有带@Import的类,并且调用collectImports方法来进行递归获取
在这里插入图片描述
在这里插入图片描述
在我们的启动类上的@SpringBootApplication注解,就包含了两个@Import注解,上面的方法就会递归获取到这两个注解要执行的类
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最终会执行到parse方法的process来处理在这里插入图片描述
执行processGroupImports方法
在这里插入图片描述
在这里插入图片描述
执行getImports方法
在这里插入图片描述
执行AutoConfigurationImportSelector类中的process方法
在这里插入图片描述
然后执行getAutoConfigurationEntry方法
在这里插入图片描述
然后执行getCandidateConfigurations方法获取候选配置,然后就看到了我们熟悉的代码
在这里插入图片描述
在这里插入图片描述
会从META-INF/spring.factories将所有的自动装配类加载出来返回
在这里插入图片描述
在这里插入图片描述
在process中将可以自动装配的类添加到entries中
在这里插入图片描述
在执行完psrse方法后,会执行this.reader.loadBeanDefinitions(configClasses)方法,将自动装配的类和类下面的方法全部加载到beanFactory里的beanDefinitionMap中。
在容器刷新refresh()方法的最后一步finishBeanFactoryInitialization(beanFactory)方法中对所有的bean进行装配
在这里插入图片描述
在这里插入图片描述
以上就是springboot自动装配的原理,这是我自己跟着源码一步一步下来的,可能会稍微有点凌乱,大家自己也可以对源码走一遍流程,有问题可以在下方评论,也可以私信我。

原创不易,谢谢大家。

多多点赞~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值