开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第24天,点击查看活动详
大家好,我是bug郭,一名双非科班的在校大学生。对C/JAVA、数据结构、Spring系列框架、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流
作者简介:
- CSDN java领域新星创作者blog.csdn.net/bug..
- 掘金LV3用户 juejin.cn/user/bug..
- 阿里云社区专家博主,星级博主,developer.aliyun.com/bug..
- 华为云云享专家 bbs.huaweicloud.com/bug..
Bean的作用域
我们知道传统意义上的作用域就是一个一个变量限定在程序的可用范围或者源代码中某个变量定义的某个区域叫做作用域! 我们
Spring中的Bean作用域并不是传统意义上的定义,Spring下的Bean的作用域指的是一个Bean对象的在Spring下的行为模式,就列如我们知道的单例模式singleton就是Bean的一种作用域!
Bean的六种作用域
singleton单例作用域(默认)prototype原型作用域(多例模式)request请求作用域(SpringMVC)session会话作用域(SpringMVC)application全局作用域(SpringMVC)websocketHTTP WebSocket作用域(Spring WebSocket)
singleton单例作用域 该作用域下的
Bean在IoC容器下只存在一个实例! 所以对该bean进行注入,装配bean都是同一个对象! Spring默认作用域
当我们创建一个Bean注册到Spring中后,如果有2个类需要注入该Bean!一类进行读取操作,另一个类进行修改操作!如果修改操作在前,那另一个类读取的操作就会读到脏数据,本来想读取到的是Bean初始值,结果读取到了另一个类修改后的数据!,这就说明Bean对象在Spring下是共享的,一个bean对象是单例!当注入时,是多个类共享的!
//创建User Bean对象!
public class User {
private String name;
private int id;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
//将Bean 注册到Spring中!
@Component
public class Users {
@Bean //将对象注册到spring中!
public User getUser(){
User user = new User();
user.setId(666);
user.setName("java");
return user;
}
}
//User1进行读操作!
@Controller
public class UserController1 {
//注入对象!
@Autowired
private User user;
public User getUser() {
return user;
}
}
//User2进行修改操作!
@Controller
public class UserController2 {
@Autowired //注入对象!
private User user;
//将user对象改了!
public User getUser() {
user.setName("C++");
user.setId(999);
return user;
}
}
//先修改Bean后读取
//启动类!!!
public class app {
public static void main(String[] args) {
//获取上下文!
ApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
//user2把bean对象改了!
UserController2 userController2 = context.getBean(UserController2.class);
System.out.println(userController2.getUser());
//user1正在读取bean! 预期读取结果是 java 666 因为这是bean注册的初始值!
UserController1 userController1 = context.getBean(UserController1.class);
System.out.println(userController1.getUser());
}
}
运行结果
User1读取到的是修改后的Bean!
Bean在Spring默认的作用域是singleton
prototype原型作用域(多例作用域) 在
Spring中对同一个Bean,进行注入装箱每个类获取到的bean都是一个新的实例对象! 通常有动态Bean使用该作用域
request请求作用域 每一次http请求都会创建一个新的Bean实例.类似于prototype作用域 一次http请求和响应的共享Bean 限定于SpringMVC中使用
session会话作用域 在一次http session中定义一个Bean实例 用户会话的共享Bean ,比如通过这个作用域记录一个用户的登入信息! 限定于SpringMVC中使用
application全局作用域 在一个http servlet Context中定义一个Bean实例 Web应用的上下文信息,例如记录应用的共享信息 限定于SpringMVC中使用
WebSocket作用域 在一次WebSocket生命周期中定义一个Bean WebSocket的每次会话中保存了一个Map结构的头信息,用来包裹客户端头,第一次初始化直到WebSocket生命周期结束都是同一个Bean 限定于SpringMVC中使用
singleton和application对比
- singleton是Spring Core的作用域 application是Spring Web的作用域
- singleton作用于IoC容器,application作用于Servlet容器中