Spring(Bean 作用域和生命周期)

news2024/9/23 7:21:37

目录

1. 案例1: Bean作用域的问题

2. 作用域

3. 设置 Bean 的作用域

4. Spring 的执行流程

5. Bean 的生命周期


1. 案例1: Bean作用域的问题

现在有一个公共的 Bean,通过给 A 用户 和 B 用户使用, 然后在使用的过程中 A 偷偷的修改了公共 Bean 的数据, 导致 B 在使用时发生了预期之外的逻辑错误

(1) 公共 Bean:   [名称是 java]

@Component
public class Users {
    @Bean
    public User user1() {
        User user = new User();
        user.setId(1);
        user.setName("java");
        return user;
    }
}

(2) 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;
    }
}

(3) B 用户再去使用公共 Bean 的时候

@Controller
public class BeanScopesController2 {

    @Autowired
    private User user1;

    public User getUser1() {
        User user = user1;
        return user;
    }
}

(4) 打印 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.getUser1().toString());

        BeanScopesController2 beanScopesController2 = context.getBean(BeanScopesController2.class);
        System.out.println("B 对象读取到是 Name: " + beanScopesController2.getUser1().toString());
    }
}

(5) 运行程序

(6) 原因分析 

存在这个问题的原因就是 Bean 默认情况下是 单例模式 (singleton), 也就是所有类使用的都是同一个对象, 使用同一个对象,那就是没有过多的生命周期的创建和销毁,从而可以提高性能,所以在 Spring 中 Bean 的作用域也是 单例模式的


2. 作用域

限定程序中变量的可用范围叫做作用域.

Bean的作用域是指, Bean 在 Spring 整个框架中的某种行为,比如 单例模式的作用域, 意思就是 Bean 在整个 Spring 中只有一份, 它是全局共享的, 当有人修改了这个值后, 其他人读到的就是被修改的值

Spring 容器在初始化一个 Bean 的实例时,会同时指定该实例的作用域,Spring中有 6 种作用域

  1. singleton: 单例模式 (默认,每次请求取的是同一个对象)
  2. prototype: 原型模式 (多例模式,每次请求创建一个新的对象)
  3. request: 请求作用域 (Spring MVC,每次请求创建一个对象)
  4. session: 会话作用域 (Spring MVC,在一个会话中共享一个对象)
  5. application: 全局作用域 (Spring MVC,所有人共用一个)
  6. websocket: HTTP WebSocket 作用域 (Spring WebSocket 项目中存在的一种)

3. 设置 Bean 的作用域

使用 @Scope 标签来声明 Bean 的作用域,

@Scope 标签既可以修饰方法,也可以修饰类, @Scope 有两种设置方式

  • 直接设置值: @Scope("prototype")
  • 类似于枚举的常量方式: @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Component
public class Users {
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    @Bean
    public User user1() {
        User user = new User();
        user.setId(1);
        user.setName("java");
        return user;
    }
}

还是 案例1中的代码,只不过加上 Bean的作用域 原型模式后,运行程序,可以看到A修改后,B没有受到影响


4. Spring 的执行流程

Spring 执行流程: 
  1. 启动 Spring 容器
  2. 实例化 Bean (分配内存空间)
  3. 将 Bean 注册到 Spring 中 (存操作)
  4. 将 Bean 装配到需要的类中 (取操作)


5. Bean 的生命周期

Bean 的生命周期:

  1. 实例化 Bean (给 Bean 分配内存空间)          买房子
  2. 设置属性 (Bean 对象注入)                            装修
  3. Bean 初始化                                                 买家电
  • 执行各种通知 (执行各种 Aware)
  • 执行初始化的前置方法
  • 执行构造方法,两种执行方式,一种是执行 @PostConstruct,另一种是执行 init-method
  • 执行初始化的后置方法

     4. 使用 Bean                                                    入住

     5. 销毁 Bean                                                    卖房

  • @PreDestroy (销毁前方法)
  • 重写 DisposableBean 接口方法
  • destroy-method
