【Spring】Bean作用域和生命周期-创新互联
- Bean作用域和生命周期
- Bean的作用域定义
- Bean作用域类型
- 更改Bean的作用域
- Spring执行流程:
- Bean的生命周期
什么是Bean的作用域呢?
我们知道变量的作用域:在作用域范围内可以访问到该变量,在作用域范围外则不能访问到该变量,这个是变量的作用域,但是Bean的作用域就和作用范围不太一样了
==Bean的作用域:==Bean在Spring中的某种行为模式,那什么是行为模式呢?Bean都有哪些行为模式呢,我们举个栗子来说明这个问题:
User类:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZJZf91Z3-1669874907222)(https://hao-typora.oss-cn-beijing.aliyuncs.com/img/image-20221130183146524.png)]
1️⃣向Spring中存储User实例:
package bit.controller;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
@Controller
public class UserController1 {@Bean(value = "student_user")
public User user1(){User user = new User();
user.setId(2);
user.setName("李四");
user.setAge(10);
return user;
}
}
2️⃣将Spring中的User实例注入到ScopeController1中:
package bit.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class ScopeController1 {@Autowired
private User user;
public void doController(){System.out.println("controller1");
System.out.println("原对象:"+user);
user.setName("王五");
System.out.println("修改后对象:"+user);
}
}
2️⃣将Spring中的User实例注入到ScopeController2中:
package bit.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class ScopeController2 {
@Autowired
private User user;
public void doController(){
System.out.println("controller2");
System.out.println(user);
}
}
3️⃣从Spring中分别取出两个controller实例,分别调用doController方法:
4️⃣结果:
在ScopeController1的doController方法中修改了User对象的名字,但是在ScopeController2的doController方法中打印的对象的信息恰好是ScopeController1修改后的结果,并不是原始的对象:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TGsHXDLa-1669874907224)(https://hao-typora.oss-cn-beijing.aliyuncs.com/img/image-20221130182941999.png)]
5️⃣原因:
==其实在Spring中存储的对象默认是单例的,==存储的User实例只有一个,虽然User实例要注入到两个类中,但是注入两个类中的User实例是同一个,所以才会出现在ScopeController1中修改了User对象属性,ScopeController2中的User对象属性同样也会修改。
⭕️那在Spring中既然有单例,那就有多例,多例就是注入到不同对象的User实例不是同一个对象,是两个不同的对象,单例有单例的好处:单例效率高,因为单例只创建一个对象,多例有多例的适用场景,有的时候就是需要注入的不是同一个对象,那就是需要用多例。所以到底用单例还是用多例,需要看场景。
存入Spring中的对象是单例还是多例,这个就叫做不同的行为模式,也就是不同的作用域
Bean作用域类型在Spring中,Bean总共有6种作用域:
- singleton(单例作用域)
- prototype(多例作用域)
- request(请求作用域)
- session(会话作用域)
- application(全局作用域)
- websocket(Http Websocket作用域)
最后四种是基于SpringMVC生效的,在当前的Spring core项目中只有前两种生效
1️⃣singleton:该作用域下的Bean在Spring中只有一个实例,通常无状态的Bean使用该作用域,无状态表示Bean的属性不需要改变
2️⃣prototype:该作用域下的Bean在Spring中有多个实例,每次注入对象注入的都是新创建的对象,通常在有状态的Bean使用该作用域
3️⃣request:每次http请求会创建新的实例,一次请求和响应共享Bean,限定在SpringMVC中使用
4️⃣session:在一个http session中定义一个Bean实例,限定SpringMVC中使用
后两种并不常用,在此就不介绍了。
更改Bean的作用域package bit.controller;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
@Controller
public class UserController1 {
//@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) //方式一
@Scope("prototype") //方式二
@Bean(value = "student_user")
public User user1(){
User user = new User();
user.setId(2);
user.setName("李四");
user.setAge(10);
return user;
}
}
使用@Scope注解即可修改Bean的作用域:
方式一:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
方式二:@Scope(“prototype”)
Spring执行流程:Spring执行流程:启动Spring容器 ->扫描配置文件并实例化Bean(真正在堆上创建出对象)->将Bean注册到Spring中(存对象)->将Bean装配到需要的类中(其实就是对象注入)
Bean的生命周期所谓生命周期指的是从对象创建到对象销毁的这个过程。
Bean的生命周期大体可以分为一下5个步骤:
- 实例化Bean(在堆上创建对象)
- 设置属性(Bean注入,也就是注入对象的操作,依赖注入)
- Bean初始化(执行一些初始化方法)
3.1.执行各种通知
3.2.初始化的前置方法
3.3.初始化方法
3.4初始化的后置方法
- 使用Bean
- 销毁Bean
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
当前名称:【Spring】Bean作用域和生命周期-创新互联
网页网址:http://myzitong.com/article/ddepdg.html