Spring Framework 与 Spring Boot 启动对比
Spring Boot 和 Spring Framework 都是构建现代 Java 企业级应用程序的强大工具。Spring Boot 基于 Spring Framework 之上,旨在简化 Spring 应用的创建和配置过程。尽管两者在启动流程上存在许多相似之处,但 Spring Boot 引入了一些额外的机制和约定,以提高开发效率和应用的可扩展性。以下将详细对比两者的启动流程,强调它们的异同点,并结合源码角度进行说明。
目录
1. 总体架构对比
Spring Framework 是一个用于构建 Java 应用程序的全面框架,提供了丰富的功能模块,如依赖注入(DI)、面向切面编程(AOP)、数据访问、事务管理等。
Spring Boot 则是在 Spring Framework 之上提供了一层抽象,旨在简化 Spring 应用的配置和部署。它通过“约定优于配置”(Convention over Configuration)的原则,自动配置应用所需的组件,并提供嵌入式服务器、生产就绪特性(如监控、健康检查)等。
2. 启动入口点
Spring Framework
在 Spring Framework 中,启动应用通常需要手动创建和配置 ApplicationContext
。例如,使用 AnnotationConfigApplicationContext
:
1 | public class MyApp { |
关键源码:
AnnotationConfigApplicationContext
构造函数- 注册配置类。
- 调用
refresh()
方法初始化上下文。
Spring Boot
Spring Boot 使用 SpringApplication.run
方法作为启动入口,通常位于带有 @SpringBootApplication
注解的主类中:
1 |
|
关键源码:
SpringApplication.run
方法- 创建
SpringApplication
实例。 - 调用
run
方法执行启动流程。
- 创建
对比
方面 | Spring Framework | Spring Boot |
---|---|---|
启动入口 | 手动创建 ApplicationContext |
使用 SpringApplication.run 方法 |
配置方式 | 程序化或 XML 配置 | 自动配置(Auto-Configuration) |
简化程度 | 需要更多的手动配置和初始化步骤 | 提供开箱即用的默认配置,减少配置负担 |
3. 环境准备与配置
Spring Framework
在 Spring Framework 中,环境和属性源的配置通常依赖于手动设置,开发者需要显式地加载属性文件或配置环境:
1 | AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); |
关键源码:
AbstractApplicationContext
的prepareRefresh
方法- 初始化
Environment
和PropertySources
。
- 初始化
Spring Boot
Spring Boot 在启动过程中自动准备环境和属性源,支持多种属性加载机制(如命令行参数、环境变量、配置文件等):
SpringApplication.prepareEnvironment
方法- 创建并配置
Environment
对象。 - 加载默认的配置属性源,包括
application.properties
或application.yml
。
- 创建并配置
关键源码:
SpringApplication.prepareEnvironment
- 使用
SpringApplicationRunListeners
触发EnvironmentPostProcessor
进行环境准备。
- 使用
对比
方面 | Spring Framework | Spring Boot |
---|---|---|
环境配置 | 手动加载和设置环境属性 | 自动加载多种属性源(配置文件、命令行等) |
属性文件命名 | 开发者自行决定(如 app.properties ) |
默认使用 application.properties /application.yml |
多环境支持 | 需要手动配置和管理 | 内置支持多环境配置(如 application-dev.properties ) |
4. 应用上下文创建
Spring Framework
开发者选择特定的 ApplicationContext
实现并手动实例化:
1 | AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); |
关键源码:
AnnotationConfigApplicationContext
构造函数- 注册配置类。
- 调用
refresh()
初始化上下文。
Spring Boot
Spring Boot 根据应用类型自动选择合适的 ApplicationContext
。对于 Web 应用,通常是 AnnotationConfigServletWebServerApplicationContext
:
关键源码:
SpringApplication.createApplicationContext
方法- 根据
WebApplicationType
选择上下文类型(NONE, SERVLET, REACTIVE)。 - 实例化相应的
ApplicationContext
实现。
- 根据
对比
方面 | Spring Framework | Spring Boot |
---|---|---|
上下文选择 | 开发者手动选择具体的 ApplicationContext 实现 |
根据应用类型自动选择上下文类型 |
灵活性 | 高,开发者可自由选择和定制上下文 | 简化选择过程,默认选择最适合的上下文 |
5. Bean 加载与处理
Spring Framework
Bean 的加载主要通过注册配置类或 XML 配置文件,开发者需显式指定:
1 | AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); |
关键源码:
AnnotationConfigApplicationContext.register
方法- 注册注解配置类。
GenericApplicationContext.refresh
方法- 加载和解析 Bean 定义。
Spring Boot
Spring Boot 利用自动配置机制,通过 @EnableAutoConfiguration
注解自动扫描和注册 Bean,无需手动指定配置类:
1 |
|
这里的 @SpringBootApplication
包含了 @EnableAutoConfiguration
,它会自动导入配置类。
关键源码:
AutoConfigurationImportSelector
类- 通过
spring.factories
文件加载所有自动配置类。
- 通过
ConfigurationClassPostProcessor
- 处理
@Configuration
类,解析@Bean
、@ComponentScan
等注解。
- 处理
对比
方面 | Spring Framework | Spring Boot |
---|---|---|
Bean 定义加载方式 | 手动注册配置类或 XML 文件 | 自动扫描和注册,通过自动配置和约定 |
配置文件依赖 | 开发者自行组织和管理 | 依赖 spring.factories 和默认配置类 |
自动配置支持 | 无内置自动配置,需要手动集成 | 内置丰富的自动配置功能,覆盖常见场景 |
6. 后处理器与自动配置
Spring Framework
在 Spring Framework 中,开发者可以手动注册 BeanFactoryPostProcessor
和 BeanPostProcessor
,以定制 Bean 的处理过程:
1 | context.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor()); |
关键源码:
AbstractApplicationContext.refresh
方法- 调用
invokeBeanFactoryPostProcessors
和registerBeanPostProcessors
方法。
- 调用
Spring Boot
Spring Boot 自动注册和配置多个 BeanFactoryPostProcessor
和 BeanPostProcessor
,以实现自动配置和额外功能:
- 自动配置类:通过
@Configuration
类和条件注解(如@ConditionalOnMissingBean
)实现灵活的配置。 - 内置后处理器:如
ConfigurationClassPostProcessor
、AutowiredAnnotationBeanPostProcessor
等,自动处理 Bean 的注入和配置。
关键源码:
SpringApplication.invokeBeanFactoryPostProcessors
方法- 加载并执行所有
BeanFactoryPostProcessor
,包括自动配置相关的处理器。
- 加载并执行所有
- **
AutoConfigurationImportSelector
**:选择并导入自动配置类。
对比
方面 | Spring Framework | Spring Boot |
---|---|---|
后处理器注册 | 手动注册或通过配置文件 | 自动注册内置和自动配置相关的后处理器 |
自动配置机制 | 不存在,需开发者手动集成 | 内置丰富的自动配置机制,通过条件注解实现 |
拓展性 | 高,开发者可自由添加和定制后处理器 | 支持自定义自动配置,但受限于 Spring Boot 的机制 |
7. Web 服务器的启动
Spring Framework
在 Spring Framework 中,作为 Web 应用时,通常需要配置和部署到外部的 Servlet 容器(如 Tomcat、Jetty)。启动过程主要涉及:
- 配置
DispatcherServlet
。 - 部署到外部服务器中运行。
1 | <!-- web.xml 示例 --> |
Spring Boot
Spring Boot 提供了嵌入式的 Web 服务器(如 Tomcat、Jetty、Undertow),无需外部部署。启动时自动初始化并启动嵌入式服务器:
1 |
|
关键源码:
SpringApplication.run
方法- 检测应用类型(Web 或非 Web)。
- 创建
WebServer
(如 Tomcat)并启动。
ServletWebServerApplicationContext
类- 管理嵌入式服务器的生命周期。
对比
方面 | Spring Framework | Spring Boot |
---|---|---|
Web 服务器部署方式 | 需要外部 Servlet 容器进行部署 | 内置嵌入式服务器,无需外部容器 |
配置复杂度 | 较高,需要手动配置和集成外部服务器 | 简化配置,自动集成和启动嵌入式服务器 |
灵活性 | 开发者需自行管理服务器的配置和生命周期 | 自动管理服务器生命周期,开发者可通过配置调整 |
8. 事件发布与生命周期管理
Spring Framework
在 Spring Framework 中,事件发布和生命周期管理主要通过 ApplicationEventPublisher
和 Lifecycle
接口实现。开发者需要手动注册监听器和处理生命周期事件:
1 | context.publishEvent(new CustomEvent(this)); |
Spring Boot
Spring Boot 在 Spring Framework 的基础上,进一步简化和扩展了事件发布和生命周期管理:
- 内置事件监听器:如
ApplicationRunner
、CommandLineRunner
,用于在应用启动后执行特定逻辑。 - 自动触发事件:如
ContextRefreshedEvent
、ApplicationReadyEvent
,提供更多生命周期内的钩子。 - 集成生产就绪特性:通过 Actuator 提供健康检查、指标监控等功能。
关键源码:
SpringApplication.callRunners
方法- 调用所有实现了
CommandLineRunner
和ApplicationRunner
的 Bean。
- 调用所有实现了
SpringApplication.finishRefresh
方法- 发布
ContextRefreshedEvent
和ApplicationReadyEvent
。
- 发布
对比
方面 | Spring Framework | Spring Boot |
---|---|---|
事件发布 | 基于 ApplicationEventPublisher ,需手动发布事件 |
自动发布多个生命周期事件,支持更多钩子 |
生命周期回调 | 需要手动实现和注册监听器 | 提供内置接口(如 CommandLineRunner )和默认监听器 |
生产就绪特性 | 不内置,需要开发者自行集成和实现 | 内置丰富的生产就绪特性,通过 Actuator 提供 |
9. 总结
Spring Boot 和 Spring Framework 在启动流程上有许多共同点,主要基于 Spring Framework 的核心机制。然而,Spring Boot 通过自动配置、嵌入式服务器、简化的启动入口等功能,显著简化了应用的配置和部署过程。以下是两者的关键异同点总结:
相似点
- 基于 Spring 核心:两者都利用 Spring Framework 的核心功能,如 IoC 容器、依赖注入、AOP 等。
- 应用上下文:都使用
ApplicationContext
作为 IoC 容器,负责管理 Bean 的生命周期。 - 事件机制:基于相同的事件发布与监听机制,支持应用生命周期事件的处理。
- Bean 加载与后处理:使用类似的 Bean 定义加载和后处理机制,通过
BeanFactoryPostProcessor
和BeanPostProcessor
扩展功能。
不同点
方面 | Spring Framework | Spring Boot |
---|---|---|
启动方式 | 手动创建和配置 ApplicationContext |
使用 SpringApplication.run 简化启动 |
配置复杂度 | 需要手动配置和管理多个组件 | 提供自动配置,减少手动配置需求 |
Web 服务器部署方式 | 依赖外部 Servlet 容器进行部署 | 内置嵌入式服务器,简化部署流程 |
自动配置支持 | 无内置自动配置机制,需手动集成各类组件 | 内置丰富的自动配置,通过约定简化配置 |
生产就绪特性 | 需要手动集成和实现 | 提供 Actuator 等内置生产就绪功能 |
依赖管理 | 开发者需自行管理和配置依赖关系 | 提供 Starters 统一管理依赖,简化依赖配置 |
结论
Spring Boot 是对 Spring Framework 的重大扩展,旨在简化和加速 Spring 应用的开发过程。通过自动配置、嵌入式服务器、生产就绪特性等功能,Spring Boot 帮助开发者更高效地构建和部署应用,而无需深入处理底层的配置细节。然而,Spring Boot 仍然保留了 Spring Framework 的核心灵活性和扩展性,使其在需要时能够进行高度自定义和优化。理解两者的启动流程和工作机制,有助于开发者在不同场景下选择合适的工具和策略,构建高效、可维护的企业级应用程序。