Files
interview/questions/10-中间件/Spring Boot核心原理.md
yasinshaw 0e46a367c4 refactor: rename files to Chinese and organize by category
Organized 50 interview questions into 12 categories:
- 01-分布式系统 (9 files): 分布式事务, 分布式锁, 一致性哈希, CAP理论, etc.
- 02-数据库 (2 files): MySQL索引优化, MyBatis核心原理
- 03-缓存 (5 files): Redis数据结构, 缓存问题, LRU算法, etc.
- 04-消息队列 (1 file): RocketMQ/Kafka
- 05-并发编程 (4 files): 线程池, 设计模式, 限流策略, etc.
- 06-JVM (1 file): JVM和垃圾回收
- 07-系统设计 (8 files): 秒杀系统, 短链接, IM, Feed流, etc.
- 08-算法与数据结构 (4 files): B+树, 红黑树, 跳表, 时间轮
- 09-网络与安全 (3 files): TCP/IP, 加密安全, 性能优化
- 10-中间件 (4 files): Spring Boot, Nacos, Dubbo, Nginx
- 11-运维 (4 files): Kubernetes, CI/CD, Docker, 可观测性
- 12-面试技巧 (1 file): 面试技巧和职业规划

All files renamed to Chinese for better accessibility and
organized into categorized folders for easier navigation.

Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-03-01 00:10:53 +08:00

