2.2 Bean作用域
在前面我们提到的IOC容器当中,默认bean对象是单例模式(只有一个实例对象)。那么如何设置bean对象为非单例呢?需要设置bean的作用域。
在Spring中支持五种作用域,后三种在web环境才生效:
作用域 | 说明 |
---|---|
singleton | 容器内同名称的bean只有一个实例(单例)(默认) |
prototype | 每次使用该bean时会创建新的实例(非单例) |
request | 每个请求范围内会创建新的实例(web环境中,了解) |
session | 每个会话范围内会创建新的实例(web环境中,了解) |
application | 每个应用范围内会创建新的实例(web环境中,了解) |
知道了bean的5种作用域了,我们要怎么去设置一个bean的作用域呢?
-
可以借助Spring中的@Scope注解来进行配置作用域
1). 测试一
-
控制器
//默认bean的作用域为:singleton (单例)
@Lazy //延迟加载(第一次使用bean对象时,才会创建bean对象并交给ioc容器管理)
@RestController
@RequestMapping("/depts")
public class DeptController {
@Autowired
private DeptService deptService;
public DeptController(){
System.out.println("DeptController constructor ....");
}
//省略其他代码...
}
-
测试类
@SpringBootTest
class SpringbootWebConfig2ApplicationTests {
@Autowired
private ApplicationContext applicationContext; //IOC容器对象
//bean的作用域
@Test
public void testScope(){
for (int i = 0; i < 10; i++) {
DeptController deptController = applicationContext.getBean(DeptController.class);
System.out.println(deptController);
}
}
}
重启SpringBoot服务,运行测试方法,查看控制台打印的日志:
注意事项:
IOC容器中的bean默认使用的作用域:singleton (单例)
默认singleton的bean,在容器启动时被创建,可以使用@Lazy注解来延迟初始化(延迟到第一次使用时)
2). 测试二
修改控制器DeptController代码:
@Scope("prototype") //bean作用域为非单例
@Lazy //延迟加载
@RestController
@RequestMapping("/depts")
public class DeptController {
@Autowired
private DeptService deptService;
public DeptController(){
System.out.println("DeptController constructor ....");
}
//省略其他代码...
}
重启SpringBoot服务,再次执行测试方法,查看控制吧打印的日志:
注意事项:
prototype的bean,每一次使用该bean的时候都会创建一个新的实例
实际开发当中,绝大部分的Bean是单例的,也就是说绝大部分Bean不需要配置scope属性