1. Bean 的作用域
作用域名称 | 说明 | 生效环境 |
---|---|---|
singleton | 单例作用域 | 通用 Spring 环境 |
prototype | 原型作用域(多例作用域) | 通用 Spring 环境 |
request | 请求作用域,每一个 HTTP 请求周期内创建新的实例 | web 环境 |
session | 会话作用域,每一个 HTTP session 生命周期内,创建新的实例 | web 环境 |
Application | 全局作用域,每一个 ServletContext 生命周期内,创建新的实例 | web 环境 |
websocket | WebSocket 作用域 | web 环境 |
通过@Scope
注解来指定作用域:
Java
@Configuration
public class DogConfig {
@Bean
public Dog dog() {
Dog dog = new Dog();
dog.setName("旺财");
return dog;
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public Dog singleDog() {
return new Dog();
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Dog prototypeDog() {
return new Dog();
}
}
Java
@RestController
@RequestMapping("/scope")
public class ScopeController {
@Resource(name = "singleDog")
private Dog singleDog;
@Resource(name = "prototypeDog")
private Dog prototypeDog;
@Autowired
private ApplicationContext context;
@RequestMapping("/single")
public String single() {
Dog dog = (Dog)context.getBean("singleDog");
return "注入的对象:" + singleDog.toString() + "," + "从容器中获取的对象:" + dog.toString();
}
@RequestMapping("/prototype")
public String prototype() {
Dog dog = (Dog)context.getBean("prototypeDog");
return "注入的对象:" + prototypeDog.toString() + "," + "从容器中获取的对象:" + dog.toString();
}
}
先来测试单例的:

可以看出,获取的两个对象地址值相同,是同一个对象
再来看多例作用域:

注入的对象是在程序启动前就已经注入进来了,之后再获取都是这个对象,而从容器中获取,每次请求都会再获取一个对象
通过@RequestScope
,@SessionScope
,@ApplicationScope
可以分别配置相应的作用域
Java
@Bean
@RequestScope
public Dog requestScopeDog() {
return new Dog();
}
@Bean
@SessionScope
public Dog sessionScopeDog() {
return new Dog();
}
@Bean
@ApplicationScope
public Dog applicationScopeDog() {
return new Dog();
}
2. Bean 的生命周期
Bean 的生命周期可以分为以下 5 个部分:
- 实例化:为 Bean 分配内存空间
- 属性赋值:Bean 的注入和装配
- 初始化:执行各种通知,执行初始化方法
- 使用 Bean
- 销毁 Bean
来分析一下源码:
在AbstractAutowireCapableBeanFactory
类中可以找到 createBean 方法

点进 createBean 方法之后能够看到执行了一个 doCreateBean 方法

再点进这个方法,能够看到实例化 Bean 的一个方法:

然后是属性装配和初始化:

在初始化方法中执行通知方法,和一些处理方法:

