1. Spring Bean 的生命周期是怎样的?
答案:
- 实例化 Bean(反射构造方法)
- 填充属性(依赖注入 @Autowired、setter)
- 执行 Aware 接口方法
- BeanNameAware
- BeanFactoryAware
- ApplicationContextAware
- 执行 BeanPostProcessor#postProcessBeforeInitialization
- 执行初始化方法
- @PostConstruct
- InitializingBean#afterPropertiesSet
- init-method
- 执行 BeanPostProcessor#postProcessAfterInitialization(AOP 代理在这里生成)
- Bean 就绪,可使用
- 容器关闭时销毁
- @PreDestroy
- DisposableBean#destroy
- destroy-method
2. Spring IOC 是如何解决循环依赖的?
答案:
- 只支持 单例 Bean 的 setter / 字段注入循环依赖
- 核心靠 三级缓存 :
- singletonObjects:成品 Bean
- earlySingletonObjects:提前曝光的原始 Bean
- singletonFactories:Bean 工厂,用于生成提前引用
- 流程:A 创建 → 放入三级缓存 → 填充 B → B 创建 → 填充 A → 从三级缓存拿到 A 原始对象 → B 完成 → A 完成
- 不支持的场景 :
- 原型(prototype)Bean
- 构造方法注入循环依赖
- 代理对象导致的循环依赖(某些场景会报错)
3. Spring AOP 底层原理是什么?什么时候用 JDK 动态代理 / CGLIB?
答案:
- 底层是 动态代理
- JDK 动态代理:目标类实现接口 → 生成接口的代理类
- CGLIB 代理:目标类没有接口 → 生成目标类的子类代理
- Spring Boot 2.0+ 默认对所有单例 Bean 使用 CGLIB,即使有接口也可以用 CGLIB。
4. @Transactional 事务失效场景有哪些?
答案:
- 同类内部方法调用(this.method ()),不走代理
- 方法不是 public
- 异常被 try-catch 吃掉,没有抛出
- 抛出非 RuntimeException/Error(默认只回滚运行时异常)
- 多线程调用,不在同一个事务上下文
- Bean 没有被 Spring 管理(不是 Bean)
- 传播机制设置错误,如 NOT_SUPPORTED、NEVER
- 数据库引擎不支持事务(如 MyISAM)
5. Spring 事务传播机制有哪些?核心区别?
答案:
- REQUIRED(默认):有事务就加入,没有就新建
- REQUIRES_NEW:新建事务,挂起当前事务
- SUPPORTS:有事务就用,没有就非事务执行
- NOT_SUPPORTED:始终非事务,挂起事务
- MANDATORY:必须在事务内执行,否则抛异常
- NEVER:必须非事务,否则抛异常
- NESTED:嵌套事务,保存点机制,外层回滚则内层回滚,内层异常不影响外层
6. Spring MVC 执行流程(完整链路)
答案:
- 请求 → DispatcherServlet
- HandlerMapping 找到对应 Controller 方法
- HandlerAdapter 调用方法
- 参数解析、数据绑定、校验
- 执行 Controller 业务
- 返回 ModelAndView / 直接返回 JSON
- 视图解析器解析视图
- 渲染页面 / 返回 JSON
- 响应给客户端
7. Spring Boot 自动配置原理
答案:
@SpringBootApplication组合注解@EnableAutoConfiguration开启自动配置- 读取
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports - 根据条件注解
@ConditionalOnXXX判断是否加载配置类 - 自动创建 Bean 并注入容器
常用条件:
- @ConditionalOnClass
- @ConditionalOnBean
- @ConditionalOnMissingBean
- @ConditionalOnProperty
8. Spring 中 BeanFactory 和 FactoryBean 区别?
答案:
- BeanFactory:IOC 容器顶层接口,负责生产、管理 Bean
- FactoryBean :一个特殊 Bean,用于复杂对象创建实现 FactoryBean 接口,重写 getObject () 返回自定义对象
- 使用场景:MyBatis 的
MapperFactoryBean、Feign 代理对象等
9. Spring 是怎么解决 Bean 并发安全问题的?
答案:
- Spring Bean 默认 单例 singleton,无状态则线程安全
- 有状态(成员变量存数据)不安全
- 解决方案:
- 改为 prototype
- 使用 ThreadLocal 存状态
- 使用 request/session 作用域
- 避免在 Bean 中定义可变成员变量
10. @Autowired、@Resource、@Inject 区别
答案:
- @Autowired(Spring):默认 byType,可配合 @Qualifier byName
- @Resource(JSR-250):默认 byName,找不到再 byType
- @Inject(JSR-330):类似 @Autowired,但没有 required 属性优先级:@Resource 更稳定,适合跨框架
11. Spring 事务是如何实现的?
答案:
- 基于 AOP 代理
- 拦截 @Transactional 方法
- 通过
PlatformTransactionManager如 DataSourceTransactionManager - 核心流程:获取连接 → 关闭自动提交 → 执行业务 → 提交 / 回滚 → 释放连接
12. Spring 中用到了哪些设计模式?
答案:
- 单例模式:Bean 默认单例
- 工厂模式:BeanFactory
- 代理模式:AOP
- 模板方法:JdbcTemplate、RedisTemplate
- 策略模式:资源加载器、事务管理器
- 观察者模式:ApplicationEvent 事件监听
- 适配器模式:HandlerAdapter
- 装饰器模式:BeanWrapper
13. Spring 如何实现 Bean 的延迟加载?
答案:
@Lazy注解- 作用:容器启动时不实例化,第一次使用时才创建
- 场景:项目启动慢、Bean 初始化很重、依赖复杂
14. Spring 事件机制原理
答案:
- 基于 观察者模式
- 定义事件 extends ApplicationEvent
- 定义监听器 implements ApplicationListener 或 @EventListener
- 发布事件:applicationContext.publishEvent (event)
- 同步 / 异步执行(@Async)
15. Spring Boot 启动流程简述
答案:
- 执行 SpringApplication.run ()
- 推断 Web 类型(Servlet/Reactive)
- 加载并初始化 Spring 容器
- 执行 ApplicationContextInitializer
- 刷新容器:扫描 Bean → 自动配置 → 创建单例 Bean
- 执行 CommandLineRunner / ApplicationRunner
- 启动 Web 服务器(Tomcat/Netty)
- 应用启动完成