Spring Boot框架问题
一、 基础与核心原理
1. 为什么要用 Spring Boot?它和传统的 Spring 框架有什么区别?
-
考察点: 对框架演进的理解。
-
回答要点:
-
简化配置: Spring 需要配置大量的 XML 或 Java Config,而 Spring Boot 通过 自动配置 大大减少了配置量。
-
快速开发: 内嵌了 Tomcat、Jetty 等 Servlet 容器,无需打 WAR 包部署,可以直接
java -jar运行。 -
无代码生成和 XML 配置: 核心是“约定大于配置”。
-
生态整合: 提供了丰富的 Starter,无缝整合各种中间件(Redis、MQ、DB等)。
-
2. Spring Boot 的自动配置原理是什么?(这是最高频的问题之一)
-
考察点: 源码阅读能力和底层原理。
-
回答要点:
-
入口是
@SpringBootApplication注解,它组合了@EnableAutoConfiguration。 -
@EnableAutoConfiguration通过@Import(AutoConfigurationImportSelector.class)导入配置。 -
AutoConfigurationImportSelector会去读取META-INF/spring.factories文件(Spring Boot 2.7+ 之后逐步迁移到META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports)。 -
文件中列出了所有的自动配置类(如
RedisAutoConfiguration)。 -
这些配置类通过
@Conditional系列注解(如@ConditionalOnClass、@ConditionalOnMissingBean)进行条件判断,只有当满足条件(例如引入了 Redis 的 jar 包)时,配置才会生效。
-
3. @SpringBootApplication 注解由哪些注解组成?
-
考察点: 基础细节。
-
回答要点:
它是一个复合注解,主要由以下三个组成:-
@SpringBootConfiguration:本质是@Configuration,表明这是一个配置类。 -
@EnableAutoConfiguration:开启自动配置。 -
@ComponentScan:默认扫描当前包及其子包下的组件。
-
二、 配置与属性
4. application.properties 和 application.yml 的区别?
-
考察点: 基础使用。
-
回答要点:
-
properties是键值对格式,平铺结构;yml是 YAML 语言,树形结构,对层次感强的配置更友好(如数据库、多环境配置)。 -
yml不支持@PropertySource注解加载(通常需要自定义PropertySourceFactory)。
-
5. 如何实现多环境配置?
-
考察点: 实际工程能力。
-
回答要点:
-
使用
application-{profile}.yml的命名方式,例如application-dev.yml、application-prod.yml。 -
在
application.yml中通过spring.profiles.active=dev来激活指定环境。 -
也可以在部署时通过启动参数指定:
java -jar app.jar --spring.profiles.active=prod。
-
6. 如何修改 Spring Boot 内嵌 Tomcat 的端口或参数?
-
考察点: 运维配置。
-
回答要点:
-
最直接的方式:在配置文件中写
server.port=8081。 -
如果涉及到更底层的配置(如连接数、线程池),可以使用
WebServerFactoryCustomizer进行代码级别的定制。
-
三、 Starter 与依赖管理
7. 什么是 Starter?为什么引入 Starter 后不需要写版本号?
-
考察点: 依赖管理机制。
-
回答要点:
-
Starter 是一组方便的依赖描述符,包含了该场景所需的全部依赖(比如
spring-boot-starter-data-redis包含了 Jedis 或 Lettuce 连接池、序列化等)。 -
版本管理来自于父 POM:
spring-boot-starter-parent中定义了<dependencyManagement>,锁定了常用依赖的版本,所以子模块引入依赖时通常不需要指定版本号(除非要覆盖)。
-
四、 核心特性与高级用法
8. 谈谈你对 Spring Boot 中 Actuator 的理解?
-
考察点: 生产环境监控能力。
-
回答要点:
-
Actuator 提供了生产就绪的监控端点(Endpoints),如
/health(健康检查)、/metrics(JVM 指标、CPU、内存)、/info(应用信息)、/loggers(动态调整日志级别)。 -
需要注意安全配置(通常需要设置
management.endpoints.web.exposure.include暴露端点,并配合 Spring Security 进行鉴权)。
-
9. Spring Boot 如何实现异步任务?
-
考察点: 并发处理能力。
-
回答要点:
-
在主类上添加
@EnableAsync。 -
在需要异步执行的方法上添加
@Async。 -
注意: 默认情况下,
@Async使用的是SimpleAsyncTaskExecutor(会无限创建线程),生产环境建议自定义线程池(实现AsyncConfigurer或定义ThreadPoolTaskExecutor的 Bean)。
-
10. Spring Boot 如何实现定时任务?
-
考察点: 任务调度。
-
回答要点:
-
使用
@EnableScheduling开启支持。 -
在方法上使用
@Scheduled(cron = "...")。 -
坑点: 默认情况下,定时任务是单线程执行的。如果一个任务阻塞,其他任务不会执行。建议配置
TaskScheduler的线程池大小。
-
五、 运行与部署
11. Spring Boot 支持哪些嵌入式容器?如何切换?
-
考察点: 对底层容器的了解。
-
回答要点:
-
默认支持 Tomcat、Jetty、Undertow。
-
切换方式:排除 Tomcat 的依赖,引入 Jetty 或 Undertow 的 Starter。
-
12. 如何让 Spring Boot 的 Jar 包部署到外部 Tomcat 运行?
-
考察点: 传统部署方式。
-
回答要点:
-
打包方式改为
<packaging>war</packaging>。 -
排除内置 Tomcat(
<scope>provided</scope>)。 -
继承
SpringBootServletInitializer并重写configure方法,通过SpringApplicationBuilder注册启动类。
-
六、 面试中可能遇到的“痛点”或原理深挖
13. 循环依赖问题:Spring Boot 默认是如何解决循环依赖的?
-
考察点: 对 Spring 核心机制的理解。
-
回答要点:
-
利用三级缓存(
singletonObjects、earlySingletonObjects、singletonFactories)进行解决。 -
本质上是通过提前暴露未完全初始化的 Bean(半成品对象)来解决。
-
注意: Spring Boot 2.6.x 版本开始默认禁止循环依赖,如果出现
The dependencies of some of the beans in the application context form a cycle错误,可以通过配置spring.main.allow-circular-references=true临时解决,但最佳实践是重构代码避免循环依赖。
-
14. 自定义 Starter 的步骤?
-
考察点: 框架封装能力。
-
回答要点:
-
创建两个模块:
xxx-spring-boot-starter(空项目,仅做依赖管理)和xxx-spring-boot-autoconfigure(核心代码)。 -
编写
XxxProperties类,使用@ConfigurationProperties绑定配置。 -
编写
XxxAutoConfiguration核心配置类,利用@Conditional控制生效条件。 -
在
resources/META-INF/spring.factories中(或对应 Spring Boot 2.7+ 的AutoConfiguration.imports)配置org.springframework.boot.autoconfigure.EnableAutoConfiguration指向配置类。
-
15. Spring Boot 的启动流程是怎样的?
-
考察点: 源码深度。
-
回答要点(简述):
-
创建
SpringApplication实例(推断应用类型是 Servlet 还是 Reactive,加载ApplicationContextInitializer和ApplicationListener)。 -
执行
run方法:-
启动计时器。
-
监听器发布
ApplicationStartingEvent。 -
准备环境变量(
ConfigurableEnvironment)。 -
创建
ApplicationContext(根据应用类型创建AnnotationConfigServletWebServerApplicationContext等)。 -
执行
refreshContext(这是 Spring 的核心,加载 Bean)。 -
执行
afterRefresh,调用callRunners(执行ApplicationRunner和CommandLineRunner)。
-
-
更多推荐

所有评论(0)