Skip to content

Spring 综合真题解析

真实面试题完整回答 + 原理串联演示


一、IoC 容器

真题 1:Spring 为什么要用三级缓存而不是二级?

面试官意图:考察对循环依赖和 AOP 代理机制的深度理解

完整回答

三级缓存的核心优势是延迟代理创建

二级缓存的方案是这样的:实例化 Bean 后,不管有没有循环依赖,都必须立即决定是否创建 AOP 代理,然后把代理对象放入二级缓存。这样即使没有循环依赖,所有 Bean 也会在实例化后就被迫创建代理。

三级缓存用 ObjectFactory 做了一层延迟——只有真的发生循环依赖、需要提前暴露时,才调用工厂方法创建代理。没有循环依赖的 Bean 走正常流程:postProcessAfterInitialization 阶段才生成代理。

所以本质问题是:二级缓存无法区分"这个 Bean 有没有被循环依赖引用"。三级缓存通过 ObjectFactory 的延迟执行做到了区隔。

原理串联: **三级缓存原理** → **Bean生命周期(后置处理阶段)** → **AOP代理生成**


真题 2:Spring 如何推断使用哪个构造方法实例化 Bean?

面试官意图:考察对 Bean 实例化源码的了解

完整回答

Spring 的构造器推断逻辑:

  1. 如果 Bean 只有一个构造方法——无论是否有参——直接使用它(从 Spring 4.3 开始,唯一构造方法无需 @Autowired)
  2. 如果有多个构造方法:
    • 找标注了 @Autowired 的构造方法,有且唯一则使用
    • 有多个 @Autowired 构造方法则抛异常
    • 没有 @Autowired 时,找默认无参构造方法
    • 没有默认无参构造方法则抛异常

选择好构造方法后,Spring 根据构造参数类型在容器中查找依赖 Bean,进行构造器注入。

原理串联: **refresh()启动流程(第11步)** → **依赖注入**


二、AOP

真题 3:@Configuration 加 final 会怎样?为什么?

面试官意图:考察对 CGLIB 增强和 Full/Lite 模式的理解

完整回答

@Configuration 类默认是 Full 模式——被 CGLIB 创建子类代理。CGLIB 代理拦截 @Bean 方法,在方法调用时检查容器中是否已有该 Bean,有则返回容器中的单例,无则创建。

如果 @Configuration 类加了 final,CGLIB 无法生成子类(final 类不能被继承),自动降级为 Lite 模式。此时 @Bean 方法就是普通方法调用,方法间调用不再保证单例。

比如:

java
@Configuration
public final class AppConfig {  // 降级为 Lite
    @Bean
    public A a() { return new A(b()); }  // b() 每次返回新实例
    @Bean
    public B b() { return new B(); }
}

原理串联: **@Configuration增强** → **CGLIB代理原理**


三、事务管理

真题 4:REQUIRES_NEW 在同一个事务管理器下真的会新建物理连接吗?

面试官意图:考察对事务传播行为源码级的理解

完整回答

会新建物理连接

DataSourceTransactionManagerhandleExistingTransaction() 处理 REQUIRES_NEW 时:

  1. suspend():从当前线程解绑旧的 ConnectionHolder,保存同步器列表、事务名称/只读/隔离级别到 SuspendedResourcesHolder
  2. doBegin():从连接池获取新的 Connection,setAutoCommit(false),绑定到当前线程
  3. 新事务在新连接上执行
  4. 执行完毕后,commit 新连接,归还到连接池
  5. resume():恢复被挂起的旧事务状态,重新绑定旧连接到线程

如果连接池只有一个连接,REQUIRES_NEW 会阻塞等待旧事务释放连接。

原理串联: **传播行为与隔离级别** → **DataSourceTransactionManager源码**


真题 5:Spring 事务默认回滚什么异常?会回滚 checked exception 吗?

面试官意图:考察对回滚规则机制的源码理解

完整回答

