一文彻底搞懂 Spring Bean(概念、生命周期、作用域、常见注解、源码原理、面试重点)
在 Spring 开发中,我们每天都会写:
java
@Service
public class UserService {}
@Autowired
private UserService userService;
但很多人其实并没有真正理解:
- Bean 到底是什么?
- Spring 是如何创建 Bean 的?
- Bean 生命周期有哪些阶段?
@Autowired是如何注入的?- 单例 Bean 是线程安全吗?
- Bean 是什么时候创建的?
本篇文章将系统讲清 Spring Bean 的核心知识体系。
一、什么是 Bean?
1 Bean 的概念
在 Spring 中,Bean 就是被 Spring 容器管理的对象。
简单理解:
Bean = 由 Spring 创建 + 管理 + 注入 的对象
例如:
java
@Service
public class UserService {}
Spring 在启动时会:
- 扫描到
@Service - 创建
UserService对象 - 存入容器
- 其他类可以通过
@Autowired使用
这个对象就是 Bean。
2 为什么需要 Bean?
如果没有 Spring:
java
UserService userService = new UserService();
会出现问题:
- 对象创建需要自己管理
- 对象依赖关系复杂
- 对象生命周期无法统一管理
而 Spring 通过 **IoC(控制反转)**解决了这些问题。
核心思想:
对象不由程序员创建
而是交给 Spring 容器创建
因此:
Bean = IoC 容器中的对象
二、Bean 的创建方式
Spring 创建 Bean 有多种方式。
1 注解方式(最常用)
Spring Boot 开发基本使用注解。
常见注解:
| 注解 | 作用 |
|---|---|
| @Component | 通用组件 |
| @Service | Service层 |
| @Repository | DAO层 |
| @Controller | 控制层 |
| @RestController | REST接口 |
示例:
java
@Service
public class UserService {
}
启动时 Spring 会自动扫描并注册 Bean。
2 @Bean 方式
适合:
- 第三方对象
- 配置类
示例:
java
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserService();
}
}
Spring 会把 userService() 的返回值注册为 Bean。
3 XML 配置(老项目)
早期 Spring 使用 XML:
xml
<bean id="userService" class="com.demo.UserService"/>
现在基本不用。
三、Bean 的作用域(Scope)
Spring Bean 默认是单例。
1 singleton(默认)
java
@Scope("singleton")
特点:
- 容器中只有 一个对象
- 所有地方共享
示例:
Controller -> Service -> Dao
三者使用同一个 Bean
优点:
- 节省内存
- 提高性能
2 prototype(多例)
java
@Scope("prototype")
特点:
- 每次获取 Bean 都创建新对象
示例:
java
@Autowired
UserService userService;
每次注入得到不同对象。
3 其他 Web 作用域
| scope | 说明 |
|---|---|
| request | 每个请求 |
| session | 每个会话 |
| application | 整个应用 |
四、Bean 生命周期(重点)
Spring Bean 生命周期是面试高频题。
完整流程如下:
1 BeanDefinition 注册
2 Bean 实例化
3 属性注入
4 Aware 回调
5 BeanPostProcessor 前置处理
6 初始化方法
7 BeanPostProcessor 后置处理
8 Bean 可用
9 容器关闭
10 Bean 销毁
我们逐步解释。
1 BeanDefinition 注册
Spring 启动时会:
- 扫描注解
- 解析 XML
- 注册 BeanDefinition
BeanDefinition 是:
Bean 的定义信息
包括:
- class
- scope
- lazy
- initMethod
2 Bean 实例化
Spring 使用反射创建对象:
java
UserService userService = new UserService();
3 属性注入
例如:
java
@Autowired
private OrderService orderService;
Spring 会进行:
依赖注入 DI
4 Aware 接口回调
如果 Bean 实现了:
BeanNameAware
BeanFactoryAware
ApplicationContextAware
Spring 会回调。
例如:
java
public class DemoBean implements BeanNameAware {
@Override
public void setBeanName(String name) {
System.out.println(name);
}
}
5 BeanPostProcessor 前置处理
Spring 提供扩展机制:
BeanPostProcessor
可以在 Bean 初始化前进行处理。
例如:
AOP
6 初始化方法
初始化方法有三种:
1 @PostConstruct
java
@PostConstruct
public void init(){
}
2 InitializingBean
java
public class DemoBean implements InitializingBean {
@Override
public void afterPropertiesSet() {
}
}
3 initMethod
java
@Bean(initMethod = "init")
7 BeanPostProcessor 后置处理
Spring 会再次调用:
postProcessAfterInitialization
例如:
AOP代理生成
8 Bean 可使用
此时 Bean 已经可以正常使用。
9 容器关闭
Spring 容器关闭:
ApplicationContext.close()
10 Bean 销毁
销毁方法:
1 @PreDestroy
java
@PreDestroy
public void destroy(){
}
2 DisposableBean
java
public void destroy()
五、Bean 生命周期总结(面试版)
Spring Bean 生命周期:
1 BeanDefinition 注册
2 实例化
3 属性注入
4 Aware回调
5 BeanPostProcessor before
6 初始化
7 BeanPostProcessor after
8 Bean使用
9 容器关闭
10 Bean销毁
面试回答建议简化为:
实例化 -> 依赖注入 -> 初始化 -> 使用 -> 销毁
六、Bean 依赖注入
Spring 注入 Bean 常见方式:
1 @Autowired
最常用。
java
@Autowired
private UserService userService;
默认 按类型注入。
2 @Qualifier
当存在多个 Bean:
java
@Autowired
@Qualifier("userServiceImpl")
3 @Resource
JDK 提供。
java
@Resource
private UserService userService;
默认 按名称注入。
七、Bean 加载时机
Spring Bean 默认:
容器启动时创建
称为:
Eager Loading
懒加载
java
@Lazy
@Service
public class UserService {}
只有使用时才创建。
八、Bean 的循环依赖(高频面试题)
例如:
A -> B
B -> A
Spring 使用:
三级缓存
解决。
三级缓存:
singletonObjects 一级缓存
earlySingletonObjects 二级缓存
singletonFactories 三级缓存
核心作用:
提前暴露对象
但只支持:
单例 + setter注入
九、Bean 常见易错点
1 @Autowired 失效
原因:
对象不是 Spring 管理
错误示例:
java
UserService service = new UserService();
解决:
必须由 Spring 注入
2 静态变量无法注入
错误:
java
@Autowired
static UserService userService;
Spring 不会注入 static。
3 单例 Bean 线程安全问题
Spring Bean 默认:
singleton
如果 Bean 内部有:
成员变量
可能产生 线程安全问题。
解决:
避免共享变量
十、Spring Bean 面试高频题
1 什么是 Spring Bean?
答:
Spring Bean 是被 Spring IoC 容器管理的对象。
2 Bean 生命周期?
答:
实例化 -> 属性注入 -> 初始化 -> 使用 -> 销毁
详细版本:
实例化
依赖注入
Aware回调
BeanPostProcessor
初始化
BeanPostProcessor
销毁
3 Bean 默认作用域?
singleton
4 如何创建 Bean?
三种:
@Component
@Bean
XML
5 Bean 单例线程安全吗?
不一定
取决于:
是否有共享变量
十一、Spring Bean 总结
Spring Bean 核心知识:
Bean = Spring容器管理的对象
核心内容:
Bean创建方式
Bean作用域
Bean生命周期
依赖注入
循环依赖
理解 Bean 的本质,其实就是理解:
Spring IoC 容器