public class BeanLifeComponent implements BeanNameAware {
    @PostConstruct
    public void postConstruct() {
        System.out.println("执行 PostConstruct()");
    }
    public void init() {
        System.out.println("执行 init-method");
    }
    public void use() {
        System.out.println("使用 bean");
    }
    @PreDestroy
    public void preDestroy() {
        System.out.println("执行: preDestroy()");
    }
    public void setBeanName(String s) {
        System.out.println("执行了 Aware 通知");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:content="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <content:component-scan base-package="com.beans"></content:component-scan>
    <beans>
        <bean id="beanLifeComponent" class="com.beans.BeanLifeComponent" init-method="init"></bean>
    </beans>
</beans>
public class BeanLifeTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config2.xml");
        BeanLifeComponent lifeComponent = context.getBean(BeanLifeComponent.class);
        lifeComponent.use();
        //执行销毁方法
        context.destroy();
    }
}

先设置属性再进行初始化,作用是

如果先初始化,就会出现空引用了,所以了为了防止空引用,就要先设置属性注入,然后再进行初始化 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/59627.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

html静态网站基于动漫网站网页设计与实现共计4个页面

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置&#xff0c;有div的样式格局&#xff0c;这个实例比较全面&#xff0c;有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 ⚽精彩专栏推荐&#x1…

