当前位置: 首页 > news >正文

【JavaEE进阶】Bean 作用域和生命周期

文章目录

  • 一. 关于Bean作用域的实例
    • 1. lombok
    • 2. 实例代码
  • 二. 作用域定义
    • 1. Bean的六种作用域
    • 2. 设置作用域
  • 三. Spring 执行流程和 Bean 的生命周期
    • 1. Spring 执行流程
    • 2. Bean生命周期

一. 关于Bean作用域的实例

注意在此例子中需要用到lombok

1. lombok

lombok是什么?
Lombok 是一个 Java 库,它通过注解的方式来简化 Java 代码的编写。它提供了一组注解,让我们可以通过在代码中添加这些注解来自动生成样板式的代码,如 getter、setter、构造函数、toString 等。

使用 Lombok 可以有效地减少冗余的样板代码,提高代码的可读性和开发效率。不需要手动编写大量的 getter 和 setter 方法,也不需要重复编写 equals、hashCode 和 toString 方法等。通过简单地添加几个注解,Lombok 会在编译时自动生成这些常见的方法和实现。

lombok的使用:

  1. 在框架中添加lombok依赖.
    在这里插入图片描述
    在这里插入图片描述
  2. 在实体类上使用lombok提供的注解.
    在这里插入图片描述
  3. 安装lombok插件在这里插入图片描述

2. 实例代码

Users:

package com.java.demo.enity;import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;@Controller
public class Users {@Beanpublic User user1(){User user = new User();user.setId(1);user.setName("xxxflower");return user;}
}

UserControlle:

package com.java.demo.controller;import com.java.demo.enity.User;
import org.springframework.stereotype.Controller;import javax.annotation.Resource;@Controller
public class UserController {@Resourceprivate User user1;public User UserPrint1() {User user = user1;System.out.println("Bean 原 Name:" + user.getName());user.setName("且听风吟"); // 进⾏了修改操作System.out.println("UserController 修改后 Name: "+user.getName());return user;}
}

UserController2:

package com.java.demo.controller;import com.java.demo.enity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController2 {@Autowiredprivate User user1;public User UserPrint2() {User user = user1;System.out.println(user.toString());return user;}
}

App:

package com.java.demo;import com.java.demo.controller.UserController;
import com.java.demo.controller.UserController2;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;@Controller
public class App {public static void main(String[] args) {ApplicationContext context =new ClassPathXmlApplicationContext("spring-config.xml");UserController userController = context.getBean("userController",UserController.class);System.out.println(userController.UserPrint1());UserController2 userController2 = context.getBean("userController2",UserController2.class);System.out.println(userController2.UserPrint2());}
}

代码预计运行结果:
在这里插入图片描述
代码实际运行结果:
在这里插入图片描述

我们可以看到上述第三行代码和我们预计的结果不符,这是为什么呢?
以上问题的原因是Bean默认情况下采用的是单例状态.(singleton),也就是所有的人使用的都是同一个Bean对象.在我们之前学习过的单例模式中,采用单例模式可以很大程度上提高性能,所以在Spring中Bean的作用域默认也是 singleton 单例模式.

二. 作用域定义

限定程序中变量的可⽤范围叫做作⽤域,或者说在源代码中定义变量的某个区域就叫做作⽤域。
Bean 的作用域是指 Bean 在 Spring 整个框架中的某种⾏为模式.比如 singleton 单例作⽤域,就表示 Bean 在整个 Spring 中只有⼀份,它是全局共享的,那么当其他⼈修改了这个值之后,那么另⼀个⼈读取到的就是被修改的值。

1. Bean的六种作用域

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

  1. 单例模式: singleton(默认模式) -> 性能的考虑
  2. 原型模式: prototype
  3. 请求作用域:request,每次 HTTP请求,都会创建一个Bean对象。【适用于Spring MVC/Spring Web】
  4. 会话作用域:session,每次Session会话共享一个Bean。【Spring MVC】
  5. 全局作用域: application,一个http servlet context 中共享一个bean。【Spring MVC】
  6. webscoket: 网络长连接,只适用于Spring WebSocket 项目。

注意后 4 种状态是 Spring MVC 中的值,在普通的 Spring 项⽬中只有前两种.

singleton

