Bean 的六种作用域总结

什么是Bean的作用域?
Bean的作用域指的是指 Bean 在 Spring 框架中的某种行为模式

⽐如单例作⽤域: 表⽰ Bean 在整个 Spring 中只有⼀份, 它是全局共享的. 那么当其他⼈修改了这个值之
后, 那么另⼀个⼈读取到的就是被修改的值.

@SpringBootTest
class DemoApplicationTests {
 @Autowired
 private ApplicationContext applicationContext; //Spring 容器
 @Test
 void contextLoads() {
 Dog dog1 = applicationContext.getBean(Dog.class);
 dog1.setName("狗狗1");
 System.out.println(dog1);
 System.out.println(dog1.getName());
 Dog dog2 = applicationContext.getBean(Dog.class);
 System.out.println(dog2);
 System.out.println(dog2.getName());
 }
}

观察运行结果得知dog1 和 dog2 为同⼀个对象, dog2 拿到了 dog1 设置的值
那么,能不能将Bean对象设置为非单例的(每次获取的bean都是⼀个新对象)
这就是Bean的不同作用域

Bean的作用域

spring中支持6种作用域,后4中在Spring MVC环境才⽣效:

  1. singleton:单例作⽤域
  2. prototype:原型作⽤域(多例作⽤域)
  3. request:请求作⽤域
  4. session:会话作⽤域
  5. Application: 全局作⽤域
  6. websocket:HTTP WebSocket 作⽤域

作用域说明

singleton ----->每个Spring IoC容器内同名称的bean只有⼀个实例(单例)(默认)
prototype ------>每次使⽤该bean时会创建新的实例(⾮单例)
request -------->每个HTTP 请求⽣命周期内, 创建新的实例(web环境中)
session ------>每个HTTP Session⽣命周期内, 创建新的实例(web环境中)
application ------->每个ServletContext⽣命周期内, 创建新的实例(web环境中)
websocket ------>每个WebSocket⽣命周期内, 创建新的实例(web环境中)

简单看下代码实现:
定义几个不同作用域的Bean

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;

@Component
public class DogBeanConfig {
 @Bean
 public Dog dog(){
 Dog dog = new Dog();
 dog.setName("旺旺");
 return dog;
 }
 @Bean
 @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
 public Dog singleDog(){
 Dog dog = new Dog();
 return dog;
 }
 @Bean
 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
 public Dog prototypeDog(){
 Dog dog = new Dog();
 return dog;
 }
 @Bean
 @RequestScope
 public Dog requestDog() {
 Dog dog = new Dog();
 return dog;
 }
 @Bean
 @SessionScope
 public Dog sessionDog() {
 Dog dog = new Dog();
 return dog;
 }
 @Bean
 @ApplicationScope
 public Dog applicationDog() {
 Dog dog = new Dog();
 return dog;
 }
}

测试不同作⽤域的Bean取到的对象是否⼀样:

@RestController
public class DogController {
@Autowired
 private Dog singleDog;
 @Autowired
 private Dog prototypeDog;
 @Autowired
 private Dog requestDog;
 @Autowired
 private Dog sessionDog;
 @Autowired
 private ApplicationContext applicationContext;
 @RequestMapping("/single")
 public String single(){
 Dog contextDog = (Dog)applicationContext.getBean("singleDog");
 return "dog:"+singleDog.toString()+",contextDog:"+contextDog;
 }
 @RequestMapping("/prototype")
 public String prototype(){
 Dog contextDog = (Dog)applicationContext.getBean("prototypeDog");
 return "dog:"+prototypeDog.toString()+",contextDog:"+contextDog;
 }
 @RequestMapping("/request")
 public String request(){
 Dog contextDog = (Dog)applicationContext.getBean("requestDog");
 return "dog:"+requestDog.toString()+",contextDog:"+contextDog.toString()
 }
 @RequestMapping("/session")
 public String session(){
 Dog contextDog = (Dog)applicationContext.getBean("sessionDog");
 return "dog:"+sessionDog.toString()+",contextDog:"+contextDog.toString()
 }
 @RequestMapping("/application")
 public String application(){
 Dog contextDog = (Dog)applicationContext.getBean("applicationDog");
 return "dog:"+applicationDog.toString()+",contextDog:"+contextDog.toStri
 }
}

每个请求都获取两次Bean
@Autowired 和 applicationContext.getBean(“singleDog”) 都是从Spring 容器中获
取对象

观察Bean的作用域

  • 单例作⽤域: 多次访问, 得到的都是同⼀个对象, 并且 @Autowired 和 applicationContext.getBean()也是同一个对象
  • 多例作⽤域:观察ContextDog, 每次获取的对象都不⼀样(注⼊的对象在Spring容器启动时, 就已经注⼊了, 所以多次
    请求也不会发⽣变化
  • 请求作⽤域:在⼀次请求中, @Autowired 和 applicationContext.getBean() 也是同⼀个对象.
    但是每次请求, 都会重新创建对象
  • 会话作⽤域:在⼀个session中, 多次请求, 获取到的对象都是同⼀个,换⼀个 浏览器访问, 发现会重新创建对象.(另⼀个Session)
  • Application作⽤域:在⼀个应⽤中, 多次访问都是同⼀个对象
    (Application scope就是对于整个web容器来说, bean的作⽤域是ServletContext级别的. 这个和singleton有点类似,区别在于: Application scope是ServletContext的单例, singleton是⼀个
    ApplicationContext的单例. 在⼀个web容器中ApplicationContext可以有多个.)
  • 26
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值