默认只回滚 RuntimeException 和 Error,checked exception(如 IOException、SQLException)不会触发回滚。

判断逻辑在 RuleBasedTransactionAttribute.rollbackOn()

  • 如果指定了 rollbackFor/noRollbackFor 规则,按规则匹配
  • 没有规则时,调用 DefaultTransactionAttribute.rollbackOn()return (ex instanceof RuntimeException || ex instanceof Error)

所以如果要回滚 checked exception,必须显式:@Transactional(rollbackFor = Exception.class)

原理串联: **事务高级特性(回滚规则)** → **TransactionInterceptor源码**


四、Spring Boot

真题 6:Spring Boot 和普通 Spring 启动流程的差异在哪?

面试官意图:考察对 Spring Boot 自动配置和容器启动的理解

完整回答

Spring Boot 在 SpringApplication.run() 中多做了:

  1. 推断 Web 应用类型(Reactive/Servlet/None)
  2. 加载 ApplicationContextInitializer(META-INF/spring.factories)
  3. 加载 ApplicationListener
  4. 自动装配:@EnableAutoConfiguration -> 加载 AutoConfiguration.imports -> 条件评估
  5. 内嵌 Web 服务器启动:onRefresh() 模板方法中启动 Tomcat/Jetty/Undertow

但核心的 refresh() 方法流程与普通 Spring 完全一致——ConfigurableApplicationContext.refresh() 这 12 步是相同的。

原理串联: **自动配置原理** → **refresh()启动流程**


真题 7:你自己写过 Starter 吗?具体步骤?

面试官意图:考察对自动配置机制的实战能力

完整回答

创建自定义 Starter 的 4 个步骤:

  1. 自动配置类:@Configuration + @ConditionalOnClass/@ConditionalOnMissingBean
  2. 属性类:@ConfigurationProperties(prefix = "xxx")
  3. 注册文件:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(Spring Boot 2.7+)
  4. 依赖管理:spring-boot-autoconfigure-processor 编译依赖

命名规范:官方用 spring-boot-starter-{name},三方用 {name}-spring-boot-starter

原理串联: **条件注解与定制Starter** → **自动配置原理**


五、Spring MVC + Security

真题 8:无状态 JWT 方案怎么处理 token 续期?怎么让 token 及时失效?

面试官意图:考察 JWT 无状态认证的工程实践

完整回答

续期方案

  • Refresh Token 模式:短期 Access Token(15-30min)+ 长期 Refresh Token(7-30天)
  • 滑动过期:每次请求检查剩余时间,小于阈值时重新签发

及时失效方案

  • 黑名单:Redis 维护登出 Token 黑名单,TTL 设为 Token 剩余有效期
  • 短有效期 + 频繁刷新:Access Token 5-15 分钟,配合 Refresh Token
  • 版本号:用户密码变更时递增,Token 携带版本号,服务端校验

原理串联: **JWT与OAuth2** → **认证流程**


六、Spring Cloud

真题 9:微服务架构下如何实现分布式事务?

面试官意图:考察分布式事务方案选型

完整回答

Seata 提供了三种模式:

  1. AT 模式(推荐优先):自动解析 SQL 生成 UNDO_LOG 回滚日志。两阶段提交——第一阶段执行 SQL + 记录回滚日志,第二阶段提交/根据 UNDO_LOG 回滚。对业务代码无侵入。

  2. TCC 模式:手动实现 Try(预留资源)/Confirm(确认)/Cancel(补偿)。性能更高但侵入性强。

  3. Saga 模式:适用于长业务流程,通过编排或 choreography 实现补偿操作。

选型建议:简单 CRUD 用 AT,高并发用 TCC,长流程用 Saga。

原理串联: **分布式事务** → **本地事务基础**


📚 相关链接

  • **面试高频100题** — 分板块面试题库
  • **面试知识体系总览** — 知识地图总览
  • ← 返回 **面试知识体系总览**

Knowledge4J — Java 知识库