一、 基础与核心原理

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.ymlapplication-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 核心机制的理解。

  • 回答要点:

    • 利用三级缓存singletonObjectsearlySingletonObjectssingletonFactories)进行解决。

    • 本质上是通过提前暴露未完全初始化的 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 的步骤?

  • 考察点: 框架封装能力。

  • 回答要点:

    1. 创建两个模块:xxx-spring-boot-starter(空项目,仅做依赖管理)和 xxx-spring-boot-autoconfigure(核心代码)。

    2. 编写 XxxProperties 类,使用 @ConfigurationProperties 绑定配置。

    3. 编写 XxxAutoConfiguration 核心配置类,利用 @Conditional 控制生效条件。

    4. 在 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)。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