spring-Bean

Bean是什么?

Bean 就是 Spring IOC 容器管理的对象,交给 Spring 创建、装配、生命周期管理的 Java 对象就叫 Bean;自己new出来的对象不属于 Spring Bean。

如何定义 Bean?(三种配置方式)

Spring 提供三种方式来声明 Bean,现在企业开发中注解驱动是主流:

|--------------|------------------------|------------------------------------------------|
| 方式 | 适用场景 | 示例 |
| XML 配置(老旧) | 遗留系统维护,或需要引入第三方无法改源码的类 | <bean id="userDao" class="com.dao.UserDao"/> |
| 注解定义(最常用) | 自己编写的类,直接在类上加注解 | @Component、@Service、@Repository、@Controller |
| Java 配置类(推荐) | 第三方类或需要复杂构造逻辑的 Bean | @Configuration + @Bean 写在方法上 |

@Component 和 @Bean 区别

  1. @Component:打在类上,适合自己写的业务类;由组件扫描自动发现。

  2. @Bean:打在配置类的方法上;适合第三方组件,类源码不能修改,无法加 @Component。

Bean 的作用域 scope

Spring 默认是 单例(Singleton)。

|---------------|------------------------------------|---------------------------------|
| 作用域 | 含义 | 适用场景 |
| singleton(默认) | 整个 IoC 容器中只有一个实例,所有地方共用。 | 无状态的 Service、Dao(绝大多数业务场景)。 |
| prototype | 每次从容器中 getBean() 或注入时,都新建一个实例。 | 有状态的对象(如每次请求参数不同的实体)。 |
| request | 仅对当前 HTTP 请求有效,每个请求新建一个。 | Web 层,如当前登录用户信息对象。 |
| session | 仅对当前 HTTP Session 有效。 | 用户会话级别的购物车对象。 |

Bean 完整生命周期

  1. 解析配置:扫描类,生成 BeanDefinition

  2. 实例化:反射调用构造方法,new 出空对象(此时属性还没赋值)

  3. 依赖注入 DI:给属性赋值,装配 @Autowired 依赖

  4. Aware 接口回调:BeanNameAware、ApplicationContextAware,把容器 /beanName 注入给 bean

  5. 初始化阶段

  6. ① @PostConstruct 注解方法 ② InitializingBean#afterPropertiesSet() ③ @Bean(initMethod = "xxx") 指定初始化方法

  7. Bean 就绪,可以给业务使用

  8. 容器关闭销毁 ① @PreDestroy ② DisposableBean#destroy() ③ @Bean(destroyMethod="xxx")

BeanDefinition

实例化

属性注入

Aware 回调

BeanPostProcessor

初始化

BeanPostProcessor

Bean 可以使用

容器关闭

销毁

解决一个经典难题:循环依赖(三级缓存)

如果是单例 Bean,Spring 能解决 Setter 注入造成的循环依赖(如 A 依赖 B,B 依赖 A)。它利用的是三级缓存(singletonFactories),在对象实例化后、属性填充前,先把"半成品对象"提前曝光出来,从而打破闭环。

一级缓存 `singletonObjects`:完全初始化完毕的 Bean

二级缓存 `earlySingletonObjects`:实例化完成,但还没填充属性的对象,避免重复执行代理

三级缓存 `singletonFactories`:lambda 工厂,提前暴露对象引用,有可能生成代理对象

注意:构造器注入的循环依赖无法解决,Spring 会直接报错。因此,官方推荐使用 Setter 注入或字段注入来规避构造器循环依赖。

相关推荐
深入云栈28 分钟前
Netty 4.2.x 源码深度解析 (十一):EventExecutor 业务线程池 —— 防止 IO 线程阻塞的并发模型
java·后端
吴声子夜歌32 分钟前
Java——基本类型
java·开发语言
柠檬味拥抱36 分钟前
鸿蒙 AI 对话实战:用蓝耘 MaaS 给礼物 App 装上「多轮对话选礼大脑」
后端
唐青枫41 分钟前
别再把 build.zig 当配置文件:Zig 构建系统从零到实战
后端
Naylor43 分钟前
只借不占:Rust 的引用与借用
后端·rust
大勇前进1 小时前
Python装饰器、生成器、上下文管理器:3个必会的"魔法"机制
后端
Go_error1 小时前
Fyne:让 Go 开发者也能玩转 GUI
后端·go
用户0795675043141 小时前
Python + OpenCV 识别 GIF 中旋转最快的图形:基于时间周期的动态识别
后端
长大19881 小时前
Python+Flask 1小时搭建个人博客:比WordPress轻量10倍
后端