目录
1. 案例
2. 作用域定义
2.1 Bean的6种作用域
2.2 设置作用域
3. Sring的执行流程
4. Bean的生命周期
思考: 为什么不是先进行初始化然后再进行设置属性呢?
1. 案例
假设现在有⼀个公共的 Bean,提供给 A ⽤户和 B ⽤户使⽤,然⽽在使⽤的途中 A ⽤户却“悄悄”地修改了公共 Bean 的数据,导致 B ⽤户在使⽤时发⽣了预期之外的逻辑错误。
我们预期的结果是,公共Bean可以在自己的类中进行修改,但不能影响其他类.
代码如下:
有一个公共的Bean对象Users
@Component
public class Users {
@Bean
public User user1() {
User user = new User();
user.setId(1);
user.setName("李四");
return user;
}
}
A 用户使用时,进行了修改操作:
@Controller
public class BeanScopesController {
@Autowired
private User user1;
public User getUser1() {
User user = user1;
System.out.println("Bean 原 Name:" + user.getName());
user.setName("王五");
return user;
}
}
B 用户再去使用公共 Bean 的时候:
@Controller
public class BeanScopesController2 {
@Autowired
private User user1;
public User getUser1() {
User user = user1;
return user;
}
}
打印 A 用户和 B 用户公共 Bean 的值:
public class BeanScopesTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
BeanScopesController beanScopesController = context.getBean(BeanScopesController.class);
System.out.println("A 对象修改之后 Name:" + beanScopesController.ge
tUser1().toString());
BeanScopesController2 beanScopesController2 = context.getBean(Bean
ScopesController2.class);
System.out.println("B 对象读取到的 Name:" + beanScopesController2.g
etUser1().toString());
}
}
控制台输出了:
Bean 原 name: 李四
A 对象修改之后 Name: 1:王五
B 对象读取到的 Name: 1:王五
我们发现A用户创建新的实例进行接收对象进行修改,也修改了Spring中原Bean对象的值.B去过去的时候就会获取到修改之后的Bean对象.
原因分析:
操作以上问题的原因是因为 Bean 默认情况下是单例状态(singleton),也就是所有⼈的使用的都是同⼀个对象,之前我们学单例模式的时候都知道,使用单例可以很大程度上提高性能,所以在 Spring 中Bean 的作用域默认也是 singleton 单例模式。
2.作用域定义
限定程序中变量的可⽤范围叫做作用域,或者说在源代码中定义变量的某个区域就叫做作用域。而 Bean 的作用域是指 Bean 在 Spring 整个框架中的某种行为模式,比如 singleton 单例作用域,就表示 Bean 在整个 Spring 中只有⼀份,它是全局共享的,那么当其他⼈修改了这个值之后,那么另一个人读取到的就是被修改的值。
2.1 Bean的6种作用域
Spring 容器在初始化⼀个 Bean 的实例时,同时会指定该实例的作用域。Spring有 6 种作用域.
singleton | 只在加载的时候创建对象,后续如果发生改变,重新请求会得到改变之后的Bean对象。 |
prototype | 每次获取的对象就是初始对象 |
request | 请求作用域:一次http请求一个Bean对象 |
session | 会话作用域:一次会话使用一个Bean对象,相对于Request作用域更广。 |
application | 全局作用域:一个httpServletContext中共用一个Bean对象一个上下文里面进行共享Bean对象 |
websocket | WebSocket的每次会话中,保存了⼀个Map结构的头信息,将⽤来包裹客户端消息头。第一次初始化后,直到WebSocket结束都是同⼀个Bean。 |
2.2 设置作用域
使⽤ @Scope 标签就可以⽤来声明 Bean 的作⽤域,比如把如设置 Bean 的作用域,如下代码所示:
3. Sring的执行流程
面试题: 讲一下Spring的执行流程
- 1. 启动容器(启动项目)
- 2. 读取配置文件完成Bean的初始化
- 2.1 使用xml直接注册Bean;
- 2.2 配置Bean的根扫描路径;
- 3. 将Bean进行存储到Spring中:通过类注解进行扫描;
- 4. 将Bean从Spring中进行读取,装配到响应的类中;
4. Bean的生命周期
生命周期指的是指对象从诞生到销毁的整个生命过程
下面总结了Bean对象的生命周期
- 1. 实例化Bean(为Bean对象进行分配内存空间)
- 2. 设置属性
- 3. Bean对象进行初始化
- 4. 使用Bean
- 5. 销毁Bean
引入房子的整个生命周期进行解释
生命周期代码演示
package com.demo.component;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* Created with IntelliJ IDEA.
* Description:
* User: YAO
* Date: 2023-07-05
* Time: 16:58
*/
@Component
public class BeanLifeComponent implements BeanNameAware {
@Override
public void setBeanName(String s) {
System.out.println("执行了通知方法");
}
@PostConstruct
public void postConstruct(){
System.out.println("执行了注解的方法");
}
public void init(){
System.out.println("执行了XML中init-method");
}
@PreDestroy
public void preDestroy(){
System.out.println("执行销毁方法");
}
}
package com;
import com.demo.component.BeanLifeComponent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created with IntelliJ IDEA.
* Description:测试Bean对象的周期
* User: YAO
* Date: 2023-07-05
* Time: 17:03
*/
public class AppBeanLife {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
BeanLifeComponent beanLifeComponent = context.getBean("beanLifeComponent",BeanLifeComponent.class);
System.out.println("使用Bean");
// 销毁Bean
context.destroy();
}
}
上述就可以看出Bean对象的生命周期
思考: 为什么不是先进行初始化然后再进行设置属性呢?
我们在A中注入B,在B中注入C
然后我们在进行获取A
控制台显示:
在获取A 之前要先对B进行设置,获取B就要先对C进行属性设置,也就是在初始化A之前要对自己的属性进行一一设置.文章来源:https://www.toymoban.com/news/detail-557472.html
其实我们还是可以通过房子进行解释,我们在装修之前肯定要把所有的原材料买全才能更好的进行装修.文章来源地址https://www.toymoban.com/news/detail-557472.html
到了这里,关于Spring系列4 -- Bean的作用域和生命周期的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!