【Spring core学习四】Bean作用域和生命周期

news2024/10/6 18:21:26

目录

一、Bean的作用域

🌈1、被修改的Bean值现象

🌈2、 Bean 的 6 种作⽤域

🌈3、设置作用域 

二、Spring的执行流程

三、Bean的生命周期 

🌈1、Bean生命周期的过程

🌈2、演示生命周期


一、Bean的作用域

🌈1、被修改的Bean值现象

UserService类:

 UserController1类:修改姓名

 UserController2类:

执行结果:

 分析: 公共 Bean,A ⽤户使⽤时,进⾏了修改操作,B ⽤户再去使⽤公共 Bean 的时候,获取到的是被修改的值。操作以上问题的原因是因为 Bean 默认情况下是单例状态(singleton),也就是所有⼈的使⽤的都是同⼀个对象,使⽤单例可以很⼤程度上提⾼性能,Spring 中Bean 的作⽤域默认也是 单例模式。

🌈2、 Bean 的 6 种作⽤域

        Spring 容器在初始化⼀个 Bean 的实例时,同时会指定该实例的作⽤域。Spring有 6 种作⽤域,最后四种是基于 Spring MVC ⽣效的:
(1) singleton:单例作⽤域

        该作⽤域下的Bean在IoC容器中只存在⼀个实例:获取Bean(即通过
applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是同⼀个对象。

        比如我们要区分两个学生一定是属性不同,如果两个个对象各种属性都相同,那么就认为是同一个对象,所以可以共享一个对象的,我们就称为是无状态的。使用场景:一般无状态的Bean,使用该单例作用域,也就是Bean对象的属性不需要更新。(每次获取的Bean都是相同的一个对象)
(2)prototype:原型作⽤域(多例作⽤域)

        每次获取的Bean都是一个新的对象。
(3)request:请求作⽤域

        在一次http请求中获取的是同一个Bean,每次http请求会创建新的Bean实例。类似于prototype。
(4) session:会话作⽤域

        在⼀个session中,是⼀个相同的Bean实例;在Session过期后,获取的就是新的一个Bean。
(5)application:全局作⽤域

        在⼀个http servlet Context中,定义⼀个Bean实例。
(6)websocket:HTTP WebSocket 作⽤域

      在⼀个HTTP WebSocket的⽣命周期中,定义⼀个Bean实例。


单例作⽤域(singleton) VS 全局作⽤域(application)

  • singleton 是 Spring Core 的作⽤域;application 是 Spring Web (Spring MVC)中的作⽤域;
  • singleton 作⽤于 IoC 的容器,⽽ application 作⽤于 Servlet 容器。
  • Application 作用域是对于整个web容器来说,bean的作用域是ServletContext级别的,和singleton有点类似,但是区别在于Application作用域是ServletContext级别,singleton是一个ApplicationContext的单例。一个web 服务,只有一个ServletContext,但是可以有多个ApplicationContext)

演示在一个ApplicationContext下获取到的是同一个单例

🌈3、设置作用域 

使⽤ @Scope 标签就可以⽤来声明 Bean 的作⽤域⽐如设置 Bean 的作⽤域
在第一部分,我们将代码做如下修改:


二、Spring的执行流程

Bean 执⾏流程(Spring 执⾏流程):

  • 启动 Spring 容器
  • 实例化 Bean(分配内存空间,从⽆到有) 
  • Bean 注册到 Spring 中(存操作)
  • 将 Bean 装配到需要的类中(取操作)

三、Bean的生命周期 

🌈1、Bean生命周期的过程

所谓的⽣命周期指的是⼀个对象从诞⽣到销毁的整个⽣命过程,我们把这个过程就叫做⼀个对象的⽣命周期。

Bean 的⽣命周期分为以下 5 ⼤部分:

(1)实例化Bean(为Bean分配内存空间);

(2)设置属性(Bean注入和装配);

(3)Bean初始化:

  • 实现各种Aware通知的方法:如BeanNameAware,BeanFactoryAware,ApplicationContextAware 的接⼝⽅法;
  • 执行BeanPostProcessor初始化前置方法;
  • 执行@PostContruct初始化方法,依赖注入操作之后被执行;
  • 执行自己指定的Init-method方法(如果有指定的话);
  • 执行BeanPostProcessor初始化后置方法;

(4)使用Bean;

(5)销毁Bean。

Bean 的⽣命流程看似繁琐,用一个例子来比喻一下:⽐如我们现在需要买⼀栋房⼦,那么我们的流程是这样的:
1. 先买房(实例化,从⽆到有);
2. 装修(设置属性);
3. 买家电,如洗⾐机、冰箱、电视、空调等([各种]初始化);
4. ⼊住(使⽤ Bean);
5. 卖出去(Bean 销毁)