  • 官⽅说明:(Default) Scopes a single bean definition to a single object instance for each Spring IoC container.
  • 描述:该作⽤域下的Bean在IoC容器中只存在⼀个实例:获取Bean(即通过applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是同⼀个对 象。
  • 场景:通常⽆状态的Bean使⽤该作⽤域。⽆状态表示Bean对象的属性状态不需要更新 备注:Spring默认选择该作⽤域

prototype

  • 官⽅说明:Scopes a single bean definition to any number of object instances.
  • 描述:每次对该作⽤域下的Bean的请求都会创建新的实例:获取Bean(即通过applicationContext.getBean等⽅法获取)及装配 Bean(即通过@Autowired注⼊)都是新的对象实例。
  • 场景:通常有状态的Bean使⽤该作⽤域

request

  • 官⽅说明:Scopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
  • 描述:每次http请求会创建新的Bean实例,类似于prototype
  • 场景:⼀次http的请求和响应的共享Bean
  • 备注:限定SpringMVC中使⽤

session

  • 官⽅说明:Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
  • 描述:在⼀个http session中,定义⼀个Bean实例
  • 场景:⽤户回话的共享Bean, ⽐如:记录⼀个⽤户的登陆信息
  • 备注:限定SpringMVC中使⽤

2. 设置作用域

使⽤ @Scope 标签就可以⽤来声明 Bean 的作⽤域,⽐如设置 Bean 的作⽤域,如下代码所示:

package com.java.demo.enity;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 Users {//使用@Scope声明Bean作用域@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)@Beanpublic User user1(){User user = new User();user.setId(1);user.setName("xxxflower");return user;}
}

运行结果:
在这里插入图片描述
我们可以看到,在使用prototype时运行结果与预期结果相同.
关于@Scope的写法有两种:

  1. 直接设置值:@Scope("prototype")
  2. 使⽤枚举设置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

三. Spring 执行流程和 Bean 的生命周期

1. Spring 执行流程

  1. 在main方法中遇到Application时启动spring容器。
  2. 此时根据容器设置的配置文件去找相应配置文件。
  3. 如果存在basepackage 。此时去循环查看basepackage中是否有五大类注解。
  4. 如果有五大类注解,此时进行初始化和属性依赖的赋值。
  5. 操作spring依赖 读修改 书写业务
  6. 关闭容器 释放资源

图解:
在这里插入图片描述
Bean 执⾏流程(Spring 执⾏流程):启动 Spring 容器 -> 实例化 Bean(分配内存空间,从⽆到
有) -> Bean 注册到 Spring 中(存操作) -> 将 Bean 装配到需要的类中(取操作)。

2. Bean生命周期

Bean 的生命周期是指一个 Bean 在被创建、初始化、使用和销毁的整个过程。
Bean 生命周期(从诞生到销毁过程):

  1. 开辟内存空间:实例化≠初始化
  2. 设置属性(注入属性)
  3. 初始化
    3.1 各种通知
    3.2 初始化前置方法
    3.3 初始化方法【两种实现方式: xml 方式、注解方式】
    3.4 初始化后置方法
  4. 使用 Bean
  5. 销毁Bean对象
    销毁容器的各种⽅法,如 @PreDestroy、DisposableBean 接⼝⽅法、destroy-method。

注意:一定是先设置属性,再初始化.因为初始化的时候可能用到属性的内容.

在这里插入图片描述
生命周期演示:

首先,我们创建一个名为 ExampleBean 的 Java 类,实现了 Spring 的 InitializingBeanDisposableBean 接口,这两个接口提供了在 Bean 初始化和销毁时的回调方法。

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;public class ExampleBean implements InitializingBean, DisposableBean {public ExampleBean() {System.out.println("ExampleBean 构造函数");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("ExampleBean 初始化方法");}public void doSomething() {System.out.println("ExampleBean 执行业务逻辑");}@Overridepublic void destroy() throws Exception {System.out.println("ExampleBean 销毁方法");}
}

然后,在 Spring 的配置文件中声明该 Bean,并将其注入到其他类中使用:

<?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.java.demo"></content:component-scan><bean id="exampleBean" class="com.java.demo.ExampleBean" scope="singleton" init-method="afterPropertiesSet" destroy-method="destroy"/></beans>

在上述配置中,我们将 ExampleBean 声明为一个 singleton 的 Bean,并指定了初始化方法为 afterPropertiesSet,销毁方法为 destroy

接下来,我们创建一个简单的测试类 ExampleApp 来使用 ExampleBean

package com.java.demo;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class ExampleApp {public static void main(String[] args) {// 加载 Spring 的配置文件ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");// 获取 ExampleBean 实例ExampleBean exampleBean =context.getBean("exampleBean",ExampleBean.class);// 执行业务逻辑exampleBean.doSomething();// 关闭 Spring 容器,触发 Bean 的销毁方法try {exampleBean.destroy();} catch (Exception e) {e.printStackTrace();}}
}

运行 ExampleApp 类,结果如下:

在这里插入图片描述
需要注意的是,Bean 的生命周期可以进一步通过添加自定义的初始化和销毁方法来扩展。可以使用 @PostConstruct @PreDestroy 注解,或者在 Spring 配置文件中通过 init-methoddestroy-method 属性来指定自定义的初始化和销毁方法。

相关文章:

【JavaEE进阶】Bean 作用域和生命周期

文章目录 一. 关于Bean作用域的实例1. lombok2. 实例代码 二. 作用域定义1. Bean的六种作用域2. 设置作用域 三. Spring 执行流程和 Bean 的生命周期1. Spring 执行流程2. Bean生命周期 一. 关于Bean作用域的实例 注意在此例子中需要用到lombok 1. lombok lombok是什么? Lo…...

3分钟自建查分系统?现在每个人都可以实现了

学生成绩查询系统在现代教育管理中扮演着重要的角色&#xff0c;它不仅可以方便学生和家长查询成绩&#xff0c;也能帮助老师更好地管理和分析学生的学业表现。作为一名教师&#xff0c;了解如何制作学生成绩查询系统是提高教学效率和管理学生成绩便利性的关键。 在制作学生成…...

关于APP备案、小程序备案的问题,如何备案?

近日&#xff0c;工信部发布了关于开展移动互联网应用程序备案工作的通知。为落实相关法律法规要求&#xff0c;促进互联网行业规范健康发展&#xff0c;进一步做好移动互联网信息服务管理&#xff0c;现组织开展移动互联网应用程序&#xff08;以下简称 APP&#xff09;备案工…...

git上传代码后,如何清空历史日志以及文件操作,重新上传?以及上传代码

【Git教程】如何清除git仓库的所有提交记录&#xff0c;成为一个新的干净仓库  马三也算Github的忠实用户了&#xff0c;经常会把一些练手的项目传到Github上面进行备份。其中有一个名为ColaFramework的Unity框架项目&#xff0c;马三开发了一年多了&#xff0c;期间提交代码的…...

超导热催生meme,换汤不换药的投机轮回

文/章鱼哥 出品/陀螺财经 币圈对炒作meme概念的热情从未消亡过。 随着一种名为LK-99的物质被发现&#xff0c;围绕超导的兴奋不仅激发了科学界&#xff0c;加密货币相关概念也与之沸腾。不出所料&#xff0c;与此前围绕元宇宙、AI大肆炒作一样&#xff0c;许多meme代币已经出现…...

【HashMap】 73. 矩阵置零

73. 矩阵置零 解题思路 首先遍历矩阵找到所有的0元素 将其的行和列索引记录下俩遍历矩阵 将所有的需要更新的元素进行更新 也就是查找hashmap中的每一个元素进行更新查找行或者列是否在hashmap中 class Solution {public void setZeroes(int[][] matrix) {// 首先遍历矩阵找…...

Vue-2.nodejs的介绍和安装

nodejs简介 ► 创建 Node.js 应用:package.json 首先&#xff0c;创建一个新文件夹以便于容纳需要的所有文件&#xff0c;并且在此其中创建一个 package.json 文件&#xff0c;描述你应用程序以及需要的依赖&#xff1a; 配合着你的 package.json 请运行 npm install。如果你…...

分别用Vue和Java来实现的风靡一时的2048 游戏

目录 1、Vue实现2、Java实现 2048 游戏是一个基于网格的数字益智游戏&#xff0c;玩家需要通过滑动相同的数字来合并它们&#xff0c;并最终得到一个值为 2048 的方块。以下是分别用Vue和Java来实现的 2048 游戏&#xff0c;包含运行效果。 1、Vue实现 首先&#xff0c;创建一…...

echarts甘特图 一个值多条线

先看图 这里我们用到的是 series &#xff1a;type:custom 自定义&#xff0c;但是这里我遇到一个问题&#xff0c;就是不过你在series里push多少数据&#xff0c;图表上显示的都是在同一水平线&#xff0c;用了好多方法都不好使&#xff0c; renderItem: (params, api) >…...

多态性说明

多态 多态性多态性类型描述编译时多态和运行时多态的差异go 语言多态性 多态性 多态性类型描述 多态性是面向对象编程中的一个重要概念&#xff0c;它允许不同的对象通过相同的接口表现出不同的行为&#xff0c;从而实现更加灵活和可扩展的代码结构。多态性有助于降低代码的耦…...

2023-08-04 LeetCode每日一题(不同路径 III)

2023-08-04每日一题 一、题目编号 980. 不同路径 III二、题目链接 点击跳转到题目位置 三、题目描述 在二维网格 grid 上&#xff0c;有 4 种类型的方格&#xff1a; 1 表示起始方格。且只有一个起始方格。2 表示结束方格&#xff0c;且只有一个结束方格。0 表示我们可以…...

腾讯云服务器地域怎么选?可用区是什么?

腾讯云服务器地域有什么区别&#xff1f;怎么选择比较好&#xff1f;地域选择就近原则&#xff0c;距离地域越近网络延迟越低&#xff0c;速度越快。关于地域的选择还有很多因素&#xff0c;地域节点选择还要考虑到网络延迟速度方面、内网连接、是否需要备案、不同地域价格因素…...

第一百二十三天学习记录:C++提高:STL-vector容器(下)(黑马教学视频)

vector插入和删除 功能描述&#xff1a; 对vector容器进行插入、删除操作 函数原型&#xff1a; push_back(ele); //尾部插入元素ele pop_back(); //删除最后一个元素 insert(const_iterator pos, ele); //迭代器指向位置pos插入元素ele insert(const_iterator pos, int cou…...

谈谈Spring与字节码生成技术

Spring框架是一个面向企业级Java应用开发的开源框架&#xff0c;它提供了许多功能和特性来简化Java开发过程。字节码生成技术在Spring框架中起着重要的作用&#xff0c;用于实现依赖注入&#xff08;Dependency Injection&#xff09;和面向切面编程&#xff08;Aspect-Oriente…...

Java数组详解 -- 基础知识与常用操作

文章目录 前言一、初识数组1. 数组的定义2. 数组的特点3. 声明和初始化数组4. 默认初始化值 二、访问和操作数组元素1. 数组的索引和范围2. 通过索引访问数组元素3. 修改数组元素的值 三、数组的长度和属性1. 数组的长度计算2. 数组的长度属性3. 数组越界的错误 四、数组的遍历…...

(统计学习方法|李航)第五章 决策树——一二三节:决策树模型与学习,特征选择,决策树的生成,

目录 一&#xff0c;决策树模型与学习 1.决策数模型 2.决策树与if-then规则 3.决策树与条件概率分布 4.决策树学习 二&#xff0c;特征选择 1.特征选择问题 2.信息增益 3.信息增益比 三&#xff0c;决策树的生成 1.ID3算法 2.C4.5的生成算法 一&#xff0c;决策树模型…...

qt lamda表达式及捕获变量列表符号说明及示例

问题描述: 最近发现很多人都喜欢用Lamda表达式了,至于他们到底知不知道自己用的是什么意思,那就另说了。 虽然我个人并不太喜欢,因为很多地方没法像以前信号和槽那样清晰了,而且很多生成UML的软件估计也不支持解析转成对应的序列图啥的。 但是这个lamda写法确实挺方便的…...

第十六章、【Linux】程序管理与SELinux初探

16.1 什么是程序 &#xff08;process&#xff09; 在Linux 系统当中&#xff1a;“触发任何一个事件时&#xff0c;系统都会将他定义成为一个程序&#xff0c;并且给予这个程序一个 ID &#xff0c;称为 PID&#xff0c;同时依据启发这个程序的使用者与相关属性关系&#xff…...

ElasticSearch索引生命周期管理--DELETE

概要 ElasticSearch中的索引生命周期管理&#xff0c;也就是ilm&#xff08;Manage the index lifecycle&#xff09;,是指定了索引在不同周期下的处理策略。ilm 的对象是索引而不是索引中的数据。ilm 包括四个阶段&#xff1a;hot 、warm、cold和delete。hot、warm和cold表示…...

sentinel简单使用

核心demo&#xff1a; 1 引入依赖: <dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-core</artifactId><version>1.8.0</version> </dependency>2 核心代码&#xff1a; 3 限流保护代码&#xff1a;…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...