一、 Spring Boot 面试题2021 核心考点概览
在2021年的Java技术面试中,Spring Boot 面试题2021 占据了极大的比重。面试官不再仅仅关注XML配置的使用,而是更多地考察开发者对Spring Boot“约定优于配置”设计理念的理解,以及底层自动配置原理的掌握程度。以下我们将通过选项卡的形式,详细拆解几个最热门的面试话题。
1.1 什么是Starter?为什么要使用它?
Starter 是Spring Boot的核心概念之一。在传统的Spring应用中,我们需要手动引入大量的依赖包,并配置它们之间的版本兼容性。而Spring Boot通过Starter机制,将常用的依赖组合在一起,形成一个“起步依赖”。
- ⚡ 简化依赖管理:只需引入一个Starter(如spring-boot-starter-web),即可自动引入Tomcat、Spring MVC等所有必要依赖。
- ⚡ 版本仲裁:Spring Boot父工程统一管理了常用依赖的版本,避免了版本冲突。
- ⚡ 场景化开发:针对不同场景(如Redis、JPA、Security)提供专门的Starter,开箱即用。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
1.2 自动配置原理深度解析
自动配置是Spring Boot最迷人的地方。其核心入口是 @SpringBootApplication 注解,该注解组合了 @EnableAutoConfiguration。
- ① 导入自动配置类:通过
@Import(AutoConfigurationImportSelector.class)导入所有候选配置类。 - ② 加载META-INF:从
spring-boot-autoconfigure包下的META-INF/spring.factories文件中读取所有配置类全限定名。 - ③ 条件装配:利用
@ConditionalOnClass、@ConditionalOnMissingBean等注解,判断类路径下是否存在特定类或容器中是否已有特定Bean,从而决定是否加载配置。
面试中常问:“如何禁用某个自动配置?” 答案是使用 spring.autoconfigure.exclude 属性或在启动类上添加 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})。
1.3 SpEL表达式在配置中的应用
Spring Expression Language (SpEL) 允许在XML或注解配置中嵌入表达式。在Spring Boot中,它常用于动态获取配置值。
@Value("${server.port:8080}")
private int port;
上述代码中,如果 server.port 未配置,则默认使用8080。这是SpEL结合属性占位符的典型用法。此外,SpEL还支持方法调用、对象属性访问等高级功能,在复杂业务逻辑配置中非常有用。
二、 网友们还关心的 Spring Boot 面试题2021 高频问答
基于对各大技术社区和招聘网站数据的分析,我们整理了以下5个被问得最多的问题,并提供了深度解答。
Q1: Spring Boot 和 Spring Cloud 有什么区别?
Spring Boot 是用于快速构建单个微服务应用的框架,关注于“快速开发”和“约定优于配置”。而 Spring Cloud 是基于 Spring Boot 的一整套微服务解决方案,关注于分布式系统的协调,如服务注册发现、配置中心、网关、负载均衡等。简而言之,Spring Boot 是构建微服务的基础,Spring Cloud 是管理微服务的架构。
Q2: 如何自定义 Starter?
1. 创建自动配置类,使用 @Configuration 和条件注解。
2. 创建自动配置属性类,用于绑定 application.yml 中的配置。
3. 在 META-INF/spring.factories 文件中注册自动配置类:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\n com.example.MyAutoConfiguration。
Q3: Spring Boot 启动流程是怎样的?
1. 创建 SpringApplication 实例。
2. 推断应用类型(Servlet/Reactive)。
3. 加载 ApplicationContextInitializer 和 ApplicationListener。
4. 调用 run() 方法,创建并刷新 ApplicationContext。
5. 执行 ApplicationRunner 和 CommandLineRunner 的 run() 方法。
Q4: 如何实现热部署?
最常用的是 spring-boot-devtools。它通过改变类加载器实现:一个类加载器加载不变的类(如第三方库),另一个加载变化的类(如自己的代码)。当检测到类文件变化时,重启应用上下文。注意:它不是真正的JIT热替换,而是重启容器,速度很快。
Q5: Spring Boot 如何集成多数据源?
1. 配置多个数据源Bean,使用不同的 @Primary 或 @Qualifier 标识。
2. 为每个数据源创建独立的 SqlSessionFactory 和 TransactionManager。
3. 在Mapper接口上指定对应的 @MapperScan 包路径,确保Mapper与数据源匹配。
Q6: 配置文件加载优先级?
优先级从高到低:
1. 命令行参数 (--server.port=8081)
2. JNDI属性
3. JVM系统属性
4. 操作系统环境变量
5. 不同位置的application.properties/yml (jar包外application-dev.yml > jar包内application-dev.yml > jar包外application.yml > jar包内application.yml)
6. @PropertySource注解
三、 Spring Boot 技术演进与版本关注点
了解Spring Boot的版本迭代,有助于在面试中展现对技术趋势的敏感度。以下是几个关键版本的核心特性:
全面拥抱Java 8+ 与响应式编程
最低要求Java 8,引入WebFlux模块支持响应式编程,集成Spring Framework 5.0,支持函数式Web框架。
性能优化与Actuator增强
引入Micrometer指标监控,支持OpenTracing,优化了JVM元空间使用,改进了Docker构建支持。
容器镜像与Actuator Health
2.2引入Actuator Health Endpoint,支持自定义HealthIndicator。2.3引入基于Gradle的构建支持,优化了Tomcat线程池配置,支持HTTP/3(实验性)。
Jakarta EE 迁移与配置元数据
2.4开始迁移到Jakarta EE命名空间(javax -> jakarta),引入配置元数据生成机制,便于IDE提示。2.5进一步简化配置,移除旧版弃用API,提升启动速度。
四、 Actuator 监控与管理实战
在生产环境中,监控Spring Boot应用的健康状态至关重要。Actuator提供了丰富的端点(Endpoints)来暴露应用内部信息。
| 端点名称 | 描述 | 是否默认暴露 | 示例路径 |
|---|---|---|---|
| beans | 列出应用中的所有Spring Bean | 否 | /actuator/beans |
| conditions | 自动配置报告,显示哪些配置生效,哪些未生效及原因 | 否 | /actuator/conditions |
| env | 暴露Spring的ConfigurableEnvironment属性 | 否 | /actuator/env |
| health | 显示应用健康信息(UP/DOWN) | 是 | /actuator/health |
| info | 显示应用信息(如构建版本、描述) | 否 | /actuator/info |
| metrics | 当前指标信息,如内存使用、线程数等 | 否 | /actuator/metrics |
| loggers | 查询和修改日志级别 | 否 | /actuator/loggers |
如何自定义健康指示器?
通过实现 HealthIndicator 接口,可以自定义健康检查逻辑,例如检查数据库连接、Redis连通性或第三方API状态。
@Component
public class MyCustomHealthIndicator implements HealthIndicator {
@Override
public Health health() {
// 检查逻辑
if (isServiceAvailable()) {
return Health.up().withDetail("service", "available").build();
} else {
return Health.down().withDetail("service", "unavailable").build();
}
}
}
五、 缓存抽象与声明式事务
5.1 缓存抽象 (@Cacheable, @CacheEvict)
Spring Boot 提供了统一的缓存抽象,支持Redis、Ehcache、Caffeine等多种缓存实现。只需引入相应依赖并启用 @EnableCaching,即可使用注解管理缓存。
@Service
public class UserService {
@Cacheable(value = "users", key = "#id")
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
@CacheEvict(value = "users", key = "#id")
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
}
5.2 声明式事务 (@Transactional)
Spring Boot 默认开启声明式事务。通过 @Transactional 注解,可以方便地管理数据库事务。
- ⚠️ 注意事项:
- 1. 事务方法必须是public的。
- 2. 自调用失效:同一类中方法A调用方法B,B的事务不生效(因为绕过了代理)。
- 3. 默认只在RuntimeException时回滚,可通过
rollbackFor指定其他异常。
六、 微服务生态与 Spring Boot 面试题2021 拓展
随着微服务架构的普及,Spring Boot 面试题2021 也常常涉及与微服务组件的集成。以下是网友普遍关心的周边知识:
如何优化 Spring Boot 应用性能?
在面试中,性能优化也是一个高频话题。可以从以下几个方面回答:
- ① JVM调优:合理设置堆内存大小,选择合适的GC算法(如G1 GC)。
- ② 连接池优化:调整数据库连接池(HikariCP)和Redis连接池的参数。
- ③ 异步处理:使用
@Async或消息队列(RabbitMQ/Kafka)处理耗时任务。 - ④ 缓存策略:合理使用本地缓存(Caffeine)和分布式缓存(Redis)。
- ⑤ 静态资源优化:启用Gzip压缩,使用CDN加速。
总结
2021年的 Spring Boot 面试题2021 不仅考察基础语法和API使用,更注重对底层原理、架构设计以及工程化实践的理解。希望本文整理的考点和深度解析,能帮助你构建完整的知识体系,顺利通过面试。记住,理解“约定优于配置”背后的思想,比死记硬背API更重要。