基于遗传算法的微电网调度(风、光、蓄电池、微型燃气轮机)(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清…

Docker介绍

目录 docker定义 docker解决了什么问题 docker技术边界 docker给我们带来了哪些改变 docker和虚拟机的区别 docker基本架构 基本架构图 RootFs Linux Namespace 进程命名空间 查看元祖进程命名空间 查看当前用户进程命名空间 容器进程命名空间 容器进程命名空间的…

[激光原理与应用-33]:典型激光器 -5- 不同激光器的全面、综合比较

目录 第1章 五类激光器的性能及应用对比 第2章 各类激光器的区别特点及应用三张表看懂-超米激光 2.1 固体激光器 2.2 气体激光器 2.3 化学激光器 2.4 染料激光器 2.5 半导体激光器 2.6 光纤激光器 2.7 自由电子激光器 第3章 10多种激光器的全面梳理 3.1 激光器的分类…

二叉树-31-37对称二叉树

31. 对称的二叉树 递归&#xff1a; 把原问题化成更小规模的问题&#xff0c;并且具有相同的问题性质&#xff0c;重复调用本身函数 二叉树的递归&#xff0c;是将某个节点的左子树、右子树看成一颗完整的树&#xff0c;那么对于子树的访问或者操作就是对于原树的访问或者操作…

HTML如何制作音乐网站(如何搭建个人音乐网页)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

Java毕业设计 JSP+MySQL幼儿园信息管理系统

幼儿园网站就是幼儿园的“商标”,在网站上可以看出一所幼儿园的特色和个性,在这个信息时代,建立属于自己的幼儿园网站是最直接的宣传手段。而就目前的幼儿园信息管理系统来说,有很多功能都是华而不实的,不能很好的与幼儿园日常工作相结合,容易导致日常工作出现异常。本系统的题…

【HDU No. 4417】 超级马里奥 Super Mario

【HDU No. 4417】 超级马里奥 Super Mario 杭电OJ 题目地址 【题意】 可怜的公主陷入困境&#xff0c;马里奥需要拯救他的情人。把通往城堡的道路视为一条线&#xff08;长度为n &#xff09;&#xff0c;在每个整数点i 上都有一块高度为hi 的砖&#xff0c;马里奥可以跳的最…

【博客552】git auto-merge原理以及auto-merge的不同模式

git auto-merge原理 1、merge 常见误区 1、git merge 是用时间先后决定merge结果的&#xff0c;后面会覆盖前面的? 答 &#xff1a;git 是分布式的文件版本控制系统&#xff0c;在分布式环境中时间是不可靠的&#xff0c;git是靠三路合并算法进行合并的。 2、git merge 只…

电脑装了w10没有w7流畅怎么办?

如果我们对自己的电脑进行了系统的重装&#xff0c;在电脑装了win10系统之后发现没有win7流畅的话&#xff0c;很多小伙伴不知道是什么情况应该怎么解决。 那么据微点阅读小编所知可能是我们电脑硬件设施的不兼容所导致的。我们可以在官网上查看win10系统的配置要求是否符合自…

一文带你深入理解【Java基础】· 泛型

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

Arduino开发实例-DIY风速测量及显示

DIY风速测量及显示 1、应用介绍 本次实例将使用一款具有 NPN 脉冲输出的数字风速计传感器。 NPN脉冲输出风速计效果好,性价比高。另外它仅在 5V 电源下工作。 在本次实例中,将此风速计传感器与 Arduino 板和 0.96 英寸 OLED 显示屏连接。 OLED显示屏将以米/秒为单位显示风速…

[附源码]计算机毕业设计基于SpringBoot的酒店预订系统设计与实现

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

​AAAI 2023 | 基于历史对比学习的时序知识图谱推理

©PaperWeekly 原创 作者 | 徐奕单位 | 上海交通大学Acemap研究方向 | 数据挖掘论文标题&#xff1a;Temporal Knowledge Graph Reasoning with Historical Contrastive Learning论文链接&#xff1a;https://arxiv.org/abs/2211.10904代码链接&#xff1a;https://github…

Elasticsearch好用查询插件分享

以前我常用的ES查询工具是Head&#xff0c;作为插件形式在浏览器中运行&#xff0c;挺方便的&#xff0c;后来发现head不太好用&#xff0c;比如在数据浏览的时候&#xff0c;不小心就点击了两个索引&#xff0c;背景色设置的还不够明显&#xff0c;比较容易看错数据的。于是想…

git中rebase和merge的区别

介绍 Merge和Rebase是合并两个分支的操作。都是checkout到某个分支上&#xff0c;然后将别的分支合并&#xff08;变基&#xff09;到本分支上。 注意&#xff1a;本分支&#xff08;head指向的分支&#xff0c;或者经过checkout后的分支&#xff09;会变化&#xff0c;而别的…

在Linux上部署Servlet程序

目录 一、部署环境 1、安装JDK 2、安装Tomcat 3、安装MySQL 二、部署程序 1、构造云服务器上的数据库 2、打包程序 3、部署程序 一、部署环境 为了部署我们自己的web程序&#xff0c;首先需要在Linux上安装程序所依赖的环境~ 1、安装JDK 直接使用yum安装openjdk&…

小程序云开发笔记二

小程序云开发笔记二一、读取数据库播放列表将数据显示到界面二、上拉加载三、上拉刷新四、云函数路由优化tcb-router案例&#xff1a;点击两个按钮调用同一个云函数将music中写成koa风格的云函数五、事件冒泡组件参数properties和data一、读取数据库播放列表将数据显示到界面 …

java同步方法

观看此文 首先 你要了解 java的同步锁 如果不了解 可以观看我的文章 java 同步锁synchronized 解决线程共享数据重复操作问题 那么 从下图 我们可以看到 逻辑代码上被绑了一个同步锁 但这个其实大可以写成一个函数 看起来会美观便捷很多 同步方法的格式如下 修饰符 synchro…

git switch 命令详解

1. 前言 2. switch 创建分支 3. switch 切换分支 1. 前言 checkout 命令具有 分支的管理 和 文件的恢复 两个核心功能&#xff0c;功能较多、不够准确。在 git 2.23 版本中新增了 switch 和 restore命令&#xff0c;用于替代 checkout 命令&#xff0c;进而分化 checkout 命…