Bean作用域及生命周期

关于Bean对象,在将其存储到spring中以后,在使用或读取该Bean对象时,如果该对象是公有的,难免就会出现被一方修改,从而影响另外一方读取到的对象准确性的情况。因此了解Bean的作用域和生命周期就是十分必要的了。

首先,还是具体使用一个例子来理解上面提到的这种情况:

文章目录

    • 示例
    • Bean的6种作用域
      • singleton
      • prototype
      • request
      • session
      • application
      • websocket
    • Bean作用域的设置
    • Spring的执行流程
    • Bean生命周期

示例

首先,新建一个Student实体类,为其设置属性,并提供其相关的get/set方法;

package com.yun.model;

public class Student {
    private int id;
    private String name;
    private double score;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", score=" + score +
                '}';
    }
}

创建一个Bean对象,使用方法注解存储到Spring;

package com.yun.controller;

import com.yun.model.Student;
import com.yun.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class StudentBean {

    @Bean
    public Student stu(){
        Student student=new Student();
        student.setId(5);
        student.setName("李大锤");
        student.setScore(99.6);
        return student;
    }
}

A首先读取并且使用bean,同时进行一定的操作;

package com.yun.controller;

import com.yun.model.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/*
* A     1.获取bean;
*       2.创建了新的对象,对新创建的对象进行修改
* */
@Controller
public class StuController1 {
    @Autowired

    private Student student1;

    public Student getStu1(){
        Student student=student1;

        System.out.println("student1 id="+student.getId()+" name="+student.getName());
        student.setId(10);
        student.setName("安慕希");
        return student;

    }
}

B 读取bean;

package com.yun.controller;

import com.yun.model.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/*
* B 读取bean,获取bean的具体值
* */
@Controller
public class StuController2 {
    @Autowired
    private Student student1;

    public Student getStud2(){
        Student student=student1;
        return student;
    }
}

获取原始bean的值,以及A读取到的值和B读取到的值;

在这里插入图片描述
通过运行结果可以得到结论,尽管看起来A是在自己新创建的Bean对象上进行了修改,但最终还是会影响到原始公共Bean的值;

而究其出现这种结果的原因,其实就是因为Bean在默认情况下是单例模式,即只有一份对象,这份对象供所有访问者使用。因此,A进行的修改操作自然也就会影响到B的读取结果。而使用单例状态的原因就是,提高性能。

Bean的6种作用域

作用域,顾名思义就是“作用到的区域或范围”,实际就是程序中变量的一个可用的范围。而Bean的作用域其实就是Bean在Spring框架中的某种行为模式,具体共有6种:

  • singleton:单例作⽤域
  • prototype:原型作⽤域(多例作⽤域)
  • request:请求作⽤域
  • session:会话作⽤域
  • application:全局作⽤域
  • websocket:HTTP WebSocket 作⽤域

singleton

是Spring默认选择的作用域;
在此作用域下的Bean在IoC容器中只有一个实例,即只有一个全局对象;
通常当Bean对象的属性状态不需要更新时,即Bean无状态的情况下会使用该作用域;

prototype

多例模式下使用的作用域;
在此作用域下的Bean每被访问一次就会创建出一个实例;
通常当Bean对象的属性状态需要更新时,即Bean有状态的情况下会使用该作用域;

在普通的Spring项目中,一般只有前面两种作用域;而后面提到的作用域则是只能在SpringMVC中使用或只能在Spring WebSocket中使⽤;

request

在每次http请求时都会创建一个新的Bean的实例;
只能在SpringMVC中使用;

session

每次会话都会定义一个Bean的实例;
只能在SpringMVC中使用;

application

在一个http servlet Context中,共享一个Bean实例;
只能在SpringMVC中使用;

websocket

在一个HTTP WebSocket中,定义一个Bean实例同时共享这个实例;
只能在Spring WebSocket中使⽤;

Bean作用域的设置

由于我们这里主要介绍的是Spring项目,因此关于Bean作用域的设置也只涉及到两种;

singleton是Spring默认的作用域,因此一个新创建的bean对象在不进行特别设置的情况下,其作用域就是singleton;

下面具体演示prototype的设置:

在这里插入图片描述

prototype的设置有上面图片中所示的两种方式,我们也可以从相关类中找到该作用域的定义信息:
在这里插入图片描述
在为其设置了全局作用域后,我们再次执行文章开始的实例,得到的结果如下:
在这里插入图片描述
此时,A的修改操作不再影响到B的读取;

Spring的执行流程

  1. 启动容器;

在这里插入图片描述
首先,启动容器,去加载相关的配置文件;

  1. 进行Bean初始化

在这里插入图片描述

