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 注入或字段注入来规避构造器循环依赖。

相关推荐
根目录下的猫5 小时前
RK3588适配的轻量级AI模型推荐
人工智能·后端·python·目标检测
景熙55235 小时前
15.Java 8 Stream 流入门到实战
java·开发语言·数据结构
wno7045 小时前
Spring Security权限控制
java·python·spring
星栈6 小时前
用 Rust 写 Agent 服务 -- adk-rust 上手记
后端·agent
杨运交6 小时前
[071][验证码模块]基于Spring拦截器的验证码认证设计思想
java·后端·spring
Geek-Chow6 小时前
CountDownLatch in Java
java
LucianaiB7 小时前
我用豆包工作 Seed-2.1-pro,复刻了 QQ 时代爆红的魔术图片
后端
码事漫谈7 小时前
智谱 ZCode 静默上传 Git 历史:48 小时信任危机复盘
后端
SL_staff7 小时前
从RBAC到场景化授权:《无忧·企业文档》三级权限模型的技术实践解析
java·开源·产品
掘金码甲哥7 小时前
当对话模型遇上向量模型,vllm production stack 又该如何应对?
后端