38. @Bean注解如何使用?
大约 3 分钟
@Bean
注解是 Spring 中用于定义 Spring 容器管理的 Bean 的一种方式。它通常用在配置类(@Configuration
注解的类)中,方法上加上 @Bean
注解,Spring 容器会自动调用这些方法,并将其返回的对象注册为 Spring 容器中的 Bean。与自动扫描和注解(如 @Component
)不同,@Bean
注解提供了更为显式和灵活的 Bean 定义方式。
1. 基本用法
在配置类中使用 @Bean
注解定义一个 Bean:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
- 配置类:使用
@Configuration
注解将一个类标记为配置类,Spring 会将其作为配置类进行处理。 @Bean
注解的方法:标记的方法返回的对象会被注册为 Spring 容器中的 Bean,方法名作为 Bean 的默认名称。
2. 自定义 Bean 名称
默认情况下,@Bean
注解的方法名就是 Bean 的名称。如果想要自定义 Bean 名称,可以在 @Bean
注解中使用 name
属性:
@Bean(name = "customService")
public MyService myService() {
return new MyServiceImpl();
}
- 自定义名称:上面的示例中,
myService
方法返回的 Bean 在容器中的名称为"customService"
。
3. 依赖注入
使用 @Bean
注解时,可以通过方法参数来注入其他的 Bean:
@Bean
public MyService myService(MyRepository myRepository) {
return new MyServiceImpl(myRepository);
}
- 参数注入:在这个例子中,
MyServiceImpl
需要一个MyRepository
的实例作为构造参数。Spring 会自动注入容器中已存在的MyRepository
Bean。
4. Bean 的作用域
默认情况下,@Bean
定义的 Bean 是单例(singleton)的。可以通过 @Scope
注解来指定不同的作用域,如 prototype
、request
、session
等:
import org.springframework.context.annotation.Scope;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public MyService myService() {
return new MyServiceImpl();
}
- 作用域:
@Scope
注解用来指定 Bean 的作用域。常见的作用域包括:singleton
:单例模式,在 Spring 容器中只有一个实例(默认)。prototype
:每次请求都会创建一个新的实例。request
:为每个 HTTP 请求创建一个实例(仅在 Web 应用中有效)。session
:为每个 HTTP 会话创建一个实例(仅在 Web 应用中有效)。
5. 初始化和销毁回调
可以为 @Bean
注解定义的 Bean 指定初始化方法和销毁方法,这些方法会在 Bean 初始化或销毁时自动调用:
@Bean(initMethod = "init", destroyMethod = "cleanup")
public MyService myService() {
return new MyServiceImpl();
}
initMethod
:指定 Bean 初始化时调用的方法。destroyMethod
:指定 Bean 销毁时调用的方法。
6. 条件注解
可以结合条件注解(如 @Conditional
)来实现条件性地创建 Bean:
import org.springframework.context.annotation.Conditional;
@Bean
@Conditional(MyCondition.class)
public MyService myService() {
return new MyServiceImpl();
}
@Conditional
:根据条件动态决定是否创建这个 Bean。条件的判断逻辑通常通过实现Condition
接口来定义。
7. 配置类之间的依赖
在一个配置类中可以依赖另一个配置类中的 Bean:
@Configuration
public class AppConfig {
@Bean
public MyRepository myRepository() {
return new MyRepositoryImpl();
}
@Bean
public MyService myService(MyRepository myRepository) {
return new MyServiceImpl(myRepository);
}
}
- Bean 依赖:
myService
方法通过参数注入了myRepository
,Spring 会确保myRepository
先于myService
被创建。
8. 完整示例
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean(name = "myService", initMethod = "init", destroyMethod = "cleanup")
public MyService myService(MyRepository myRepository) {
return new MyServiceImpl(myRepository);
}
@Bean
public MyRepository myRepository() {
return new MyRepositoryImpl();
}
}
在这个完整示例中,我们定义了两个 Bean:myService
和 myRepository
。myService
依赖于 myRepository
,并且指定了初始化和销毁方法。
9. 总结
@Bean
注解用于显式定义 Spring 容器中的 Bean。- 可以通过方法参数、
@Scope
、initMethod
、destroyMethod
等来灵活地管理 Bean 的生命周期和依赖关系。 @Bean
通常与配置类一起使用,这些配置类使用@Configuration
注解进行标注。