对配置了加载组件路径下的类进行扫描,即扫描该路径下的文件,查看是否有相关的类注解;

  1. 注册Bean对象到容器
    在这里插入图片描述

将在加载组件路径下的类中,添加了相关注解的类注册到容器中;

  1. 装配或使用Bean

在这里插入图片描述
即将需要使用的Bean注入到需要的类中去;

  1. Spring销毁

相关使用操作完毕,最终Spring销毁;

Bean生命周期

生命周期实际就是一个对象从产生到被销毁的全过程,关于Bean生命周期主要有5步:

  1. 实例化Bean

即为Bean对象分配内存空间;

  1. 设置属性
    对Bean对象进行依赖注入;
  2. 进行Bean初始化
    3.1 执行各种通知;

3.2 初始化的前置方法;

3.3 初始化方法;
3.4 初始化的后置方法;

  1. 使用Bean;
  2. 销毁Bean;

简单使用代码来观察这个过程:

package com.yun.controller;

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class BeanLife implements  BeanNameAware {



    @Override
    public void setBeanName(String s) {

        System.out.println("执行 setBeanName() 通知 "+s);
    }


    @PostConstruct
    public void myPostConstruct(){
        System.out.println("执行 myPostConstruct() 方法");
    }



    public void init(){
        System.out.println("执行 init()");
    }

    public void use(){
        System.out.println("执行 use 方法");
    }

    @PreDestroy
    public void myPreDestroy(){
        System.out.println("执行 myPreDestroy() 销毁");
    }
}

使用xml的方式进行注入:

<?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">

<!--    <bean id="userService" class="com.bit.service.UserService"></bean>-->



    <!-- 配置存储 Bean 对象的扫描根路径 -->
    <content:component-scan base-package="com.yun"></content:component-scan>

    <bean id="beanlife" class="com.yun.controller.BeanLife"
          init-method="init"></bean>


</beans>

设置一个启动类:

import com.yun.controller.BeanLife;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanLifeApp {
    public static void main(String[] args) {
        
        /*
        * 必须使用ClassPathXmlApplicationContext类,ApplicationContext无方法destroy()方法
        * */
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
        BeanLife beanLife=context.getBean("beanlife",BeanLife.class);
        beanLife.use();
        System.out.println("执行 main方法");
        context.destroy();
    }
}

运行结果:

在这里插入图片描述

over!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024年AMC8模拟考试实测流程、注意事项和常见问题

和往年的AMC8比赛一样&#xff0c;在正式比赛的前一周左右会开放两天的模拟考试时间&#xff0c;AMC8的主办方建议所有的参赛选手重视且参加模拟考试&#xff0c;以测试设备、熟悉流程&#xff0c;避免将来正式考试不小心违规&#xff0c;或者设备不给力。 2024年的AMC8模拟考…

Matlab字符识别实验

Matlab 字符识别OCR实验 图像来源于屏幕截图&#xff0c;要求黑底白字。数据来源是任意二进制文件&#xff0c;内容以16进制打印输出&#xff0c;0-9a-f’字符被16个可打印字符替代&#xff0c;这些替代字符经过挑选&#xff0c;使其相对容易被识别。 第一步进行线分割和字符…

一个简易的PHP论坛系统

一个简易的PHP论坛系统 php课程设计&#xff0c;毕业设计 预览 技术 bootstrap 4.x jquery css php mysql 5.7 目录结构 登录 管理员 admin/123456 测试用户 user1/123456 更多文章和源码获取查看

MongoDB认证考试小题库

Free MongoDB C100DBA Exam Actual Questions 关于MongoDB C100 DBA 考试真题知识点零散整理 分片架构 应用程序 --> mongos --> 多个mongod对于应用来说&#xff0c;连接分片集群跟连接一台单机mongod服务器一样分片好处&#xff0c; 增加可用RAM、增加可用磁盘空间、…

【Spring Cloud Alibaba】Sentinel 服务熔断与流量控制

目录 前言 一、Sentinel 入门 1.1 什么是 Sentinel ? 1.2 微服务集成 Sentinel 1.3 安装Sentinel控制台 二、Jmeter 压力测试工具 2.1 Jmeter 介绍 2.2 Jmeter 安装 2.3 接口测试 三、Sentinel 使用 3.1 限流规则 3.1.1 warm up(预热模式) 3.1.2 排队等待 3.1.3…

记redis5.x在windows上搭建集群(六主六从)

六个运行端口 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 1、安装redis,文章太多不多BB 2、复制六份redis文件夹出来改名 3、修改每一份的配置文件 redis.windows.conf 修改为以下格式&#xff1a; #运行端口 port…

线性代数——(期末突击)概率统计习题(概率的性质、全概率公式)

