Files
interview/questions/spring-boot.md
yasinshaw fe2e6dc2f2 feat: add 50 backend interview questions and answers
Generated comprehensive interview preparation materials covering:
- Distributed systems (transactions, locks, ID generation, consistency)
- Database (indexing, sharding, replication, transactions)
- Caching (Redis, cache problems, distributed lock)
- Message queues (RocketMQ, Kafka)
- Concurrency (ThreadLocal, ConcurrentHashMap, thread pools)
- JVM (GC, memory, tuning)
- System design (seckill, short URL, IM, feed, LBS)
- Algorithms (B+ tree, LRU, Red-Black tree, Skip list, Timing wheel)
- Network (TCP/IP, HTTP/HTTPS)
- Security (encryption, SQL injection, XSS)
- Performance tuning
- Design patterns
- Microservices (Spring Boot, Gateway, Service Mesh)
- Container orchestration (Kubernetes, Docker)
- CI/CD, observability

Each file includes:
- Detailed questions
- Comprehensive answers
- Code examples
- Real project experience
- Alibaba P7 level requirements

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:09:50 +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 等替代框架