☰
SpringBoot核心面试知识点全解析:自动装配原理、CGLIB代理与配置体系
2026/10/1 13:00:14 网站建设 项目流程

进入金三银四也好,日常骑驴找马也罢,SpringBoot 相关的问题几乎是面试必考项。我这些年面过不少候选人,也在技术社区里围观过大量面试复盘,感触最深的一点是:很多人框架用得挺熟,CRUD 写得飞起,被问到 SpringBoot 自动装配的原理、为什么默认走 CGLIB 代理、配置文件优先级这类问题时,反而聊不到点子上。

这篇整理不是写给零基础读者怎么建项目的,也不是给架构师讲高并发治理的,而是把我认为面试前最值得过一遍的 SpringBoot 核心知识点按主题拆开。每个主题都会讲清楚“是什么”“为什么”“面试官想听到什么”,同时附上一些实际项目里踩过的坑。你可以把它当成面试前的速查笔记,也可以当成复习提纲,哪块不熟就翻哪块。

1. 自动装配原理:SpringBoot 最核心的面试考点

1.1 三个注解融为一体

自动装配几乎是所有 SpringBoot 面试的开场白。面试官通常会先问“你说说 SpringBoot 为什么能自动配置”,如果你直接背诵“因为有 @EnableAutoConfiguration”,那只能算及格,离加分还差得远。

首先得把启动类上的 @SpringBootApplication 拆开。它本质上是三个注解的组合:@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan。其中 @SpringBootConfiguration 底层就是 @Configuration,表示这是一个配置类;@ComponentScan 负责扫描主类所在包及其子包下的组件;真正承担自动装配核心逻辑的是 @EnableAutoConfiguration。

这里有个容易被忽略的细节:为什么规范要求启动类放在根包下?就是因为 @ComponentScan 默认扫描的范围是启动类所在包,一旦把启动类放到子包里,扫描范围就会受限,一些 Bean 会找不到。面试官如果顺口问一句“你遇到过 ComponentScan 失效的情况吗”,往往是这个原因。

1.2 自动装配的完整链路

@EnableAutoConfiguration 本身也是一个组合注解,核心是导入了 AutoConfigurationImportSelector。这个类通过 getAutoConfigurationEntry 方法去读取候选配置清单,然后再做过滤、去重、排除,最终返回真正需要导入的配置类。

早期版本里,候选配置清单写在 META-INF/spring.factories 文件里,键是 EnableAutoConfiguration。从 SpringBoot 2.7 开始,官方引入了新的 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件,逐步替代 spring.factories 中的自动配置条目。如果你在维护老项目,两个入口都要能认出来。

关键点在于:被列进 imports 文件只是“候选”,最终是否生效还取决于每个配置类上的条件注解。这就是自动装配最常见的误区——候选人以为“配置类加载了就等于装配了”,实际上配置类会被加载,但内部的 @Bean 方法必须通过条件判断才会真正执行。

拿 RedisAutoConfiguration 举例。它上面标了一堆条件注解:@ConditionalOnClass(RedisOperations.class),表示 classpath 下必须有 RedisOperations 这个类;@ConditionalOnMissingBean 则表示容器里没有 RedisTemplate 等关键 Bean 时才执行装配。所以自动装配是“候选清单加条件判断”双重过滤后的结果。这个逻辑在面试时讲清楚,基本就能和大多数候选人拉开差距。

1.3 自定义自动配置与条件装配

面试进阶时,面试官可能让你现场说说“怎么自己写一个自动配置”。这个不能只停留在概念上,得能说出关键步骤:

第一步,写一个配置类,在上面标注 @Configuration 和一组条件注解。第二步,把类路径写入 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件。第三步,提供一个带前缀的属性类,比如 @ConfigurationProperties(prefix = "my.demo"),让使用方能在 application.yml 里配置参数。

条件注解里最常用的是 @ConditionalOnMissingBean、@ConditionalOnProperty、@ConditionalOnClass 这组。需要注意 @ConditionalOnMissingBean 的语义:它判断的是“当前容器里是否缺少某个类型的 Bean”,而不是“整个 JVM 里有没有这个类”。很多人写 starter 时容易在这里翻车,比如自定义 Starter 里默认注册了一个 ObjectMapper 的定制 Bean,结果项目的其他模块也注册了,导致默认 Bean 被跳过,配置不生效。

