[SpringBoot进阶]探究 spring.factories 所有写法、执行时机及如何应用
作者介绍大家好我是CodeStats。一个在底层技术上考古了四年的硬核爱好者也是WWAIC全周项目AI编程范式的提出者和实践者。我曾手写过一个完整的 Java Web 框架从 IoC 容器到嵌入式 Tomcat代码全开源也喜欢用通俗的语言拆解 CPU、JVM、操作系统的运行本质。我的技术信条所有高深的技术最后都能用大白话讲清楚。如果讲不清楚说明还没真正理解。 本文你将收获什么本文将围绕五个核心问题系统性地拆解 Spring Boot 的启动流程和spring.factories扩展机制Spring Boot 执行run方法的核心步骤与流程要点spring.factories支持哪些配置类型Spring Boot 如何把启动类注册为 Beanspring.factories如何配置环境进行解密和自定义 Starter启动类注解在 Springrefresh第五步如何被解析一、run方法核心执行流程一句话总结Spring Boot 的启动分为两大阶段——Boot 的准备阶段和 Spring 的刷新阶段启动类在中间的prepareContext被注册为 Bean。1.1 六阶段全景图SpringApplication.run()的执行流程可以分为六个关键阶段阶段方法核心职责① 启动监听listeners.starting()触发启动事件② 准备环境prepareEnvironment()加载配置、执行EnvironmentPostProcessor③ 创建上下文createApplicationContext()创建空ApplicationContext④ 准备上下文prepareContext()注册启动类执行ApplicationContextInitializer⑤ 刷新上下文refreshContext()进入 Spring 12 步完成容器初始化⑥ 启动后处理listeners.started()执行ApplicationRunner/CommandLineRunner1.2 核心要点prepareEnvironment()是 Spring Boot 的地盘加载配置、解密、添加属性源此时ApplicationContext尚未创建。prepareContext()是连接 Boot 与 Spring 的桥梁将启动类注册为 BeanDefinition。refreshContext()是 Spring 的内核进入AbstractApplicationContext.refresh()的 12 步标准流程。二、spring.factories支持的配置类型一句话总结spring.factories是 Spring Boot 的 SPI 配置文件支持 9 种扩展类型覆盖从环境准备到容器刷新的全流程。2.1 完整配置类型清单配置键用途执行时机EnableAutoConfiguration声明自动配置类refresh第5步EnvironmentPostProcessor修改EnvironmentprepareEnvironment()ApplicationContextInitializer上下文初始化前回调prepareContext()ApplicationListener注册生命周期监听器启动早期加载SpringApplicationRunListener监听run全流程run方法各阶段SpringBootExceptionReporter自定义异常报告启动异常时PropertySourceLoader自定义配置文件格式加载配置文件时AutoConfigurationImportFilter过滤自动配置类refresh第5步AutoConfigurationImportListener监听自动配置导入refresh第5步2.2 ⚠️ Spring Boot 3.0 重要变化从Spring Boot 3.0开始EnableAutoConfiguration配置必须迁移到新文件text# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports com.example.config.RedisAutoConfiguration但EnvironmentPostProcessor、ApplicationListener等其他类型仍然使用spring.factories。三、启动类如何被注册为 Bean一句话总结启动类在prepareContext()阶段被手动注册为BeanDefinition从而让 Spring 在后续refresh中能够解析其上的注解。3.1 启动类的身份SpringBootApplication是一个复合注解本质包含三个核心注解javaSpringBootConfiguration // 本质是 Configuration EnableAutoConfiguration // 开启自动配置 ComponentScan // 开启组件扫描因此启动类本身就是一个配置类。3.2 注册时机prepareContext()javaprivate void prepareContext(DefaultApplicationContext context, ...) { context.setEnvironment(environment); applyInitializers(context); // 执行 Initializer listeners.contextPrepared(context); load(context, sources.toArray(new Object[0])); // ★ 注册启动类 listeners.contextLoaded(context); }3.3 核心链路textSpringApplication.run() └── prepareEnvironment() ← 加载配置文件 └── createApplicationContext() ← 创建空容器 └── prepareContext() ← ★ 启动类注册为 BeanDefinition └── refreshContext() ← 进入 Spring 12 步 └── 第5步: ConfigurationClassPostProcessor 解析启动类注解四、环境解密与自定义 Starter 实战一句话总结通过EnvironmentPostProcessor在环境准备阶段完成配置解密通过EnableAutoConfigurationspring.factories实现自定义 Starter 的自动装配。4.1 配置解密EnvironmentPostProcessor执行时机prepareEnvironment()阶段早于ApplicationContext创建和refresh()。javapublic class DecryptEnvPostProcessor implements EnvironmentPostProcessor { Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { String encrypted environment.getProperty(db.password); if (encrypted ! null encrypted.startsWith({cipher})) { String decrypted decrypt(encrypted.substring(8)); // 将解密值放回 Environment MapString, Object map new HashMap(); map.put(db.password, decrypted); environment.getPropertySources() .addFirst(new MapPropertySource(decrypted, map)); } } }properties# META-INF/spring.factories org.springframework.boot.env.EnvironmentPostProcessor\ com.example.processor.DecryptEnvPostProcessor4.2 自定义 Starter 开发项目结构textmy-starter/ └── my-starter-autoconfigure/ ├── MyProperties.java ← ConfigurationProperties ├── MyAutoConfiguration.java ← Configuration Conditional └── resources/META-INF/spring.factories自动配置类javaConfiguration ConditionalOnClass(MyService.class) EnableConfigurationProperties(MyProperties.class) ConditionalOnProperty(prefix my.starter, name enabled, matchIfMissing true) public class MyAutoConfiguration { Bean public MyService myService(MyProperties properties) { return new MyService(properties); } }properties# META-INF/spring.factories org.springframework.boot.autoconfigure.EnableAutoConfiguration\ com.example.config.MyAutoConfiguration五、refresh第5步自动配置的解析一句话总结ConfigurationClassPostProcessor在第5步解析启动类注解AutoConfigurationImportSelector从spring.factories加载并过滤自动配置类。5.1refresh()12 步中的第5步步骤方法核心职责1-4准备阶段创建 BeanFactory预处理5invokeBeanFactoryPostProcessors()★ 执行 BeanFactoryPostProcessor自动配置的核心6-10中间阶段注册 BeanPostProcessor初始化消息源、事件广播器11finishBeanFactoryInitialization()实例化所有单例 Bean12finishRefresh()完成刷新发布事件5.2 第5步的执行顺序先执行BeanDefinitionRegistryPostProcessor可增删改 BeanDefinition后执行BeanFactoryPostProcessor只能修改ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor因此最先被执行。5.3ConfigurationClassPostProcessor解析流程textConfigurationClassPostProcessor ├── 处理 PropertySources ├── 处理 ComponentScan → 扫描业务 Bean └── 处理 Import └── EnableAutoConfiguration └── Import(AutoConfigurationImportSelector.class) └── AutoConfigurationImportSelector.selectImports() ├── SpringFactoriesLoader 扫描 META-INF/spring.factories ├── 读取 EnableAutoConfiguration 键对应的值 ├── Conditional 条件过滤 └── 返回最终生效的自动配置类列表5.4AutoConfigurationImportSelector核心逻辑javaprotected AutoConfigurationEntry getAutoConfigurationEntry(...) { // 1. 获取排除列表EnableAutoConfiguration 的 exclude // 2. 从 spring.factories 加载所有候选自动配置类 // 3. 移除排除项 // 4. Conditional 条件过滤 // 5. 触发 AutoConfigurationImportListener // 6. 返回最终配置类 }六、总结一张图串起全部textSpringApplication.run() │ ├── ① 启动监听 (listeners.starting) │ ├── ② prepareEnvironment() ← ★ EnvironmentPostProcessor 在此执行解密 │ └── 加载 application.yml执行所有 EnvironmentPostProcessor │ ├── ③ createApplicationContext() ← 创建空容器 │ ├── ④ prepareContext() ← ★ 启动类注册为 BeanDefinition │ ├── applyInitializers() ← ★ ApplicationContextInitializer │ └── load(启动类) ← ★ 注册启动类 │ ├── ⑤ refreshContext() ← 进入 Spring 12 步 │ │ │ ├── 第1-4步准备 BeanFactory │ ├── 第5步invokeBeanFactoryPostProcessors() │ │ └── ConfigurationClassPostProcessor │ │ ├── ComponentScan → 扫描业务 Bean │ │ └── Import → EnableAutoConfiguration │ │ └── AutoConfigurationImportSelector │ │ └── 读取 spring.factories → 加载自动配置类 │ ├── 第6-10步注册 BeanPostProcessor初始化事件系统 │ └── 第11步finishBeanFactoryInitialization() → 实例化所有单例 Bean │ └── ⑥ 启动后处理 (listeners.started/running) 如果本文对你有帮助点赞 让更多同学看到收藏⭐ 方便后续查阅关注 获取更多底层技术拆解所有高深的技术最后都能用大白话讲清楚。如果讲不清楚说明还没真正理解。我是CodeStats我们下期见