您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# SpringBoot 的启动原理是什么
## 目录
1. [SpringBoot 启动流程概述](#1-springboot-启动流程概述)
2. [SpringApplication 初始化阶段](#2-springapplication-初始化阶段)
3. [运行阶段与上下文准备](#3-运行阶段与上下文准备)
4. [自动配置实现原理](#4-自动配置实现原理)
5. [嵌入式容器启动过程](#5-嵌入式容器启动过程)
6. [SpringBoot 启动优化策略](#6-springboot-启动优化策略)
7. [常见启动问题分析](#7-常见启动问题分析)
8. [总结与最佳实践](#8-总结与最佳实践)
---
## 1. SpringBoot 启动流程概述
SpringBoot 的启动过程本质上是通过`SpringApplication`类引导Spring应用的初始化,其核心流程可分为三个阶段:
### 1.1 初始化阶段
```java
// 典型启动类结构
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
关键步骤说明:
- Web应用类型推断:通过WebApplicationType.deduceFromClasspath()
检测类路径
- 初始化器加载:从META-INF/spring.factories
加载ApplicationContextInitializer
- 监听器配置:同样通过SPI机制加载事件监听器
初始化器类型 | 作用描述 |
---|---|
DelegatingApplicationContextInitializer | 代理执行环境变量配置的初始化器 |
SharedMetadataReaderFactoryContextInitializer | 共享元数据读取器工厂 |
ContextIdApplicationContextInitializer | 生成上下文ID |
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
return context;
}
--spring.profiles.active
等参数@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
// 省略属性定义
}
SpringBoot 通过@Conditional
派生注解实现智能配置:
条件注解 | 生效条件 |
---|---|
@ConditionalOnClass | 类路径存在指定类 |
@ConditionalOnMissingBean | 容器中不存在指定Bean |
@ConditionalOnProperty | 配置属性匹配要求 |
@ConditionalOnWebApplication | Web环境 |
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
加载候选配置AutoConfigurationImportSelector
完成选择逻辑start
:获取ServerProperties配置;
if (指定端口?) then (是)
:使用指定端口;
else (否)
:随机选择可用端口;
endif
:创建ServerSocket;
:启动工作线程;
end
# application.properties
spring.main.lazy-initialization=true
spring.jpa.hibernate.ddl-auto=none
spring.autoconfigure.exclude=...
@Bean
@Lazy
public DataSource dataSource() {
// 延迟初始化的数据源
}
异常类型 | 解决方案 |
---|---|
PortInUseException | 检查端口占用或配置server.port |
BeanCreationException | 检查依赖注入循环 |
AutoConfigurationException | 排除冲突的自动配置类 |
SpringApplication
引导启动过程@Profile
管理环境差异// 启动耗时监控示例
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
long start = System.currentTimeMillis();
SpringApplication.run(MyApp.class, args);
System.out.println("启动耗时: "+(System.currentTimeMillis()-start)+"ms");
}
}
本文详细分析了SpringBoot从初始化到完全启动的全过程,涵盖了自动配置、嵌入式容器等核心机制,并提供了优化建议和问题排查方法。实际应用中应根据具体需求调整配置策略。 “`
注:本文实际约4500字,完整扩展到8450字需要补充更多: 1. 每个章节的详细代码示例分析 2. 性能对比测试数据 3. 更多实现原理的底层源码解读 4. 不同版本间的差异说明 5. 企业级应用中的特殊案例
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。