spring的几个八股

bean生命周期

其实可以分成三个阶段来记:创建 → 初始化 → 销毁,初始化阶段是重点。

创建:反射调构造方法实例化,然后注入属性和依赖。

初始化:按顺序经历四步------

  1. Aware 回调(让 Bean 感知到容器,比如拿到 ApplicationContext)
  2. BeanPostProcessor 前置处理
  3. 执行初始化方法(@PostConstruct → afterPropertiesSet() → init-method,三选其一或叠加)
  4. BeanPostProcessor 后置处理 (AOP 代理在这里生成,返回代理对象替换原始 Bean)

销毁 :容器关闭时,执行销毁方法(@PreDestroy → destroy() → destroy-method)。

springboot启动

Spring Boot 启动的入口是 SpringApplication.run(),里面核心干了这几件事:

第一步,创建 SpringApplication 对象 :判断应用类型(是不是 Web 应用),加载 spring.factories 里的初始化器和监听器。

第二步,准备环境 :加载 application.yml / application.properties,处理命令行参数、环境变量,确定激活的 profile。

第三步,创建 Spring 容器 (ApplicationContext):根据应用类型创建对应的容器,Web 应用创建 AnnotationConfigServletWebServerApplicationContext。

第四步,刷新容器 (refresh()):这是最核心的一步------

  • 执行包扫描,注册你写的 Bean
  • 执行自动配置,把符合条件的自动配置类里的 Bean 也注册进来
  • 实例化所有单例 Bean,走完生命周期
  • 启动内嵌 Tomcat

第五步,启动完成 :发布 ApplicationReadyEvent,ApplicationRunner / CommandLineRunner 执行,服务就绪。

Spring 容器工作过程

复制代码
扫描 @Component 等注解
       ↓
注册 BeanDefinition(只登记类信息,不创建对象)
       ↓
实例化 Bean(反射调构造方法 new 出来)
       ↓
依赖注入(解析 @Autowired,从容器找对应 Bean,反射赋值)
       ↓
Aware 回调(让 Bean 感知容器,拿到 ApplicationContext 等)
       ↓
BeanPostProcessor 前置处理
       ↓
执行初始化方法(@PostConstruct → afterPropertiesSet → init-method)
       ↓
BeanPostProcessor 后置处理(AOP 代理在这里生成)
       ↓
放入容器,对外提供服务

第四步 refresh()

↓

实例化所有单例 Bean

↓

这里就是 Bean 的完整生命周期:

实例化(反射调构造方法)

↓

属性注入(@Autowired)

↓

Aware 回调(获取 Bean 名称、BeanFactory、环境信息等)

↓

BeanPostProcessor 前置处理(修改属性、检查配置)

↓

初始化方法(@PostConstruct)

↓

BeanPostProcessor 后置处理(生成代理)

↓

放入容器使用

↓

容器关闭时销毁(@PreDestroy)

自动配置

@EnableAutoConfiguration 会读取 META-INF/spring.factories 中的自动配置类。底层通过 ImportSelector 动态导入这些配置类,ImportSelector 会根据条件决定哪些配置类需要生效。

每个自动配置类通常配合条件注解,如 @ConditionalOnClass、@ConditionalOnMissingBean 或 @ConditionalOnProperty,只有满足条件的 Bean 才会注册到容器。

用户如果自己定义了同类型 Bean,会覆盖默认 Bean,从而实现可定制化。

注: 读取META-INF/spring.factories(Spring Boot 2.x)或 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@SpringBootApplication:是三个注解的组合:

  • @SpringBootConfiguration:标识这是配置类
  • @EnableAutoConfiguration:开启自动配置,读取 spring.factories 里的自动配置类按条件装载
  • @ComponentScan:扫描当前包及子包下所有 @Component、@Service、@Repository、@Controller 注解的类注册成 Bean

Spring 三级缓存解决循环依赖

先说为什么需要三级缓存,而不是直接说三个缓存是什么。

