Spring Boot 面试专题及答案
问题一:什么是 Spring Boot?
-
核心回答:Spring Boot 是 Spring 框架的一个子项目,旨在简化基于 Spring 的应用的初始搭建和开发过程。它通过“约定优于配置”的原则和大量的自动配置,让开发者能快速创建一个独立运行、生产级别的 Spring 应用。
-
详细解读:
-
传统 Spring 的痛点:需要大量手动配置 XML 或 JavaConfig,管理依赖版本冲突,部署需要外部的 Web 服务器(如 Tomcat)。
-
Spring Boot 的解决方案:
-
自动配置:根据你引入的依赖(如
spring-boot-starter-data-jpa),Spring Boot 会自动配置相关的 Bean 和组件,你无需手动编写大量配置。 -
起步依赖:将一组常用的依赖聚合在一起(如
spring-boot-starter-web包含了 Spring MVC, Tomcat 等),解决了依赖管理和版本冲突问题。 -
内嵌服务器:将 Tomcat, Jetty 或 Undertow 直接内嵌在应用中,使得应用可以作为一个独立的 JAR 文件运行,无需部署到外部服务器。
-
生产就绪功能:提供诸如健康检查、指标收集、外部化配置等监控和管理功能(通过 Actuator)。
-
-
问题二:Spring Boot 有哪些优点?
-
详细解读:
-
减少开发、测试时间和努力:自动配置和起步依赖让开发者能立即开始编写业务逻辑。
-
避免 XML 配置:全面拥抱 JavaConfig 和注解驱动开发。
-
避免 Maven 导入和版本冲突:起步依赖帮你管理了所有子依赖的版本,保证兼容性。
-
提供“约定优于配置”方法:如果你遵循默认的目录结构和命名约定,你几乎不需要任何配置。
-
内嵌服务器:简化了部署流程,
java -jar即可运行。 -
更少的配置:无需
web.xml。使用@Configuration和@Bean进行显式配置,或直接享受自动配置的便利。 -
基于环境的配置:这是 Spring Boot 强大的特性之一。你可以通过
application-{profile}.properties/yml文件为不同环境(dev, test, prod)定义不同的配置,并通过spring.profiles.active激活。
-
问题三:什么是 JavaConfig?
-
核心回答:JavaConfig 是 Spring 提供的使用 Java 类来替代传统的 XML 文件进行容器配置的方式。
-
详细解读:
-
核心注解:
-
@Configuration:标记一个类为配置类,相当于一个 XML 配置文件。 -
@Bean:标记在方法上,表示该方法返回的对象应被注册为 Spring 容器中的一个 Bean,相当于 XML 中的<bean>标签。
-
-
优点:
-
类型安全:在编译时就能发现类型错误,而 XML 要等到运行时。
-
重构友好:IDE 可以轻松支持类名、方法名的重命名和查找引用。
-
强大的面向对象能力:配置类可以继承、组合,可以使用所有 Java 语言的特性。
-
-
问题四:如何重新加载 Spring Boot 上的更改,而无需重新启动服务器?
-
核心回答:使用 Spring Boot DevTools。
-
详细解读:
-
功能:
-
自动重启:当 classpath 下的文件发生更改时,自动重启应用。它比冷启动更快,因为它使用了两个类加载器,一个用于不变的第三方 Jar,一个用于你正在开发的类。
-
LiveReload:自动刷新浏览器(需要浏览器安装 LiveReload 插件)。
-
开发时配置:提供默认的开发时配置,如更详细的日志记录。
-
远程调试:支持远程应用更新(不常用)。
-
-
原理:它监视
classpath资源的变动。在 IDEA 中,需要勾选Build project automatically(自动构建);在 Eclipse 中,保存即触发。 -
注意:
spring-boot-devtools在生产环境会被自动禁用。
-
问题五:Spring Boot 中的监视器是什么?
-
核心回答:监视器指的是 Spring Boot Actuator。它提供了一系列用于监控和管理生产环境应用的端点。
-
详细解读:
-
作用:暴露应用内部状态,如健康状态、指标(内存、CPU、请求统计)、环境属性、日志级别等。
-
访问方式:通过 HTTP JMX 端点。例如,默认情况下,
/actuator/health端点提供应用健康信息。 -
常用端点:
-
health:应用健康状态。 -
info:应用自定义信息(需在配置中设置)。 -
metrics:应用指标。 -
env:环境属性。 -
loggers:查看和修改日志级别。
-
-
问题六:如何在 Spring Boot 中禁用 Actuator 端点安全性?
-
详细解读:
-
历史背景:在 Spring Boot 1.x 中,确实可以通过
management.security.enabled=false来禁用所有 Actuator 端点的安全控制。 -
现状(Spring Boot 2.x 及以上):这个配置已失效。安全性由 Spring Security 统一管理。
-
正确做法:
-
如果你引入了
spring-boot-starter-security,所有 Actuator 端点默认都是安全的。 -
你可以通过
application.properties为 Actuator 端点单独配置安全规则:
properties
# 暴露所有端点(默认只暴露 health 和 info) management.endpoints.web.exposure.include=* # 然后使用 Spring Security 配置来放行特定的端点
-
在 Security 配置类中放行端点:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/actuator/health", "/actuator/info").permitAll() // 放行健康检查和信息端点.antMatchers("/actuator/**").hasRole("ADMIN") // 其他端点需要 ADMIN 角色.anyRequest().authenticated();} } -
-
问题七:如何在自定义端口上运行 Spring Boot 应用程序?
-
详细解读:
-
这是最直接的方式。也可以在
application.yml中配置:server:port: 8090 -
命令行参数:在运行时通过
--server.port=8090指定,优先级最高。 -
程序化设置:在
main方法中通过SpringApplication.setDefaultProperties设置。
-
问题八:什么是 YAML?
-
详细解读:
-
YAML Ain‘t Markup Language:一种人性化的数据序列化标准,非常适合做配置文件。
-
优点(相比于
.properties):-
层次结构:使用缩进表示层级,结构更清晰。
-
减少重复:可以定义锚点(
&)和别名(*)来复用配置片段。 -
支持复杂数据类型:如 List、Map。
-
-
示例对比:
properties
# application.properties server.port=8090 spring.datasource.url=jdbc:mysql://localhost/test spring.datasource.username=root spring.datasource.password=secret
yaml
# application.yml server:port: 8090 spring:datasource:url: jdbc:mysql://localhost/testusername: rootpassword: secret
-
问题九:如何实现 Spring Boot 应用程序的安全性?
-
详细解读:
-
添加依赖:
spring-boot-starter-security。 -
默认行为:依赖引入后,所有端点都会被保护,需要使用 HTTP Basic 认证,默认用户名为
user,密码在启动日志中生成。 -
自定义配置:创建一个配置类继承
WebSecurityConfigurerAdapter(在 Spring Security 5.7+ 中,推荐使用基于组件的配置)。-
内存认证:在配置类中配置用户名、密码和角色。
-
JDBC 认证:从数据库加载用户和权限。
-
自定义 UserDetailsService:实现从任何数据源加载用户详情。
-
配置 URL 访问规则:指定哪些 URL 需要什么权限,哪些可以匿名访问。
-
配置登录/登出页面。
-
-
问题十:如何集成 Spring Boot 和 ActiveMQ?
-
详细解读:
-
添加依赖:
spring-boot-starter-activemq。 -
配置连接工厂:在
application.properties中配置 ActiveMQ broker URL:spring.activemq.broker-url=tcp://localhost:61616。 -
发送消息:使用
JmsTemplate。 -
接收消息:使用
@JmsListener注解。
-
问题十一:如何使用 Spring Boot 实现分页和排序?
-
详细解读:
-
这主要依赖于 Spring Data JPA。
-
步骤:
-
在 Repository 接口中,直接定义方法,参数为
Pageable。
public interface UserRepository extends JpaRepository<User, Long> {Page<User> findByLastName(String lastName, Pageable pageable); }-
在 Service 或 Controller 中,构造
Pageable对象。
@GetMapping("/users") public Page<User> getUsers(@RequestParam(defaultValue = "0") int page,@RequestParam(defaultValue = "10") int size,@RequestParam(defaultValue = "lastName") String sort) {Pageable pageable = PageRequest.of(page, size, Sort.by(sort));return userRepository.findAll(pageable); } -
-
前端传参:通常为
?page=0&size=20&sort=firstName,asc。
-
问题十二:什么是 Swagger?你用 Spring Boot 实现了它吗?
-
详细解读:
-
Swagger(现称为 OpenAPI):一套规范和工具集,用于描述、生成、消费和可视化 RESTful Web 服务。
-
Spring Boot 集成:使用
springdoc-openapi-ui库。-
添加依赖。
-
访问 UI:启动应用后,访问
http://localhost:8080/swagger-ui.html。 -
自动生成:它会自动扫描你的
@RestController,根据注解生成 API 文档。 -
自定义注解:使用
@Operation,@ApiResponse等注解增强文档描述。
-
-
问题十三:什么是 Spring Profiles?
-
详细解读:
-
作用:提供一种方式,让应用在不同环境(开发、测试、生产)下使用不同的配置、注册不同的 Bean。
-
使用方式:
-
定义配置文件:
application-{profile}.properties/yml,如application-dev.yml,application-prod.yml。 -
激活 Profile:
-
配置:
spring.profiles.active=prod -
命令行:
--spring.profiles.active=dev,debug -
JVM 参数:
-Dspring.profiles.active=test
-
-
-
代码中使用
@Profile注解:只有指定 Profile 激活时,被注解的 Bean 或配置类才会被加载。@Configuration @Profile("dev") public class DevConfig {// 这个配置只在 dev 环境下生效 }
-
问题十四:什么是 Spring Batch?
-
详细解读:
-
用途:一个轻量级、全面的批处理框架,用于处理大量的数据。
-
核心概念:
-
Job:一个完整的批处理流程。
-
Step:Job 的一个步骤,包含
ItemReader(读)、ItemProcessor(处理)、ItemWriter(写)。
-
-
Spring Boot 支持:通过
spring-boot-starter-batch依赖,自动配置 JobRepository 等基础设施,让开发者专注于业务逻辑。
-
问题十五:什么是 FreeMarker 模板?
-
详细解读:
-
它是一个 Java 模板引擎,用于生成文本输出(HTML, XML, 电子邮件,代码等)。
-
Spring Boot 集成:
-
添加依赖
spring-boot-starter-freemarker。 -
模板文件默认放在
src/main/resources/templates/下,后缀为.ftlh或.ftl。 -
在 Controller 中返回视图名,Spring 会自动定位并渲染模板。
-
-
优势:语法简单,与 HTML 融合度高,将表现层与业务逻辑彻底分离。
-
问题十六:如何使用 Spring Boot 实现异常处理?
-
详细解读:
-
@ControllerAdvice:一个全局的异常处理组件,可以捕获所有 Controller 中抛出的异常。 -
@ExceptionHandler:在@ControllerAdvice类中注解方法,指定该方法处理哪种异常。
@ControllerAdvice public class GlobalExceptionHandler {@ExceptionHandler(UserNotFoundException.class)public ResponseEntity<?> handleUserNotFound(UserNotFoundException ex) {ErrorResponse error = new ErrorResponse("NOT_FOUND", ex.getMessage());return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);}@ExceptionHandler(Exception.class)public ResponseEntity<?> handleGlobalException(Exception ex) {ErrorResponse error = new ErrorResponse("INTERNAL_SERVER_ERROR", "An unexpected error occurred");return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);} } -
问题十七:您使用了哪些 starter maven 依赖项?
-
详细解读:
-
这是一个开放性问题,根据你的项目经验回答。
-
常见 starters:
-
spring-boot-starter-web:构建 Web 应用,包含 RESTful, Spring MVC, 内嵌 Tomcat。 -
spring-boot-starter-data-jpa:使用 Spring Data JPA 和 Hibernate。 -
spring-boot-starter-security:使用 Spring Security 进行认证和授权。 -
spring-boot-starter-test:用于测试,包含 JUnit, Mockito, Spring Test。 -
spring-boot-starter-actuator:添加监控和管理功能。 -
spring-boot-starter-cache:启用 Spring 框架的缓存支持。
-
-
问题十八:什么是 CSRF 攻击?
-
详细解读:
-
攻击原理:攻击者诱骗已在一个网站(如银行网站)认证过的用户,去点击一个恶意链接或访问一个恶意页面,该页面会伪造一个请求(如转账)发给目标网站。由于用户的浏览器会自动携带 Cookie(Session),目标网站会认为这是一个合法的用户请求。
-
防御机制:
-
CSRF Token:服务器生成一个随机的 Token 并放在表单(或 HTTP 头)中,提交请求时验证此 Token。Spring Security 默认已启用 CSRF 保护。
-
-
问题十九:什么是 WebSockets?
-
详细解读:
-
与 HTTP 的区别:HTTP 是无状态、请求-响应模式的协议。WebSocket 是长连接、全双工通信协议。
-
应用场景:实时应用,如聊天室、实时游戏、股票行情、协同编辑。
-
Spring Boot 集成:使用
spring-boot-starter-websocket,并通过@EnableWebSocketMessageBroker和实现WebSocketConfigurer接口来配置。
-
问题二十:什么是 AOP?
-
详细解读:
-
核心思想:将横切关注点(如日志、事务、安全)与核心业务逻辑分离。
-
相关术语:
-
Aspect:横切关注点的模块化(一个类,用
@Aspect注解)。 -
Advice:在特定连接点执行的动作(如
@Before,@After,@Around)。 -
Pointcut:匹配连接点的表达式,定义了 Advice 在哪里执行。
-
-
Spring Boot 中使用:无需特殊配置,直接添加
@Aspect组件即可。
-
问题二十一:什么是 Apache Kafka?
-
详细解读:
-
角色:分布式、高吞吐量、高可用的发布-订阅消息系统。
-
核心概念:
-
Topic:消息的类别或频道。
-
Producer:向 Topic 发布消息的客户端。
-
Consumer:订阅 Topic 并处理消息的客户端。
-
Broker:Kafka 集群中的一个服务器节点。
-
-
Spring Boot 集成:使用
spring-kafka库,通过@KafkaListener注解消费消息,使用KafkaTemplate发送消息。
-
问题二十二:我们如何监视所有 Spring Boot 微服务?
-
详细解读:
-
单个服务的痛点:如文档所述,需要手动访问每个服务的 Actuator 端点,效率低下。
-
解决方案:
-
Spring Boot Admin:一个开源社区项目,它提供了一个 UI 界面,可以集中管理和监控所有微服务的状态。它会收集并可视化所有注册服务的 Actuator 端点信息。
-
集中式日志:使用 ELK Stack(Elasticsearch, Logstash, Kibana)或 Graylog 收集所有微服务的日志。
-
分布式追踪:使用 Spring Cloud Sleuth 和 Zipkin,追踪一个请求在多个微服务间的调用链路和性能。
-
指标聚合:使用 Micrometer 将指标数据导出到 Prometheus,然后用 Grafana 进行可视化。
-
-