上面一个过程可能比较抽象,尤其是第三步初始化中,很多顺序理解不清楚,所以遇见比较抽象的东西,我们可以用代码来验证一下。

🌈2、演示生命周期

下面的代码不需要掌握,只是根据代码进一步理解生命周期的执行过程即可。

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">
       <content:component-scan base-package="beanLife"></content:component-scan>
       <bean id = "beanLifeComponent" class = "beanLife.BeanLifeComponent" init-method="init"></bean>
</beans>

 BeanLifeComponent类

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

import javax.annotation.PostConstruct;

//交给Spring管理
@Component
public class BeanLifeComponent implements BeanNameAware {

    //0.构造函数
    public BeanLifeComponent(){
        System.out.println("执行构造函数");
    }

    //1.实现这个接口:通知
    @Override
    public void setBeanName(String s) {
        System.out.println("设置了BeanName:"+s);
    }
    //2.设置前置方法
    @PostConstruct
    public void postConstruct(){
        System.out.println("执行postConstruct方法");
    }
//    这个方法不论是否执行,都会执行12步
    public void sayHello(){
        System.out.println("hello");
    }

    //3、init-method方法
    public void init(){
        System.out.println("执行init方法");
    }

    //4、销毁bean
    public void preDestroy(){
        System.out.println("执行了destroy方法");
    }
}
public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //通过类名拿到对象
        BeanLifeComponent component = context.getBean((BeanLifeComponent.class));
        //执行sayHello方法
//        component.sayHello();
        //销毁方法
        component.preDestroy();
    }
}

测试结果: 与前文的总结顺序一致。

 

注意: 


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

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

相关文章

[MySql]JDBC编程

JDBC&#xff0c;即Java Database Connectivity&#xff0c;java数据库连接。是一种用于执行SQL语句的Java API&#xff0c;它是Java中的数据库连接规范。这个API由 java.sql.*,javax.sql.* 包中的一些类和接口组成&#xff0c;它为Java开发人员操作数据库提供了一个标准的API&…

全域Serverless化,华为云引领下一代云计算新范式

近日&#xff0c;华为开发者大会2023&#xff08;Cloud&#xff09;在东莞成功举办&#xff0c;期间“全域Serverless化&#xff0c;引领下一代云计算新范式”专题论坛人气满满。华为云首席产品官方国伟携手业界专家、客户、伙伴&#xff0c;面向广大开发者&#xff0c;分享了在…

Authing 身份云上线数据对象管理(元数据),助力企业构建唯一身份源

在身份管理领域&#xff0c;元数据具有重要的作用和价值。元数据有助于理解数据的结构和意义&#xff0c;提升数据处理效率&#xff1b;促进跨部门、跨组织的数据共享和协作&#xff1b;以及支持数据分析&#xff0c;为业务决策提供支持等。当前&#xff0c;Authing 身份云已经…

在ICC/ICC2/FC中运行Calibre

