【Spring】Bean的生命周期详解

一文彻底搞懂 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 在启动时会:

  1. 扫描到 @Service
  2. 创建 UserService 对象
  3. 存入容器
  4. 其他类可以通过 @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 容器
相关推荐
冬夜戏雪1 小时前
面经摘录(五)
java·后端·spring
李昊哲小课1 小时前
Python CSV 模块完整教程
java·服务器·python
人道领域2 小时前
苍穹外卖:菜品分页查询与删除功能(保姆级详解)
java·开发语言·数据库·后端·spring
亚马逊云开发者2 小时前
MCP 到底是什么?一篇讲透:协议原理 + Bedrock 实战 + 安全防护
java
年少无为呀!2 小时前
OpenClaw 飞书 Skill 开发完全指南
python·机器人·飞书·助手·openclaw·skill开发
0和1的舞者2 小时前
高并发论坛系统:单元测试 + 接口自动化 + 性能测试 + CI/CD 全链路测试报告
java·测试开发·测试工具·jmeter·pytest·测试·测试报告
空空kkk3 小时前
Java基础——代理
java·开发语言
赵谨言3 小时前
基于YOLOv5的植物目标检测研究
大数据·开发语言·经验分享·python
野生技术架构师3 小时前
互联网大厂必备 Java 面试八股文真题解析
java·开发语言·面试