条件注解的评估时机也值得记一下:它发生在容器刷新阶段,并且与 BeanDefinition 的解析顺序有关。这也是为什么有时候你会看到“某个配置类明明符合条件却没生效”的玄学问题,排查时先看是否被自定义 Bean 抢先注册,再看 @ConditionalOnProperty 的 matchIfMissing 属性配置是否合理。

提示:面试被问到自动装配原理时,按“注解组合 -> 配置类候选清单 -> 条件过滤 -> Bean 注册”这条链路展开,比单纯背结论要完整得多。

2. Starter 机制:从用到写的理解路径

2.1 Starter 为什么这么香

自动装配解决的是“怎么配”的问题,而 Starter 解决的是“依赖怎么带”的问题。两者合在一起,才构成 SpringBoot 开箱即用的体验。

一个 Starter 的本质是两样东西的打包:依赖描述和自动配置类。比如 spring-boot-starter-web 引入了 spring-web、spring-webmvc、内嵌 Tomcat 等依赖,同时因为包含 spring-boot-autoconfigure 的传递和 spring.factories/imports 机制,web 相关自动配置才能被扫描到。

我经常用“买路由器”来打比方。传统 SSM 整合是给你一堆零件,要自己拧螺丝、接网线、装驱动;SpringBoot Starter 是一台免安装的智能路由,通电自动识别网络,你只需要设置 WiFi 密码(改几个配置项)。这也是为什么面试官喜欢问“为什么用 SpringBoot 开发效率高”,答案的本质不是 IDEA 快,而是 Starter 机制把“依赖管理”和“自动配置”这两件麻烦事标准化了。

2.2 命名规范与版本管理

命名这件事看起来不起眼,面试和实际项目里都有讲究。官方 Starter 命名是 spring-boot-starter-xxx,比如 spring-boot-starter-data-redis。第三方自定义 Starter 如果要在 SpringBoot 项目里直接引用,通常有两种命名风格,一是 spring-boot-starter-xxx,二是 xxx-spring-boot-starter,区别在于:前者容易被官方依赖分类混淆,后者能明确表达“这是一款针对 SpringBoot 的第三方 Starter”。

版本管理上有一个实际踩过很多次的坑:使用了非官方 Starter 时,一定要关注它编译对应的 SpringBoot 版本。常见问题是项目里引了某个 mybatis-spring-boot-starter 的旧版本,它基于 SpringBoot 2.x 编写,结果直接放进 SpringBoot 3.x 项目里,启动时各种 NoSuchMethodError。所以引入第三方 Starter 前先看一眼它父依赖的 SpringBoot 版本,比报错后再去搜索要省力得多。

2.3 动手写一个自定义 Starter

写自定义 Starter 并不神秘,核心就是把逻辑下沉到一个独立模块,让其他服务通过依赖引入后自动生效。

项目结构通常分为 autoconfigure 模块和 starter 模块。autoconfigure 模块存放自动配置类和属性类,starter 模块只做一件事:依赖 autoconfigure 模块,同时把自己暴露给使用方。这种拆分是为了更精细地控制依赖范围。

配置类大致长这样:

@AutoConfiguration @ConditionalOnClass(MyService.class) @EnableConfigurationProperties(MyProperties.class) public class MyAutoConfiguration { @Bean @ConditionalOnMissingBean public MyService myService(MyProperties properties) { return new MyService(properties.getPrefix()); } }

然后在 resources/META-INF 下新增文件,内容按行写自动配置类的全限定名。如果是 SpringBoot 2.7 之前的项目,则要写入 META-INF/spring.factories:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.autoconfigure.MyAutoConfiguration

项目里用的时候,除了引入依赖,还要确保 spring-boot-autoconfigure 在 classpath 中,否则 @AutoConfiguration 注解可能识别不到。贡献者普遍容易漏掉这一步,面试手写时特意提一嘴会显得更有经验。

提示:自定义 Starter 的自动配置类不需要手动 @ComponentScan 扫描,SpringBoot 是通过 imports 文件加载的。这也是自动配置类有时候“不被项目扫描也能生效”的根本原因。

3. 内嵌容器与可执行 Jar:为什么 java -jar 就能跑 Web 应用

3.1 可执行 Jar 的结构

面试中有一个高频连环问:SpringBoot 打成 Jar 包后为什么能直接 java -jar 运行?普通 Java Jar 不是不能内置依赖吗?

