Spring Bean 详解

Spring 的核心是依赖注入(Dependency Injection, DI)和面向切面编程(Aspect-Oriented Programming, AOP)。

在 Spring 框架中,Bean 是一个核心概念,是Spring管理的基本单位。

本文将详细介绍 Spring Bean 的相关内容,包括其定义、生命周期、配置方式和常见用法。


什么是 Spring Bean

在 Spring 框架中,Bean 是由 Spring IoC 容器管理的对象。

简单来说,任何一个由 Spring 容器初始化、装配和管理的对象都可以被称为 Spring Bean。

Bean 是应用程序的核心构建块,通过配置文件或者注解来定义,Spring 容器负责它们的生命周期和依赖关系。


Spring Bean 的生命周期

Spring Bean 的生命周期包括以下几个阶段:

  1. 实例化(Instantiation):Spring 容器通过反射机制创建 Bean 的实例。
  2. 属性赋值(Populate Properties):Spring 容器将配置文件中指定的属性赋值给 Bean。
  3. 初始化(Initialization):如果 Bean 实现了 InitializingBean 接口,会调用其 afterPropertiesSet() 方法;如果 Bean 在配置文件中通过 init-method 属性指定了初始化方法,会调用该方法。
  4. 使用(Usage):Bean 已经准备好,可以被应用程序使用。
  5. 销毁(Destruction):如果 Bean 实现了 DisposableBean 接口,会调用其 destroy() 方法;如果 Bean 在配置文件中通过 destroy-method 属性指定了销毁方法,会调用该方法。

Spring Bean 的配置方式

Spring 提供了多种方式来配置 Bean,主要包括 XML 配置、注解配置和 Java 配置。

使用 XML 配置

XML 配置是最传统的 Spring Bean 配置方式,通过在 applicationContext.xml 文件中定义 Bean。

1
2
3
4
5
6
7
8
9
10
11
12
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="exampleBean" class="com.example.ExampleBean">
<property name="property1" value="value1"/>
<property name="property2" ref="anotherBean"/>
</bean>

<bean id="anotherBean" class="com.example.AnotherBean"/>
</beans>

使用注解配置

注解配置利用注解来定义和装配 Bean,通常与 @ComponentScan 注解结合使用。

1
2
3
4
5
6
7
8
9
10
11
12
@Component
public class ExampleBean {
@Autowired
private AnotherBean anotherBean;

// getters and setters
}

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}

@Service,@Repository,@Controller可以视为@Component的别名,功能上是一致的,只是用于标记不同的场合。

使用 Java 配置

Java 配置是基于 @Configuration 注解和 @Bean 注解的方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
@Configuration
public class AppConfig {

@Bean
public ExampleBean exampleBean() {
return new ExampleBean(anotherBean());
}

@Bean
public AnotherBean anotherBean() {
return new AnotherBean();
}
}

Spring Bean 的作用域

Spring Bean 的作用域决定了 Bean 的生命周期和可见范围。Spring 提供了几种常见的作用域:

  1. singleton(默认):容器中只有一个共享的 Bean 实例。
  2. prototype:每次请求都会创建一个新的 Bean 实例。
  3. request:每个 HTTP 请求都会创建一个新的 Bean 实例,仅适用于 Web 应用。
  4. session:每个 HTTP 会话都会创建一个新的 Bean 实例,仅适用于 Web 应用。
  5. application:在 ServletContext 范围内,一个 Bean 定义对应一个实例。
  6. websocket:每个 WebSocket 会话都会创建一个新的 Bean 实例。

设置作用域

配置 Bean 的作用域可以通过 XML 配置或注解配置:

XML 配置

1
<bean id="exampleBean" class="com.example.ExampleBean" scope="prototype"/>

注解配置

1
2
3
4
5
@Scope("prototype")
@Component
public class ExampleBean {
// ...
}

@Scope 可以添加在@Component、@Bean、@…等用于标记Bean的注解附近,用于标注作用域


Spring Bean 的依赖注入

依赖注入是 Spring 框架的核心功能之一,用于减少类之间的耦合性。Spring 支持多种依赖注入方式:

  1. 构造器注入:通过构造函数注入依赖。
  2. Setter 方法注入:通过 Setter 方法注入依赖。
  3. 字段注入:通过字段直接注入依赖(通常使用 @Autowired 注解)。

构造器注入

1
2
3
4
5
6
7
8
9
@Component
public class ExampleBean {
private final AnotherBean anotherBean;

@Autowired
public ExampleBean(AnotherBean anotherBean) {
this.anotherBean = anotherBean;
}
}

Setter 方法注入

1
2
3
4
5
6
7
8
9
@Component
public class ExampleBean {
private AnotherBean anotherBean;

@Autowired
public void setAnotherBean(AnotherBean anotherBean) {
this.anotherBean = anotherBean;
}
}

字段注入

1
2
3
4
5
@Component
public class ExampleBean {
@Autowired
private AnotherBean anotherBean;
}

Spring Bean 的常见用法

Spring Bean 在实际开发中有许多常见的用法:

  1. Service 层:使用 @Service 注解定义业务逻辑层的 Bean。
  2. Repository 层:使用 @Repository 注解定义数据访问层的 Bean。
  3. Controller 层:使用 @Controller 注解定义控制层的 Bean。
  4. 配置类:使用 @Configuration 注解定义配置类 Bean。

Service 层

1
2
3
4
@Service
public class UserService {
// 业务逻辑
}

Repository 层

1
2
3
4
@Repository
public class UserRepository {
// 数据访问逻辑
}

Controller 层

1
2
3
4
5
6
7
8
9
10
11
@Controller
public class UserController {
@Autowired
private UserService userService;

@RequestMapping("/user")
public String getUser(Model model) {
model.addAttribute("user", userService.getUser());
return "user";
}
}

配置类

1
2
3
4
5
6
7
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserService();
}
}