370 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Spring Boot 核心原理
## 问题
1. Spring Boot 的自动配置原理是什么?
2. @SpringBootApplication 注解包含哪些核心注解?
3. Spring Boot 的启动流程是怎样的?
4. 什么是条件注解(@Conditional
5. Spring Boot 如何实现配置文件加载?
6. Spring Boot 的健康检查和监控如何实现?
7. Spring Boot 的 Starter 原理是什么?
---
## 标准答案
### 1. @SpringBootApplication 注解
```java
@SpringBootConfiguration // 1. 配置类
@EnableAutoConfiguration // 2. 自动配置
@ComponentScan // 3. 组件扫描
public @interface SpringBootApplication {
}
```
---
#### **1. @SpringBootConfiguration**
```java
@Configuration // 本质上是 @Configuration
public @interface SpringBootConfiguration {
}
```
**作用**:标记为配置类(等同于 XML 配置文件)
---
#### **2. @EnableAutoConfiguration**
```java
@AutoConfigurationPackage // 自动配置包
@Import(AutoConfigurationImportSelector.class) // 导入自动配置类
public @interface EnableAutoConfiguration {
}
```
**核心**`AutoConfigurationImportSelector`
```java
// 加载 META-INF/spring.factories 中的自动配置类
String[] configurations = SpringFactoriesLoader.loadFactoryNames(
getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader()
);
```
---
#### **3. @ComponentScan**
```java
@ComponentScan(
excludeFilters = { // 排除过滤器
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)
}
)
```
**作用**:扫描 `@Component``@Service``@Repository``@Controller` 等注解
---
### 2. 自动配置原理
#### **核心流程**
```
1. @EnableAutoConfiguration
2. 加载 META-INF/spring.factories
3. 根据 @Conditional 条件注解决定是否加载配置
4. 注册 Bean
```
---
#### **spring.factories 示例**
```properties
# spring-boot-autoconfigure-2.7.0.jar
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
...
```
---
#### **条件注解示例**
```java
@Configuration
@ConditionalOnClass(DataSource.class) // 类路径存在 DataSource
@ConditionalOnMissingBean(DataSource.class) // 容器中不存在 DataSource Bean
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {
@Bean
public DataSource dataSource(DataSourceProperties properties) {
// 创建 DataSource
return properties.initializeDataSourceBuilder().build();
}
}
```
---
### 3. Spring Boot 启动流程
```java
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
```
---
#### **核心步骤**
```
1. 创建 SpringApplication
2. 准备 Environment
3. 打印 Banner
4. 创建 ApplicationContext
5. 刷新 Context加载 Bean
6. 调用 RunnerApplicationRunner、CommandLineRunner
```
---
#### **源码分析**
```java
public SpringApplication(Class<?>... primarySources) {
// 1. 保存主配置类
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// 2. 推断 Web 应用类型SERVLET、REACTIVE、NONE
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 3. 加载 ApplicationContextInitializer
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 4. 加载 ApplicationListener
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 5. 推断主类main 方法所在类)
this.mainApplicationClass = deduceMainApplicationClass();
}
```
---
### 4. 配置文件加载
#### **加载顺序**
```
1. 命令行参数(--server.port=8081
2. Java 系统属性System.getProperties()
3. 操作系统环境变量
4. JAR 外部的 application-{profile}.properties
5. JAR 内部的 application-{profile}.properties
6. JAR 外部的 application.properties
7. JAR 内部的 application.properties
8. @PropertySource
9. 默认属性SpringApplication.setDefaultProperties
```
---
#### **配置文件示例**
```yaml
# application.yml
server:
port: 8080
spring:
profiles:
active: dev
---
spring:
config:
activate:
on-profile: dev
datasource:
url: jdbc:mysql://localhost:3306/dev
---
spring:
config:
activate:
on-profile: prod
datasource:
url: jdbc:mysql://prod-db:3306/prod
```
---
### 5. 自定义 Starter
#### **步骤**
**1. 创建 autoconfigure 模块**
```java
@Configuration
@ConditionalOnClass(HelloService.class)
@EnableConfigurationProperties(HelloProperties.class)
public class HelloAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public HelloService helloService(HelloProperties properties) {
return new HelloService(properties.getMessage());
}
}
```
**2. 创建配置类**
```java
@ConfigurationProperties(prefix = "hello")
public class HelloProperties {
private String message = "Hello World";
// getter/setter
}
```
**3. 创建 spring.factories**
```properties
# META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.hello.HelloAutoConfiguration
```
**4. 使用**
```yaml
# application.yml
hello:
message: Hello Spring Boot
```
```java
@Autowired
private HelloService helloService;
helloService.sayHello(); // 输出Hello Spring Boot
```
---
### 6. Actuator 监控
#### **依赖**
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
```
---
#### **配置**
```yaml
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus # 暴露端点
endpoint:
health:
show-details: always # 显示详细信息
```
---
#### **常用端点**
| 端点 | 说明 | 示例 |
|------|------|------|
| **/actuator/health** | 健康检查 | `{"status":"UP"}` |
| **/actuator/info** | 应用信息 | 版本、描述等 |
| **/actuator/metrics** | 指标 | JVM、HTTP 请求等 |
| **/actuator/prometheus** | Prometheus 格式 | 监控数据 |
| **/actuator/env** | 环境变量 | 配置属性 |
| **/actuator/loggers** | 日志配置 | 日志级别 |
---
#### **自定义健康检查**
```java
@Component
public class DatabaseHealthIndicator implements HealthIndicator {
@Autowired
private DataSource dataSource;
@Override
public Health health() {
try (Connection conn = dataSource.getConnection()) {
if (conn.isValid(1)) {
return Health.up()
.withDetail("database", "MySQL")
.build();
}
} catch (SQLException e) {
return Health.down()
.withException(e)
.build();
}
}
}
```
---
### 7. 阿里 P7 加分项
**深度理解**
- 理解 Spring Boot 的条件装配机制
- 理解 SpringApplication 的启动流程
- 理解 AutoConfigurationImportSelector 的工作原理
**实战经验**
- 有自定义 Starter 的经验
- 有解决自动配置冲突的经验
- 有 Spring Boot 性能优化的经验
**架构能力**
- 能设计可复用的 Spring Boot Starter
- 能设计多环境配置方案
- 能设计微服务监控体系
**技术选型**
- 了解 Spring Boot 2.x vs 3.x 的区别
- 了解 GraalVM Native Image 的支持
- 了解 Quarkus、Micronaut 等替代框架