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属性