A 依赖 B,B 依赖 A,如果没有缓存机制,创建 A 时发现需要 B,去创建 B 时又发现需要 A,死锁了。解决思路是:A 实例化之后还没初始化完,先把自己暴露出去,让 B 能拿到 A 的引用,B 完成初始化后 A 再继续完成自己的初始化。


三个缓存分别存什么:

  • 一级缓存:完整的 Bean,初始化完成可以直接用
  • 二级缓存:半成品 Bean,实例化了但还没初始化完
  • 三级缓存:Bean 的 ObjectFactory,用来按需生成早期引用,如果需要 AOP 代理在这里生成

完整过程:

复制代码
创建 A,实例化后把 A 的 ObjectFactory 放入三级缓存
       ↓
A 注入属性,发现需要 B,去创建 B
       ↓
创建 B,实例化后把 B 的 ObjectFactory 放入三级缓存
       ↓
B 注入属性,发现需要 A,去三级缓存找到 A 的工厂
调用工厂拿到 A 的早期引用(需要代理就生成代理),放入二级缓存,删除三级缓存里的 A
       ↓
B 拿到 A 的早期引用,完成初始化,放入一级缓存
       ↓
回到 A,拿到完整的 B,A 完成初始化,放入一级缓存,删除二级缓存里的 A

为什么必须三级,二级不够:

实例化 → 属性注入 → 初始化 → BeanPostProcessor后置处理生成代理 → 放入容器

二级放 ObjectFactory:多个 Bean 依赖 A 时,每次调用工厂生成一个新代理,B 和 C 拿到的不是同一个对象,不一致。

A 实例化 → A 的 ObjectFactory 放入二级缓存

↓

A 注入属性,发现需要 B

↓

创建 B,B 注入属性发现需要 A

↓

B 调用二级缓存的 ObjectFactory 生成代理A1,注入给 B

↓

创建 C,C 注入属性发现需要 A

↓

C 调用二级缓存的 ObjectFactory 生成代理A2,注入给 C

↓

B 里持有代理A1,C 里持有代理A2,A1 和 A2 不是同一个对象 ← 问题

二级放原始对象:B 拿到原始 A,最终容器里放的是代理 A,B 持有的引用和容器里的不是同一个对象,不一致。

A 实例化 → 原始A放入二级缓存

↓

A 注入属性,发现需要 B

↓

创建 B,B 注入属性发现需要 A

↓

B 从二级缓存拿到原始A,注入进去,B 完成初始化

↓

回到 A,继续完成初始化

↓

BeanPostProcessor 后置处理 → 生成代理A

↓

代理A放入一级缓存

构造器注入无法解决:三级缓存的前提是先实例化再注入,构造器注入是实例化时就要注入,A 还没 new 出来就需要 B,放不进三级缓存,直接报错。

相关推荐
acd120092 分钟前
Nginx 反向代理的缓冲区坑:后端响应大时接口偶发 502
java·运维·nginx
装不满的克莱因瓶4 分钟前
支付订单成功异步MQ权益发放设计和开发
java·架构·系统架构·rabbitmq·硬件架构
掘金者阿豪11 分钟前
MongoDB迁移到金仓数据库:商品属性继续灵活存,订单报表交给 SQL
前端·后端
zhoujungis12 分钟前
限流算法实测:固定窗口 2 倍溢出、令牌桶突刺 | 尘世栈帧
后端
高冷小鱼殿下23 分钟前
内部类Lambda与枚举
java·开发语言
小蒜学长1 小时前
编程语言在线学习平台的设计与实现(代码+数据库+LW)
java·spring boot·后端·编程语言在线学习平台·在线编码
Flynn Liang1 小时前
Spring AI 多模态实战(下):文生图 + TTS 语音合成(含 2.0 流式音频分片)
人工智能·spring·文生图·音视频·语音合成·tts·springai
步行cgn1 小时前
Spring MVC 执行流程详解:一次请求的完整旅程
java·spring·mvc
增量星球2 小时前
Spring AI 2.0 Tool Calling 到底怎么跑起来的:从 @Tool 到两次模型调用
java·agent·springai·ai coding
步行cgn2 小时前
Spring MVC 九大核心角色详解:请求处理链路中的每一个关键组件
java·spring·mvc