目录 概率的性质 题一 全概率公式 题二 题三 概率的性质 有限可加性&#xff1a; 若有限个事件互不相容&#xff0c;则 单调性&#xff1a; 互补性&#xff1a; 加法公式&#xff1a; 可分性&#xff1a; 题一 在某城市中共发行三种报纸&#xff1a;甲、乙、丙。在这个…

vue3实现动态侧边菜单栏的几种方式总结

基于自建json数据的动态侧边菜单栏 后端接口json数据 src/api/menuList.js const menuList [{url: ,name: 人员管理,icon: icon-renyuan,menuId: 1,children: [{url: /user,name: 用户管理,icon: icon-jurassic_user,menuId: 1001,children: []},{url: /role,name: 角色管…

如何构建快速、准确的3D模型格式转换?Govie成功应用HOOPS Exchange解决数据转换问题

德国公司 "Govies "将三维CAD模型与互动的视觉环境和讲故事的元素相结合。 2021年5月10日&#xff0c;工程软件开发工具包的供应商Tech Soft 3D告知&#xff0c;总部位于德国的实时三维可视化专家3D Interaction Technologies&#xff08;3DIT&#xff09;正在使用H…

(Java企业 / 公司项目)分布式事务Seata详解(含Seata+Nacos组合使用)

一. Seata介绍 Seata 是一款开源的分布式事务解决方案&#xff0c;致力于在微服务架构下提供高性能和简单易用的分布式事务服务。在 Seata 开源之前&#xff0c;其内部版本在阿里系内部一直扮演着应用架构层数据一致性的中间件角色&#xff0c;帮助经济体平稳的度过历年的双11&…

简单高效 LaTeX 科学排版 第004集 命令与环境

这是《简单高效LaTeX》的第四个视频&#xff0c;主要演示讨论基本命令与排版环境&#xff0c;还有保留字符。 视频地址&#xff1a;https://www.ixigua.com/7298100920137548288?id7298102807985390120&logTagf853f23a668f8a2ee405

nmealib库编译提示 undefined reference to `ceil‘

一、问题描述 下载了nmealib库文件&#xff0c;默认工程进行编译&#xff0c;报错&#xff0c;提示如下&#xff1a; gcc -I include -c src/generate.c -o build/nmea_gcc/generate.o gcc -I include -c src/generator.c -o build/nmea_gcc/generator.o ar rsc lib/libnm…

机器学习数据处理

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

前端重置密码报错记录

昨天晚上&#xff0c;我写了重置密码的前端&#xff0c;测试的时候报错 今天上午&#xff0c;我继续试图解决这个问题&#xff0c;我仔细检查了一遍&#xff0c;前端没有问题 可以正常接收输入的数据并且提交 但是后端接收到的数据为空&#xff0c;后端接口也没有问题 但后端收…

Sqoop与其他数据采集工具的比较分析

比较Sqoop与其他数据采集工具是一个重要的话题&#xff0c;因为不同的工具在不同的情况下可能更适合。在本博客文章中&#xff0c;将深入比较Sqoop与其他数据采集工具&#xff0c;提供详细的示例代码和全面的内容&#xff0c;以帮助大家更好地了解它们之间的差异和优劣势。 Sq…

openssl3.2 - 官方demo学习 - cms - cms_ver.c

文章目录 openssl3.2 - 官方demo学习 - cms - cms_ver.c概述运行结果笔记END openssl3.2 - 官方demo学习 - cms - cms_ver.c 概述 CMS验签, 将单独签名和联合签名出来的签名文件都试试. 验签成功后, 将签名数据明文写入了文件供查看. 也就是说, 只有验签成功后, 才能看到签名…

解决JuPyter500:Internal Server Error问题

目录 一、问题描述 二、问题分析 三、解决方法 四、参考文章 一、问题描述 在启动Anaconda Prompt后&#xff0c;通过cd到项目文件夹启动Jupyter NoteBook点击.ipynb文件发生500报错。 二、问题分析 base环境下输入指令&#xff1a; jupyter --version 发现jupyter环境…

WebGL在虚拟现实(VR)的应用

WebGL在虚拟现实&#xff08;VR&#xff09;领域的应用日益增多&#xff0c;它为在Web浏览器中创建交互式的虚拟现实体验提供了强大的支持。以下是一些WebGL在VR领域的应用示例&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&am…

Open3D 点云等比例缩放(20)

Open3D 点云等比例缩放(20) 一、算法介绍二、算法实现1.代码世人慌慌张张,不过图碎银几两, 偏偏这碎银几两,能解世间万种慌张。 一、算法介绍 实现这样一个功能,沿着中心,按照指定的比例,比如1/2,缩小或者放大点云,保存到新的文件中 二、算法实现 1.代码 import…