答案在于 SpringBoot 的可执行 Jar 采用了特殊的嵌套结构。它会生成一个 fat jar,内部包含 BOOT-INF/classes、BOOT-INF/lib、META-INF 等目录。页面启动时由 JarLauncher 负责加载嵌套的依赖 Jar,而不是依赖系统 ClassLoader 直接找到所有类。

具体启动链路是:main 方法所在的 JarLauncher 创建一个全新的类加载器,把 BOOT-INF/lib 下的所有 Jar 包装成 URL,再通过反射调用我们自己写的启动类的 main 方法。这也是为什么 SpringBoot 可执行 Jar 里的类路径和普通 Jar 不同,外部系统想直接拿到其中的类比较困难,反编译时看到的结构也和普通项目源码不一致。

面试时如果讨论“怎么将 SpringBoot Jar 反编译成项目”,本质上就是要把嵌套结构还原成普通 Maven 工程:解压出 BOOT-INF/classes 下的 class 文件,用反编译工具转成 Java 源码,再把 BOOT-INF/lib 下的依赖按 pom 坐标整理。思路不难,真正耗时间的是处理资源文件、配置文件以及依赖版本的还原。

3.2 容器替换与核心调优参数

默认内嵌容器是 Tomcat,这并不代表只能用 Tomcat。SpringBoot 支持通过引入 spring-boot-starter-jetty 或 spring-boot-starter-undertow 替换默认容器,操作很简单,把 web starter 里的 Tomcat 排除,再替换成目标容器即可。

换成 Undertow 的好处是 IO 并发场景下内存占用低,我实测过高并发接口在同样配置下 Undertow 的 GC 压力比 Tomcat 小一些。但换容器不是银弹,很多项目用 Tomcat 默认设置也能扛住业务量,真正影响性能的是线程池、连接超时、AcceptCount 这几个参数。

server: port: 8080 tomcat: max-threads: 200 min-spare-threads: 20 accept-count: 100 connection-timeout: 5000

这里要注意 max-threads 不是越大越好,线程太多会导致频繁上下文切换,接口响应时间反而上升。通常先压测拿到基准数据,再逐步调整 max-threads 和 accept-count 的组合,才是规范的调优方式。

3.3 外置容器部署与踩坑

老项目里还有一类需求:打成 war 包部署到外部 Tomcat。做法是将打包方式改为 war,然后继承 SpringBootServletInitializer 并重写 configure 方法。这个考点不算难,但踩坑点很典型。

容易出问题的是 JSP 支持和静态资源路径。SpringBoot 默认不以 war 包里的 JSP 为主要视图,需要额外引入 tomcat-embed-jasper,并且 JSP 只建议放在 src/main/webapp 下。另一个坑是下划线、中划线路径在外部容器和内嵌容器下解析存在差异,部署环境不同可能导致 404。所以做外置部署前,一定要在目标容器版本上做一次完整回归。

提示:SpringBoot 3.x 部分内嵌容器的默认版本和外部 Tomcat 版本差异较大,war 包部署时优先看外部 Tomcat 主版本是否满足 Servlet API 要求,否则会出现 NoClassDefFoundError。

4. 配置体系:优先级、YAML 与多环境

4.1 配置优先级与“不生效”之谜

有句话说“SpringBoot 项目百分之八十的疑难杂症都出在配置上”,这话不算夸张。配置优先级是其中最容易踩雷的。

配置来源从高到低大致是:命令行参数 > Java 系统属性 > 操作系统环境变量 > application-{profile}.yml > application.yml > 默认配置。很多人改了 application.yml 却不生效,第一反应是“配置写错了”,其实大概率是当前环境里有更高优先级的配置源覆盖了它。比如 IDE 里设置了环境变量,或者启动时带了 --server.port=8081,这类配置就会直接压制 yml 文件里的端口配置。

排查“配置不生效”时,我会先确认配置来源,再用 Actuator 的 /configprops 或 /env 接口查看实际生效值。这个动作比反复重启服务更高效,也值得在项目里养成习惯。

4.2 YAML 写法、@Value 与 @ConfigurationProperties

YAML 和 properties 两种格式各有偏好。properties 简单直接,适合少量配置;YAML 缩进表达结构,适合多级配置。但 YAML 有一个容易翻车的点:数组和对象缩进不对,或行内写了 Tab 字符,启动时直接解析失败。建议所有 YAML 文件统一用空格缩进,不要出现 Tab。

