一、核心概念
1. SpringApplication
类
Spring Boot 启动的核心类。它封装了应用上下文创建、环境准备、自动配置、内嵌服务器启动等逻辑。
2. @SpringBootApplication
注解
这是启动类上的关键注解,它是一个组合注解,等价于:
@Configuration // 标识为配置类
@EnableAutoConfiguration // 启用自动配置
@ComponentScan // 扫描当前包及其子包下的组件
3. 应用上下文(ApplicationContext)
Spring 容器的核心,负责管理 Bean 的生命周期、依赖注入、事件发布等。
4. 自动配置(Auto-configuration)
Spring Boot 根据 classpath 中的依赖自动配置 Bean,例如:
- 存在
spring-boot-starter-web
→ 自动配置 Tomcat + Spring MVC - 存在
spring-boot-starter-data-jpa
→ 自动配置 DataSource、EntityManager
5. 内嵌服务器(Embedded Server)
默认内嵌 Tomcat,也可替换为 Jetty 或 Undertow,无需部署 WAR 包。
二、Spring Boot 启动流程(详细步骤)
启动流程从 main
方法开始,以下是超详细步骤分解:
步骤 1:调用 SpringApplication.run()
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
步骤 2:创建 SpringApplication
实例
- 设置主配置类(
primarySource = DemoApplication.class
) - 推断应用类型(Web Application、Reactive、Non-Web)
- 加载
ApplicationContextInitializer
和ApplicationListener
- 设置主类(用于推断 package)
📌 此时还未创建容器。
步骤 3:执行 run()
方法(核心流程)
3.1 创建并配置 Environment
(环境)
- 创建
StandardServletEnvironment
(Web 应用) - 加载配置源:
application.properties
/application.yml
- 命令行参数(
--server.port=8081
) - 系统属性、环境变量
- 激活 Profile(
spring.profiles.active=dev
)
3.2 创建 ApplicationContext
根据应用类型创建:
AnnotationConfigServletWebServerApplicationContext
(Web)AnnotationConfigReactiveWebServerApplicationContext
(WebFlux)AnnotationConfigApplicationContext
(非 Web)
3.3 prepareContext()
:准备上下文
- 将
Environment
关联到ApplicationContext
- 调用
ApplicationContextInitializer
(如有) - 注册主配置类(
DemoApplication
)为 Bean - 扫描组件(
@ComponentScan
)
3.4 refreshContext()
:刷新上下文(Spring 核心)
这是 Spring 框架的核心流程,包括:
invokeBeanFactoryPostProcessors
- 执行
BeanFactoryPostProcessor
,如ConfigurationClassPostProcessor
- 解析
@Configuration
、@Import
、@ComponentScan
等注解 - 关键:处理
@EnableAutoConfiguration
- 读取
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件(Spring Boot 3.x) - 或
spring.factories
(Spring Boot 2.x) - 加载所有自动配置类(如
WebMvcAutoConfiguration
)
- 读取
- 执行
registerBeanPostProcessors
注册 Bean 后置处理器(如AutowiredAnnotationBeanPostProcessor
)finishBeanFactoryInitialization
- 实例化所有非懒加载的单例 Bean
- 执行
@Bean
方法 - 依赖注入(
@Autowired
) - 调用
InitializingBean.afterPropertiesSet()
和@PostConstruct
finishRefresh()
- 发布
ContextRefreshedEvent
- 启动内嵌 Web 服务器(Tomcat/Jetty)
- 发布
3.5 启动内嵌服务器
- 创建
ServletWebServerFactory
(如TomcatServletWebServerFactory
) - 创建 Tomcat 实例
- 将 Spring MVC 的
DispatcherServlet
注册到 Tomcat - 启动 Tomcat,监听端口(默认 8080)
3.6 执行 ApplicationRunner
和 CommandLineRunner
- 按
@Order
或实现Ordered
接口顺序执行 - 用于启动后执行自定义逻辑(如数据初始化)
3.7 发布 ApplicationReadyEvent
- 标志应用已准备好接收请求
- 可监听此事件做最后处理
三、常见错误与解决方案
错误现象 | 原因 | 解决方案 |
---|---|---|
APPLICATION FAILED TO START |
配置错误、端口占用、Bean 冲突 | 查看日志定位具体原因 |
Port 8080 already in use |
端口被占用 | 修改 server.port=8081 或关闭占用进程 |
NoSuchBeanDefinitionException |
Bean 未注册 | 检查 @Component , @Service 是否在扫描路径下 |
Failed to configure a DataSource |
缺少数据库配置 | 添加 spring.datasource.url 或使用 @SpringBootTest |
Circular dependency |
循环依赖 | 使用 @Lazy 或重构设计 |
ClassNotFoundException: Servlet |
缺少 Web 依赖 | 确保添加 spring-boot-starter-web |
四、注意事项
- 主类位置:
@SpringBootApplication
类应放在根包下,确保@ComponentScan
能扫描到所有组件。 - 自动配置冲突:避免手动配置与自动配置 Bean 冲突(如手动定义
DataSource
但未排除DataSourceAutoConfiguration
)。 - Profile 激活:
- 优先级:命令行 > 环境变量 >
application.properties
- 多 Profile:
spring.profiles.active=dev,metrics
- 优先级:命令行 > 环境变量 >
- DevTools 影响:
- 启用热部署,但会禁用缓存(如 Thymeleaf 缓存)
- 生产环境不要包含
spring-boot-devtools
- 日志级别:生产环境设置
logging.level.root=WARN
,避免日志过多。
五、使用技巧
1. 自定义 Banner
在 src/main/resources/
下创建 banner.txt
,内容将显示在启动日志顶部。
2. 启动时执行代码
@Component
public class StartupRunner implements CommandLineRunner {
@Override
public void run(String... args) {
System.out.println("应用启动完成,执行初始化任务...");
}
}
3. 条件化配置
@Configuration
@ConditionalOnProperty(name = "app.feature.enabled", havingValue = "true")
public class FeatureConfig { ... }
4. 排除自动配置
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
5. 监听启动事件
@Component
public class StartupListener {
@EventListener
public void handleContextRefresh(ContextRefreshedEvent event) {
System.out.println("上下文刷新完成");
}
}
六、最佳实践与性能优化
最佳实践
分层清晰:
- Controller → Service → Repository
- 使用
@Controller
,@Service
,@Repository
明确职责
异常统一处理:
@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity<String> handle(Exception e) { return ResponseEntity.status(500).body(e.getMessage()); } }
配置外化:
- 敏感信息使用环境变量:
SPRING_DATASOURCE_PASSWORD=xxx
- 多环境配置:
application-dev.yml
,application-prod.yml
- 敏感信息使用环境变量:
健康检查:
- 添加
spring-boot-starter-actuator
- 访问
/actuator/health
监控应用状态
- 添加
日志结构化:
- 使用 JSON 格式日志,便于 ELK 收集
- 配置:
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n
性能优化建议
优化项 | 配置示例 | 说明 |
---|---|---|
Gzip 压缩 | server.compression.enabled=true |
减少响应体积 |
连接池优化 | spring.datasource.hikari.maximum-pool-size=20 |
避免连接不足 |
JVM 调优 | -Xms512m -Xmx1024m -XX:+UseG1GC |
生产环境设置堆大小和 GC |
缓存 | 使用 @Cacheable + Redis |
减少数据库压力 |
异步处理 | @Async + @EnableAsync |
提升吞吐量 |
Actuator 监控 | management.endpoints.web.exposure.include=* |
实时监控性能指标 |
七、扩展:Spring Boot 3.x 新特性(基于 Java 17+)
- Jakarta EE 9+:包名从
javax.*
→jakarta.*
- GraalVM 原生镜像支持:通过
native-image
编译为原生可执行文件,启动更快、内存更小。 - 新的自动配置机制:使用
spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
替代spring.factories
。 - Micrometer 2.0:更强大的指标监控。
总结
Spring Boot 启动流程虽复杂,但其设计精巧,通过自动配置和约定优于配置原则极大简化了开发。掌握其核心流程,有助于:
- 快速定位启动问题
- 理解 Bean 加载顺序
- 优化应用性能
- 实现高级定制(如自定义 Starter)
✅ 动手实践建议:
- 创建一个最简项目,逐步添加依赖观察启动日志变化
- 使用
--debug
参数启动,查看自动配置报告- 尝试排除某个 AutoConfiguration,观察行为变化