Spring Bean 详解
在 Spring 框架中,Bean 是 Spring IoC(控制反转)容器管理的核心对象,表示由容器实例化、组装和管理的组件。Spring Bean 通常用于定义应用程序中的业务逻辑或配置组件。
1. 什么是 Spring Bean?
- 定义:Spring Bean 是由 Spring 容器初始化、装配和管理的对象。
- 作用:Bean 通常是服务层组件、DAO 层组件或其他业务逻辑对象。
- 生命周期:Bean 的生命周期由 Spring 容器管理,从实例化到销毁。
2. Spring Bean 的定义方式
Spring 提供了多种方式定义 Bean。
2.1 XML 配置
最传统的方式,通过 XML 文件声明 Bean。
示例:
<beans xmlns="http://www.springframework.org/schema/beans" ...>
<bean id="myBean" class="com.example.MyBean">
<property name="name" value="Spring Bean"/>
</bean>
</beans>
id
:Bean 的唯一标识符。class
:Bean 的实现类。property
:用于设置 Bean 的属性值。
2.2 注解配置
通过注解方式声明和管理 Bean,推荐使用。
1. @Component
- 将类标记为 Spring 容器的 Bean。
@Component
public class MyBean {
private String name = "Spring Bean";
}
2. @Controller
, @Service
, @Repository
- 是
@Component
的派生注解,用于标识控制器、服务层和数据访问层。
@Service
public class MyService {
public void doSomething() {
System.out.println("Service is working!");
}
}
3. @Configuration
和 @Bean
- 使用 Java 配置类定义 Bean。
@Configuration
public class AppConfig {
@Bean
public MyBean myBean() {
return new MyBean();
}
}
2.3 自动装配(@Autowired
)
Spring 提供了自动装配功能来简化依赖注入。
@Component
public class MyService {
@Autowired
private MyRepository myRepository;
}
@Autowired
:自动装配依赖项。@Qualifier
:用于指定具体的 Bean。@Primary
:在多个候选 Bean 中指定优先使用的 Bean。
2.4 Spring Boot 中的自动配置
在 Spring Boot 中,可以通过 @SpringBootApplication
开启自动配置,并自动扫描 Bean。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3. Spring Bean 的作用域
Spring 支持多种 Bean 的作用域,决定了 Bean 的生命周期和可见性。
作用域 | 描述 |
---|---|
singleton | (默认)在容器中只创建一个实例,所有请求共享该实例。 |
prototype | 每次请求都会创建一个新的实例。 |
request | 每个 HTTP 请求都会创建一个新的实例(仅适用于 Web 应用)。 |
session | 每个 HTTP 会话创建一个实例(仅适用于 Web 应用)。 |
application | ServletContext 的生命周期内创建一个实例(仅适用于 Web 应用)。 |
示例:
@Component
@Scope("prototype")
public class PrototypeBean {
// 每次注入都会创建新的实例
}
4. Spring Bean 的生命周期
Spring 容器对 Bean 的生命周期有完整的管理流程。
4.1 生命周期流程
- 实例化:使用构造函数或工厂方法创建对象。
- 属性赋值:通过依赖注入(DI)设置属性。
- 初始化:调用自定义初始化方法。
- 使用:Bean 准备好被使用。
- 销毁:容器关闭时,调用销毁方法。
4.2 生命周期回调
@PostConstruct
和@PreDestroy
- Java 提供的生命周期回调注解。
@Component
public class MyBean {
@PostConstruct
public void init() {
System.out.println("Bean is initialized");
}
@PreDestroy
public void destroy() {
System.out.println("Bean is destroyed");
}
}
InitializingBean
和DisposableBean
接口- Spring 提供的生命周期接口。
@Component
public class MyBean implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Bean is initialized");
}
@Override
public void destroy() throws Exception {
System.out.println("Bean is destroyed");
}
}
@Bean(initMethod, destroyMethod)
- 在 Java 配置类中指定初始化和销毁方法。
@Configuration
public class AppConfig {
@Bean(initMethod = "init", destroyMethod = "cleanup")
public MyBean myBean() {
return new MyBean();
}
}
5. 依赖注入(DI)
Spring 通过 IoC 容器提供依赖注入(Dependency Injection)。
5.1 构造器注入
通过构造器注入依赖。
@Component
public class MyService {
private final MyRepository myRepository;
@Autowired
public MyService(MyRepository myRepository) {
this.myRepository = myRepository;
}
}
5.2 Setter 注入
通过 Setter 方法注入依赖。
@Component
public class MyService {
private MyRepository myRepository;
@Autowired
public void setMyRepository(MyRepository myRepository) {
this.myRepository = myRepository;
}
}
6. Bean 的注入方式
6.1 按类型注入
通过 Bean 的类型查找和注入。
@Autowired
private MyBean myBean;
6.2 按名称注入
通过 Bean 的名称查找和注入。
@Autowired
@Qualifier("myBean")
private MyBean myBean;
6.3 手动注入
通过 Spring 上下文手动获取 Bean。
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MyBean myBean = context.getBean(MyBean.class);
7. Spring Bean 的重要特性
7.1 可配置性
Bean 的属性可以通过 XML、Java 配置或注解动态配置。
7.2 可扩展性
- 自定义 BeanPostProcessor:
- 在 Bean 初始化和销毁前后执行自定义逻辑。
- 自定义 BeanFactoryPostProcessor:
- 在 Bean 工厂初始化后修改 Bean 的定义。
8. 示例:综合使用 Spring Bean
// Bean 定义
@Component
@Scope("singleton")
public class MyBean {
public void doSomething() {
System.out.println("Doing something...");
}
}
// 服务类
@Service
public class MyService {
@Autowired
private MyBean myBean;
public void execute() {
myBean.doSomething();
}
}
// 配置类
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {}
// 主类
public class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MyService service = context.getBean(MyService.class);
service.execute();
}
}
9. 总结
Spring Bean 是 Spring IoC 容器管理的核心组件,它支持多种定义和配置方式,并提供了强大的生命周期管理和依赖注入功能。通过合理使用 Spring Bean,可以显著提高应用程序的模块化、可配置性和可扩展性。