从代码取配置有三种常见姿势:@Value 注入单个值、Environment 读取、@ConfigurationProperties 绑定属性类。面试常问“@Value 和 @ConfigurationProperties 有什么区别”,核心差别在于:

  • @Value 支持 SpEL,可以写复杂表达式,但只能绑定简单类型;
  • @ConfigurationProperties 支持复杂对象、集合、Map 的绑定,且会做松散绑定,比如 prefix.user-name 可以映射到 userName。

实际项目中,如果配置项比较多且成组,强烈建议用 @ConfigurationProperties 建一个属性类,可读性和后续扩展性都更好。用 @Value 散落在各个类里,后期重构关联成本很高。

4.3 Profile 多环境、随机端口与配置安全

多环境管理在面试中属于送分题,但很多人答不出“优先级叠加”的细节。spring.profiles.active 指定生效的 profile,本质上是在 application.yml 基础之上叠加加载 application-{profile}.yml,profile 文件优先级更高。

随机端口这个热搜词也经常出现。SpringBoot 支持在配置里使用 ${random.int[1024,65535]}、${random.uuid} 等占位符。常见用法是测试环境不想冲突时,把端口配置为随机:

server: port: ${random.int[8000,9000]}

但要注意,随机端口只在该应用启动时生成一次,存在 Environment 里。如果你用固定端口做服务发现注册,随机端口可能造成注册中心拿到的是 0 或错误端口,生产环境要慎用。

配置安全上,常见做法是用 Jasypt 对敏感配置进行加密。引入 jasypt-spring-boot-starter 后,配置里就能写 ENC(加密串),启动时用密钥解密。这种方案简单有效,但密钥一定要放到启动参数或环境变量里,不能直接写进配置文件,否则加密就变成心理安慰了。

提示:SpringBoot 的配置加载顺序可以通过 spring.config.additional-location 增加外部配置目录,这在容器化部署时代尤其好用,把部分敏感配置放挂载目录,和代码镜像解耦。

5. SpringBoot 默认 CGLIB 代理与 AOP

5.1 两种动态代理的区别

SpringBoot 2.0 之后,代理机制默认走 CGLIB,这是一个经典面试考点。很多人只记得“默认 CGLIB”,但说不出为什么。

JDK 动态代理要求目标类必须实现接口,通过 Proxy.newProxyInstance 生成一个实现同接口的代理类;CGLIB 则直接继承目标类,通过生成子类覆盖需要拦截的方法来实现。所以使用 CGLIB 的隐藏要求是:目标类不能被 final 修饰,目标方法不能是 final 或 private,否则无法被继承和覆盖。

SpringBoot 默认使用 CGLIB 是综合权衡的结果。一方面很多业务类没有接口,JDK 代理只能退而求其次不代理;另一方面 CGLIB 能拦截非接口方法,配置更统一。代价是引入了 CGLIB 依赖,并且 final 类、final 方法会出现代理失效的坑。

5.2 代理失效的经典场景

这块能展开的内容太多了,面试官尤其喜欢让候选人现场判断“这个 @Transactional 到底有没有生效”。

最常见的场景是同类内调用。A 方法里直接调用同类 B 方法,B 上有 @Transactional,但 A 调用的是 this.B(),没有经过代理对象,事务拦截器完全不参与,所以事务不生效。解决办法有几种:注入自身代理对象、把 B 方法抽取到另一个 Bean、或者在配置里开启 exposeProxy 后用 AopContext.currentProxy() 获取代理对象。

第二种常见场景是方法本身的问题。private、final、static 方法上标 @Transactional 不会生效。原因是 CGLIB 无法覆盖 private/final 方法,代理逻辑进不去。还有一种是异常被吞了,事务方法内 catch 住异常没抛出,回滚自然不触发。

第三种场景是代理失效导致的安全问题。如果你的类被 final 修饰,SpringBoot 启动阶段就可能直接报错或静默降级,排查时看到 “final” 关键字要第一时间想到代理机制。

5.3 面试回答思路

被问到“SpringBoot 为什么默认 CGLIB”,打分的点在“有没有理解代理模式的应用背景”。一个不错的回答思路是:

先点明 Spring AOP 底层两种实现方式,再说 SpringBoot 2.0 后将 proxyTargetClass 默认值从 false 改为 true,因此默认 CGLIB。然后补充 CGLIB 原理和约束,最后提一句“如果业务确实基于接口设计,可以通过配置切回 JDK 动态代理”。这样既有结论,又有原理,还有工程意识,面评通常不错。