1. which calibre找到calibre的安装目录 > which calibre > /eda/mentor/ixl_cal_version/bin/calibre 2. 在 /eda/mentor/ixl_cal_version目录下使用find ./* -name "icc_calibre.tcl",找到icc_calibre.tcl 3. 打开icc_calibre.tcl里面有不同工具(ICC2/FC/…

《Linux0.11源码解读》理解(五) head之开启分页

先回顾一下地址长度以及组合的演变&#xff1a;16位cpu意味着其数据总线/寄存器也是16位&#xff0c;但是地址总线&#xff08;寻址能力&#xff09;与此无关&#xff0c;可能是20位。可以参考&#xff1a;cpu的位宽、操作系统的位宽和寻址能力的关系_cpu位宽_brahmsjiang的博客…

C++——map和set(multimap和multiset)

目录 1.关联式容器 2.键值对 3.树形结构的关联式容器 3.1 set 3.1.1 set的介绍 3.1.2 set的使用 3.2 multiset 3.2.1 multiset的介绍 3.2.2 multiset的使用 3.3 map 3.3.1 map的介绍 3.3.2 map的使用 3.4 multimap 3.4.1 multimap的介绍 3.4.2 multimap的使用 …

抖音小店选品攻略:10个技巧助你选择助轻松学会选品技巧

抖音小店是目前非常火爆的电商平台之一&#xff0c;许多商家都希望能在抖音上开设自己的小店。而在开设抖音小店之前&#xff0c;选品是一个非常重要的环节。下面是不若与众总结的一些抖音小店选品技巧&#xff0c;希望能帮助到你。 1. 确定目标受众&#xff1a;在选品之前&…

数据库应用:MySQL高级语句

目录 一、理论 1.常用查询 2.函数 3.进阶查询 二、实验 1.普通查询 2.函数 3.进阶查询 三、问题 1.MySQL || 运算符不生效 四、总结 一、理论 1.常用查询 常用查询包括&#xff1a;增、删、改、查&#xff1b; 对 MySQL 数据库的查询&#xff0c;除了基本的查询外…

(学习笔记-TCP连接断开)建立了连接,但是客户端或服务端出现问题,会怎么样?

客户端突然出现故障 客户端出现故障指的是客户端的主机发生了宕机或者断电的场景。发生这种情况的时候&#xff0c;如果服务端一直不会发送数据给客户端&#xff0c;那么服务端是永远无法感知到客户端宕机这件事的&#xff0c;也就是服务端的TCP连接将一直处于ESTABLISH 状态&…

两巨头强强联手!美国EB-5投资移民新项目侨外出国首发

7月15日&#xff0c;在侨外出国“见证辉煌历史 重启明日新章”的主题活动中&#xff0c;一个全新乡村EB-5投资移民项目——峰堡长岭天然气开发项目正式扬帆起航。 这一项目&#xff0c;由两大行业巨头——侨外出国和CanAm基金强强联手。众所周知&#xff0c;侨外出国是EB-5投资…

并发编程中常见的锁策略

本文介绍一些常见的锁策略。 锁策略是多线程编程中相对进阶的内容&#xff0c;它不仅仅局限于Java&#xff0c;任何和“锁”相关的话题&#xff0c;都可能会涉及到这些内容&#xff1b;即使是别的语言&#xff0c;只要涉及到“锁”&#xff0c;也都会涉及到锁策略。 锁策略的…

px4上传数据waiting for bootloader

输入make px4_fmu-v6c_default upload&#xff0c;出现waiting for bootloader 原因&#xff0c;可能是启动了QGC占用了端口&#xff0c;把QGC关掉&#xff0c;重新上电&#xff0c;就OK了。

C++ 继承与多态的基本用法

目录 1.继承 1.1访问等级 1.2函数遮蔽 2.多态 2.1虚函数 1.继承 有父类&#xff0c;有子类&#xff0c;这种层次关系就叫继承&#xff0c;也就说说子类能从父类哪里继承很多东西&#xff0c;继承这种概念或性质是面向对象程序设计的核心思想之一。 这种继承需要先定义一个父…

TS类型断言、函数重载踩过的坑

任意属性 interface Person {name: string;age?: number;[propName: string]: string;//报错 } let tom: Person {name: Tom,age: 25,gender: male }; 任意属性需要包含确定属性和可选属性的类型&#xff1a;[propName: string]: string|number; 类型断言 &#x1f449;在…

zabbix企业级监控(监控第二台linux服务器安装部署)接上篇单台监控文章操作

zabbix企业级监控监控linux主机 目录 【agent端配置】&#xff08;监控第二台linux服务器&#xff09; 1、源码安装zabbix&#xff08;解包、编译、配置、安装&#xff09; 2、改agent配置文件 3、启动服务 图形操作&#xff1a; 【agent端配置】&#xff08;监控第二台l…

批处理判断目录是否存并且删除非空目录

这个功能很常用&#xff0c;但是偶尔总是忘记写法&#xff0c;这里贴一个亲测通过的例子吧。 ECHO OFF CLS if exist DirName ( rmdir /q /s DirName ) ELSE ( echo dir NOT exist!)这个例子的功能非常简单&#xff0c;判断目录DirName是否存在&#xff0c;存在就删除&#x…

【Linux】多线程(上)

本文详细介绍了多线程的常见概念 生产者消费者模型将在多线程&#xff08;下&#xff09;继续讲解 欢迎大家指正 提起讨论进步啊 目录 多线程的理解 线程的优点 线程的缺点&#xff1a; 线程的用途 线程VS进程 用户级线程库 POSIX线程库 线程创建&#xff1a; 线程…

【管理设计篇】聊聊系统部署生产有哪些方式

背景 对于互联网应用来说&#xff0c;除了在服务端开发和服务治理之外&#xff0c;还需要保证的有高可用运维。所以很多时候我们不能仅仅局限于&#xff0c;实现需求这个层面&#xff0c;比如软件设计&#xff0c;工程质量&#xff0c;性能&#xff0c;运维、可测试、可观测性…

基于深度学习的高精度交通标志检测系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于CCTSDB数据集的高精度交通标志&#xff08;指示、禁止和警告&#xff09;检测系统可用于日常生活中来检测与定位交通标志目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的交通标志目标检测识别&#xff0c;另外支持结果可视化与图片或视…

【react + antd】antd如何自定义请求使用antd的upload组件实现图片上传且可预览可删除

文章目录 1. 效果展示2. customRequest如何使用&#xff1f;特别注意&#xff1a; 3. 控制上传时什么时候使用customRequest&#xff0c;什么时候选择beforeUpload方法&#xff1f; 1. 效果展示 官网给出的案例无法使用封装好的请求方式上传图片&#xff0c;以及无法满足上传图…