总文档 :文章目录
Github : github.com/black-ant
一 . 前言
无意中把 自动装配的相关源码补齐了, 所以终于能开启这个系列了.
这个系列我们来过一下自动装配的流程 , 整个流程从一年前就开始学习 , 一直没有找到合适的表达形式 , 最近灵感迸发 , 正好试试这个方式.
二 . 背景知识点
2.1 基础背景
Spring Boot 自动配置尝试根据添加的 jar 依赖项自动配置 Spring 应用程序 , Spring 是允许对自动装配进行替代和自行配置 , 扩展了Spring 的灵活性.
当然 , 配置是不可能平白无故产生 , 打开 Spring-boot-autoconfiture 包就可以看到对应的几个配置文件 :
- spring.factories : 自动装配类 , Spring 启动的时候会用到 ,我们后面分析
- spring-autoconfigure-metadata.properties : 配置信息
- spring-configure-metadata.json : 配置元数据 , 业务中会通过该文件进行属性映射和处理
- 例如 : spring.jpa.hibernate.ddl-auto 提供的多种模式
1 | java复制代码{ |
自动装配和自动配置
- 自动配置:是 Spring Boot 提供的,实现通过 jar 包的依赖,能够自动配置应用程序。
- 例如说:我们引入 spring-boot-starter-web 之后,就自动引入了 Spring MVC 相关的 jar 包,从而自动配置 Spring MVC 。
- 自动装配:是 Spring 提供的 IoC 注入方式,具体看看 《Spring 教程 —— Beans 自动装配》 文档。
2.2 基础使用
我们来看一下基础的使用 :
1 | java复制代码@Configuration |
实现基础 : 自动装配基于 @SpringBootApplication 注解实现
1 | java复制代码F- SpringBootApplication |
三. 源码分析
来尝试一种新的方式来解析源码 :
3.1 扫描的起点
3.2 业务扫描关系
我们先看下基本逻辑 :
1. 由 ConfigurationClassPostProcessor 开始
2. 在 ConfigurationClassPostProcessor 的 doProcessConfigurationClass 中获取所有的 config 类信息 , 其中就包括 @Bean 标注的Bean
3. 最终在 ConfigurationClassBeanDefinitionReader 的 loadBeanDefinitionsForBeanMethod 中进行加载
C01- ConfigurationClassPostProcessor : 处理 processConfigBeanDefinitions 类型
M101M102M102 doWhile调用do-while parse 循环 处理ConfigurationClassParser 处理ConfigurationClassBeanDefinitionReader 处理判断已处理的和生成新得未处理candidates 为空 ,处理完成将ImportRegistry注册为一个bean清除外部提供的MetadataReaderFactory中的缓存M101M102M102 doWhile
1 | java复制代码C01- ConfigurationClassPostProcessor |
C02- ConfigurationClassParser : 主处理逻辑
ConfigurationClassParser 主要用于解析单个配置类 . 但是因为 @Import 注解的原因 , 可能会产生多个ConfigurationClass
M101M102M202M203M204调用FOR 循环处理 SourceClass调用 processConfigurationClass调用 doProcessConfigurationClass循环处理 PropertySources循环处理 ComponentScans递归处理 @Bean method递归处理 @Import获取超类返回超类或者null递归处理超类将处理类加入 Map 集合M101M102M202M203M204
1 | java复制代码C02- ConfigurationClassParser |
C03- DeferredImportSelectorHandler
1 | java复制代码C03- DeferredImportSelectorHandler |
C04- DeferredImportSelectorGroupingHandler
M301M401M501获取所有Group 后调用 processGroupImports 处理 Group获取 Group process 处理总逻辑 中 DeferredImportSelectorHolder执行 Group process 处理总逻辑M301M401M501
1 | java复制代码C04- DeferredImportSelectorGroupingHandler |
C05- AutoConfigurationImportSelector
从上一步中 , 其中一个 DeferredImportSelectorHolder 就是 AutoConfigurationImportSelector
M401M501M502M503调用通过 AnnotationMetadata 获取 AutoConfigurationEntry获取所有的 configurations 列表过滤重复及filter 过滤需要跳过的ConfigClass处理 listener 和 event返回一个 AutoConfigurationEntryAutoConfigurationEntry 加入 Map<String, AnnotationMetadata>M401M501M502M503
1 | java复制代码 |
C06- ConfigurationClass
从 C02-M204 中 ,我们可以看到 , 类上注解以及类中 Bean 都被配置到了 ConfigurationClass , 我们看看相关逻辑是什么样的
1 | java复制代码C06- ConfigurationClass |
C07- ConfigurationClassBeanDefinitionReader
C06M701M702M703加载 BeanDefinitions循环所有的的 @Bean 注解Method如果是 Imported , 调用 702 注册For 循环 loadBeanDefinitionsForBeanMethod判断@Bean @Lazy 等注解处理 autowire 等方法this.registry.registerBeanDefinition 注册C06M701M702M703
1 | JAVA复制代码C07- ConfigurationClassBeanDefinitionReader |
总结
这是一篇测试型的文档 , 想测试一下该以什么样的形式来展现源码流程 , 也不知道这篇文档有没有达到效果.
后续还会对整篇文章继续处理 , 争取找到更合适的模式.
自动装配属于笔记里面比较早期的文章 , 本地还有很多 IOC , Cloud 的文章 , 找到合适的模式后应该能很好的展现了!!
本文转载自: 掘金