提示:写切面时建议对接口方法使用 Before/After 注解,而不是直接修改目标方法签名。否则用 CGLIB 子类代理时,一旦目标方法为 final,切面就可能静默失效。

6. 数据访问层实战与面试要点

6.1 整合 MyBatis 的完整配置

SpringBoot 整合 MyBatis 是后端开发者的基础功,面试时一般会问 Mapper 接口是怎么被扫描并注册成 Bean 的。

最简单的方式是引入 mybatis-spring-boot-starter,然后在配置类上标注 @MapperScan,或在每个 Mapper 接口上标 @Mapper。注意 @MapperScan 和 @Mapper 二者选其一即可,不必同时加。扫描到 Mapper 接口后,MyBatis 会通过 MapperFactoryBean 注册为代理 Bean,这个代理最终绑定到 SqlSessionTemplate。

实际项目里我更推荐 @MapperScan 加配置类,理由是可以集中指定 sqlSessionTemplateRef,多个数据源时也能精确绑定。另外一个容易被忽略的配置是驼峰映射:

mybatis: configuration: map-underscore-to-camel-case: true

如果不开启这个开关,数据库 user_name 字段不会自动映射到 Java 的 userName 属性,结果对象里对应字段全是 null。这个现象在项目里排查过很多次,十有八九是没开驼峰映射。

6.2 事务管理与传播行为

@Transactional 是面试必背的一块。除了上一章讲的代理失效问题,还需要掌握事务的传播级别和隔离级别,面试官一般会挑几个让候选人解释。

常见传播行为有 REQUIRED、REQUIRES_NEW、NESTED、MANDATORY 等。REQUIRED 表示如果没有事务就新建,有就加入;REQUIRES_NEW 表示挂起当前事务,新起一个独立事务;NESTED 则表示嵌套事务,内层回滚可以只回滚保存点,不影响外层。这里很多人把 NESTED 和 REQUIRES_NEW 混淆,其实 NESTED 依赖 JDBC 的 savepoint,性能和数据源支持上有差异。

事务不要滥用,我在项目里见过最典型的问题是:一个方法里调用外部接口,外部接口超时 30 秒,整个事务被拖住,数据库连接一直被占用,最后连接池耗尽。所以长事务一定要拆解,外部调用尽量放到事务外层异步处理。

6.3 数据库读写分离的思路

数据库读写分离是一个偏架构的考点,面试出现频率不低。SpringBoot 并没有内置读写分离,需要自己实现动态数据源。经典思路是继承 AbstractRoutingDataSource,重写 determineCurrentLookupKey 方法,通过 ThreadLocal 记录当前应该走主库还是从库。

实现要点有几个。第一,数据源配置通常用 HikariCP 或 Druid 创建 master 和 slave 两个独立数据源,再把它们放进一个目标数据源 Map,交给路由数据源管理。第二,通过 AOP 拦截 Service 或 Mapper 层方法,按方法名或注解切换数据源策略。比如 select、get、query 开头的走从库,其他走主库。第三,事务和路由的兼容问题,一旦方法上开启事务,数据源必须在事务开启前确定,否则可能全程走主库。

我自己的经验是:小项目不要轻易上读写分离,主从延迟、数据一致性排查成本很高。面试能讲清楚思路和关键点就够,落地时务必评估业务必要性。

提示:多数据源场景下,@Transactional 默认绑定主数据源的事务管理器。如果读写分离后出现“查到的是旧数据”的诡异现象,先检查是不是事务将读写全部路由到了主库。

7. 高频考点速查与日常小技巧

7.1 面试高频题速查表

这部分我把 SpringBoot 面试中出现频率最高的题目和参考回答角度整理成速查表,适合打印出来贴在工位上。

面试问题核心回答要点
自动装配原理注解组合、AutoConfigurationImportSelector、imports 文件、条件注解
Starter 和依赖的区别Starter 是依赖加自动配置的组合,解决“引入即用”
为什么 java -jar 能启动可执行 Jar 嵌套结构、JarLauncher、自定义类加载器
默认 CGLIB 代理原因SpringBoot 2.0 后 proxyTargetClass 默认 true,可拦截非接口方法
yml 和 properties 区别结构表达、缩进、松散绑定支持
配置优先级命令行 > 环境变量 > profile 文件 > 主配置文件
@Value 与 @ConfigurationProperties 对比单个值 vs 结构化绑定、SpEL 支持
内嵌容器替换排除 Tomcat,引入 Jetty/Undertow starter
profile 多环境spring.profiles.active、配置文件的叠加关系
@Transactional 失效场景同类调用、final/private 方法、异常被吞、自调用
SpringBoot 3.x 新特性Jakarta EE 命名空间、AOT 编译、GraalVM 支持
如何打 war 包部署打包方式改为 war、继承 SpringBootServletInitializer

