Bean 是 Spring 最核心的概念,但很多人(包括当初的我)搞不清它到底是"方法"还是"类"。这篇把 Bean 的本质讲清楚:它既不是方法也不是类,而是"容器管理的对象实例";再讲清 @Component 和 @Bean 两种定义方式的区别。
一、Bean 是什么:容器管理的对象
先分清三个概念:
| 概念 | 是什么 |
|---|---|
| 类(class) | 模板/蓝图,比如 GreetingService |
| 方法 | 工厂方法,负责"怎么创建对象" |
| Bean | 由 Spring 容器创建并管理的对象实例 |
一句话:Bean = 交给 Spring 容器管理的对象。你 new 出来的对象不是 Bean(Spring 不管它),但交给 Spring 创建并放进容器的对象就是 Bean。
GreetingService s1 = new GreetingService(); // 普通对象,不是 Bean(Spring 不管)
@Service
class GreetingService { ... } // 交给 Spring,创建出来的实例是 Bean二、三种定义 Bean 的方式
方式一:@Component / @Service 等,注解在类上
@Service // 注解在类上:这个类交给 Spring,扫描时实例化
public class UserService {
public void save() { ... }
}Spring 启动时扫描到 @Service,自动 new UserService() 放进容器。这是最常用的方式——你自己的类都这么干。
方式二:@Bean,注解在方法上
@Configuration
public class AppConfig {
@Bean // 注解在方法上:返回值交给 Spring
public RedisTemplate redisTemplate() { // 方法名 = Bean 名字
return new RedisTemplate(); // 返回的对象 = Bean
}
}@Bean 注解在方法上,但方法本身不是 Bean——方法的返回值才是 Bean。方法名是 Bean 的名字,方法体是"怎么创建"。
方式三:XML <bean> 配置(老方式,现在很少用):
<bean id="userService" class="com.example.UserService" />三、@Component vs @Bean 怎么选
这是最容易混的点,核心区别:
| 维度 | @Component(类上) | @Bean(方法上) |
|---|---|---|
| 注解位置 | 类 | 方法 |
| Bean 来源 | 这个类的实例 | 方法的返回值 |
| 谁能用 | 你自己的类(能改源码) | 第三方类(改不了源码) |
| 场景 | 业务类、Service、Controller | 第三方库的对象(RedisTemplate 等) |
关键:你的类能加 @Component;但第三方库的类(RedisTemplate、RestTemplate、DataSource)你改不了源码、加不了 @Component,就用 @Bean 方法手动 new 出来交给 Spring。
这就是为什么《Spring Boot 自动配置原理》里全是 @Bean 方法——自动配置要创建的全是第三方库的对象,只能用 @Bean 方法。
四、Bean 的作用域
Bean 默认是单例(singleton),也可以配置成其他作用域:
| 作用域 | 含义 |
|---|---|
singleton(默认) | 整个容器只有一个实例 |
prototype | 每次获取都新建一个实例 |
@Scope("prototype") // 每次获取都 new 一个
@Component
public class User { ... }默认单例就是之前《单例模式》里讲的"Spring 容器缓存"——容器把 Bean 存进缓存池,大家拿到的都是同一个。
五、Bean 的生命周期(简带)
Bean 从创建到销毁,会经过几个阶段:
实例化(new) → 依赖注入 → 初始化(@PostConstruct) → 使用 → 销毁(@PreDestroy)了解即可,日常用到最多的是 @PostConstruct(初始化后干点事,比如加载缓存)。
小结
- Bean = Spring 容器创建并管理的对象实例,不是方法也不是类
- 三种定义方式:
@Component(类上)、@Bean(方法上,返回值是 Bean)、XML - 自己的类用
@Component,第三方类用@Bean方法 - 默认单例,
@Scope("prototype")改成每次新建
理解了 Bean,再回头看《Spring Boot 自动配置原理》就通了——自动配置本质就是"用 @Bean 方法自动帮你建好那些 Bean"。