这张表只是索引,每个知识点要能展开讲 2 到 3 分钟,面试才算真正过关。千万不要背成“茴香豆的茴字有几种写法”,要让面试官感到你真的在项目里这么用过。

7.2 整合第三方组件的通用套路

SpringBoot 的热搜词里大量涉及 ES、Redis、ActiveMQ、Kettle、视频转码、Mqtt 等组件的整合。很多人每整合一个组件就要查一遍教程,其实底层套路是通用的。

第一步,确认官方是否提供 starter,有就优先用。例如 spring-boot-starter-data-redis。没有就必须引入第三方 starter,比如 mybatis-spring-boot-starter。第二步,看自动配置生效后的默认 Bean 是什么,通过自动装配原理判断自己还需要补充哪些配置。比如 Redis 默认提供 RedisTemplate,但默认序列化器是 JdkSerializationRedisSerializer,一般得自己定制 JSON 序列化器。第三步,补全业务封装层,比如封装 RedisUtil、MQ 消息监听器等。

这套流程熟了之后,整合新组件的心态会完全不一样:从“到处搜教程”变成“看官方文档、找自动配置类、验证默认行为”。这其实就是 SpringBoot 框架给开发者的最大赋能,把重复配置标准化,让开发者专注于差异逻辑。

举例来说,整合 Elasticsearch 时先引入 spring-boot-starter-data-elasticsearch,再用 @Document 注解声明实体,然后注入 ElasticsearchRestTemplate。真正费时间的是对查询 DSL 的封装,比如 bool 查询、分词匹配规则,这些和 SpringBoot 关系不大,但面试时如果你能顺带提一句“ES 的索引设计要和业务查询场景匹配”,就显得很有实战经验。

7.3 一些不起眼但很实用的小技巧

平时项目里有很多小技巧,单拎出来不复杂,但在面试实战中可以作为一种加分项展示。第一个是自定义启动 Banner,用在线 Banner 生成器把文字转成 ASCII 艺术字,放进 resources 目录下的 banner.txt,启动时就会展示自己的标识。这虽然不能提升系统性能,但能体现工程细节方面的注意。

第二个是引入外部 Jar 包。Maven 项目里如果依赖了一个不在中央仓库的私有 Jar,最简单的做法是安装到本地仓库:

mvn install:install-file -Dfile=xxx.jar -DgroupId=com.example -DartifactId=xxx -Dversion=1.0 -Dpackaging=jar

然后按坐标正常引用。但要注意这种本地安装只对当前机器有效,团队协作时最好搭建私有仓库,否则其他人构建时会直接报缺失依赖。

第三个是处理文档型接口的开关问题。新项目里如果引入了 springdoc 或 knife4j,不想在某个环境暴露接口文档,可以通过 springdoc.api-docs.enabled=false 和 springdoc.swagger-ui.enabled=false 关闭。别小看这个小配置,生产环境暴露接口文档是我见过最常见的低级安全问题之一。

写在后面的一些个人经验

整理的这些知识点,大都不是靠背诵记下来的,而是在项目里一个个踩坑踩出来的。

我自己带项目时有个习惯:每次遇到“配置不生效”“代理不进切面”“事务没回滚”这类问题,都会把排查过程整理成笔记,标注根因和复原方式。时间久了,这些笔记就成了面试时最自然的素材库,因为面试官极爱问“你遇到过什么问题、怎么排查的”,这时候能讲出具体失败案例和解决路径的候选人,明显比只会背官方文档的人更有说服力。

这套复习思路同样适用于那些没时间做系统复习的人:与其花几个小时漫无目的地刷题,不如把自动装配原理、Starter 设计、内嵌容器、配置体系、AOP 代理、数据访问这六大板块过一遍,再结合自己项目里的实际报错仔细想一遍。面试前再做一轮快问快答,基本就能稳住。

最后再分享一个小技巧:面试聊 SpringBoot 时,不管问题多基础,都尽量往“启动过程、运行时 Bean 生命周期、配置加载顺序”这三条主线上靠。SpringBoot 的一切特性都能在这三条主线上找到落脚点,这也是 SpringBoot 框架设计得最出彩的地方。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询