【Spring6】| Bean的作用域
目录
一:Bean的作用域
1. singleton(单例)
2. prototype(多例)
3. 其它scope
4. 自定义scop(了解)
一:Bean的作用域
1. singleton(单例)
(1)默认情况下,Spring的IoC容器创建的Bean对象是单例的(singleton)!
在Spring上下文对象初始化的时候实例化!
SpringBean类
package com.bjpowernode.spring6.bean;public class SpringBean {
}
spring-scop.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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="springBean" class="com.bjpowernode.spring6.bean.SpringBean"/>
</beans>
测试程序
package com.bjpowernode.spring6.test;import com.bjpowernode.spring6.bean.SpringBean;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class SpringScopTest {@Testpublic void testScop(){ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-scop.xml");SpringBean sb1 = applicationContext.getBean("springBean", SpringBean.class);System.out.println(sb1);// 访问同一个对象SpringBean sb2 = applicationContext.getBean("springBean", SpringBean.class);System.out.println(sb2);}
}
执行结果:
通过测试验证:Spring的IoC容器中,默认情况下,Bean对象是单例的!

(2)这个对象在什么时候创建的呢?
可以为SpringBean提供一个无参数构造方法,进行测试:
SpringBean类
package com.bjpowernode.spring6.bean;public class SpringBean {public SpringBean() {System.out.println("SpringBean的无参数构造方法执行了!");}
}
将测试程序中getBean()所在行代码注释掉
package com.bjpowernode.spring6.test;import com.bjpowernode.spring6.bean.SpringBean;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class SpringScopTest {@Testpublic void testScop(){new ClassPathXmlApplicationContext("spring-scop.xml");}
}
执行结果:
通过测试得知,默认情况下,Bean对象的创建是在初始化Spring上下文的时候就完成的!
调用getBean方法只是从Map集合当中取出数据!

2. prototype(多例)
(1)那么就要创建多例的怎么办呢?
如果想让Spring的Bean对象以多例的形式存在,可以在bean标签中指定scope属性的值为:prototype(原型、多例)!
spring-scop.xml配置
增加了scope属性,目前来说scope属性有两个值:
第一个值:singleton 单例(默认情况下不设置就是单例的)
第二个值:prototype 原型/多例
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="springBean" class="com.bjpowernode.spring6.bean.SpringBean" scope="prototype"/>
</beans>
执行结果:
得到两次创建的内存地址就不一样了,多例!

(2)此时是什么时候创建对象呢?
在初始化上下文对象时不会创建对象,每一次执行getBean()方法的时候创建Bean对象,调用几次则创建几次!
SpringBean类
package com.bjpowernode.spring6.bean;public class SpringBean {public SpringBean() {System.out.println("SpringBean的无参数构造方法执行了!");}
}
将测试程序中getBean()所在行代码注释掉
package com.bjpowernode.spring6.test;import com.bjpowernode.spring6.bean.SpringBean;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class SpringScopTest {@Testpublic void testScop(){new ClassPathXmlApplicationContext("spring-scop.xml");}
}
执行结果:
此时并没有执行构造方法,通过测试验证确实是调用getBean方法的时候创建对象!

3. 其它scope
scope属性的值不止两个,它一共包括8个选项:
①singleton:默认的,单例。
②prototype:原型。每调用一次getBean()方法则获取一个新的Bean对象,或每次注入的时候都是新对象。
③request:一个请求对应一个Bean。仅限于在WEB应用中使用。
④session:一个会话对应一个Bean。仅限于在WEB应用中使用。
⑤global session:portlet应用中专用的。如果在Servlet的WEB应用中使用global session的话,和session一个效果。(portlet和servlet都是规范。servlet运行在servlet容器中,例如Tomcat。portlet运行在portlet容器中。)
⑥application:一个应用对应一个Bean。仅限于在WEB应用中使用。
⑦websocket:一个websocket生命周期对应一个Bean。仅限于在WEB应用中使用。
⑧自定义scope:很少使用。
例如:在pom.xml文件当中引入web的框架springmvc
<!--引入web的框架,例如springmvc--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>6.0.0-M2</version>
</dependency>
此时的scop值就可以使用request和session的值

4. 自定义scop(了解)
接下来自定义一个Scope,线程级别的Scope!
在同一个线程中,获取的Bean都是同一个;如果是跨线程则是不同的对象!
(1)先测试单例模式下开启多线程创建的是几个Bean对象
package com.bjpowernode.spring6.test;import com.bjpowernode.spring6.bean.SpringBean;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class SpringScopTest {@Testpublic void testThradScop(){ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-scop.xml");// 主线程SpringBean sb1 = applicationContext.getBean("springBean", SpringBean.class);System.out.println(sb1);SpringBean sb2 = applicationContext.getBean("springBean", SpringBean.class);System.out.println(sb2);// 启动一个新的线程new Thread(new Runnable() {@Overridepublic void run() {SpringBean sb3 = applicationContext.getBean("springBean", SpringBean.class);System.out.println(sb3);SpringBean sb4 = applicationContext.getBean("springBean", SpringBean.class);System.out.println(sb4);}}).start();}
}
测试结果:单例模式,拿到的都是同一个Bean对象

(2)测试自定义scop
第一步:自定义Scope(实现Scope接口)
实际上spring内置了线程范围的类:org.springframework.context.support.SimpleThreadScope,可以直接用!
第二步:将自定义的Scope注册到Spring容器中
注册的时候需要用到自定义范围配置器CustomScopeConfigurer(自定义范围配置器)
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"><property name="scopes"><map><entry key="threadScop"><!--这个Scope接口的实现类使用的是Spring框架内置的,也可以自定义。--><bean class="org.springframework.context.support.SimpleThreadScope"/></entry></map></property></bean>
第三步:使用Scope
<bean id="springBean" class="com.bjpowernode.spring6.bean.SpringBean" scope="threadScop"/>

完整的spring-cope.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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--先开启自定义范围配置器CustomScopeConfigurer--><bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"><property name="scopes"><map><entry key="threadScop"><!--使用内置的线程类:SimpleThreadScope--><bean class="org.springframework.context.support.SimpleThreadScope"/></entry></map></property></bean><!--使用上面自动定义的scope--><bean id="springBean" class="com.bjpowernode.spring6.bean.SpringBean" scope="threadScop"/>
</beans>
第四步:执行结果
还是同样的测试代码,可以看出:
对于同一个线程访问的是同一个Bean对象;对于不同的线程访问的是不同的对象!

相关文章:
【Spring6】| Bean的作用域
目录 一:Bean的作用域 1. singleton(单例) 2. prototype(多例) 3. 其它scope 4. 自定义scop(了解) 一:Bean的作用域 1. singleton(单例) (1…...
Qt界面美化之自定义qss样式表
原生的QT界面不好看,有时候需要根据美工的设计图修改样式。如果使用QML的话搞界面是快,但是QML有点儿吃内存,有时简单的功能还是用传统c的widget方便些。好在有qss,传统界面也可以美化的。QSS称为Qt Style Sheets也就是Qt样式表&a…...
春招进行时:“211文科硕士吐槽工资5500” HR:行情和能力决定价值
学历重要,还是能力重要? 春招进行时,不少学生求职遇冷,会把原因归结为学历水平不够高、毕业院校不够档次、专业不够热门、非一线城市就业机会少等等。 直到上海一位211大学的文科男硕士,吐槽招聘会提供的岗位薪资待遇…...
【DaVinci Developer专题】-45-自动生成SWC中所有Runnable对应的C文件
点击返回「Autosar从入门到精通-实战篇」总目录 案例背景(共5页精讲): 在DaVinci Developer中,以Test_A_SWC的Runnable为例,见图0-1。我们现在尝试自动生成一个包含Test_A_SWC_Init和Test_A_SWC_Main函数原型(也是适用于 C/S Port Serve Runnable)的C文件。 图0-1 目…...
redis启动和关闭服务脚本
编译安装redis,自己写了个脚本。 简单实现启动、关闭和 查看redis服务。 基本流程如下: 脚本执行,必须附带1个参数,没有参数会提示附带参数。 脚本会获取redis-server进程数量。作为开启、关闭以及查看redis服务的数据依据。 …...
windows CMD快捷键:
🐱个人主页:莎萌玩家🙋♂️作者简介:全栈领域新星创作者、专注于全栈各领域技术,共同学习共同进步,一起加油呀!💫系列专栏:网络爬虫、WEB全栈开发📢资料领取…...
【C/C++语言】刷题|双指针|数组|单链表
主页:114514的代码大冒 qq:2188956112(欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ ) Gitee:庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com 文章目录 目录 文章目录 前言 一、删除有序数组中的重复项 二、合并两个有序数组 三,移除…...
Leetcode.1487 保证文件名唯一
题目链接 Leetcode.1487 保证文件名唯一 Rating : 1697 题目描述 给你一个长度为 n的字符串数组 names。你将会在文件系统中创建 n个文件夹:在第 i 分钟,新建名为 names[i]的文件夹。 由于两个文件 不能 共享相同的文件名,因此如…...
python-星号(*)-双星号(**)-函数动态参数匹配-解包操作
文章目录1.乘法和幂运算符2.函数接收数量不固定的入参3.限制函数入参仅以关键字形式输入4. 可迭代对象解包操作5.扩展可迭代对象解包1.乘法和幂运算符 ● 单个 * 用于乘法运算 ● 两个 ** 表示幂运算 >>> 2*3 >>> 6 >>> 2**3 >>> 82.函数…...
面试官:为什么说ArrayList线程不安全?
本博客知识点收录于:⭐️《JavaSE系列教程》⭐️ 1)线程安全与不安全集合 我们学习集合的时候发现集合存在由线程安全集合和线程不安全集合;线程安全效率低,安全性高;反之,线程不安全效率高,安…...
STP详解
STP STP全称为“生成树协议”(Spanning Tree Protocol),是一种网络协议,用于在交换机网络中防止网络回路产生,保证网络的稳定和可靠性。它通过在网络中选择一条主路径(树形结构),并…...
linux AWK常用命令 —— 筑梦之路
搜集整理awk常用命令,以便使用查询 # 打印文件第一列awk {print $1} rumenz.txt# 打印文件前两列awk {print $1,$2} rumenz.txt# 打印文件最后一列awk {print $NF} rumenz.txt# 打印文件总行数awk END{print NR} rumenz.txt# 打印文件第一行awk NR1{print} rumenz.…...
SpringCloud:服务拆分及远程调用
目录 SpringCloud:服务拆分及远程调用 1、服务拆分 2、远程调用 SpringCloud:服务拆分及远程调用 SpringCloud是目前国内使用最广泛的微服务框架。 官网地址: Spring Cloud SpringCloud集成了各种微服务功能组件,并基于SpringBoot实现了…...
网络应用之javascript函数定义和调用
函数定义和调用学习目标能够写出函数的定义和调用方式1. 函数定义函数就是可以重复使用的代码块, 使用关键字 function 定义函数。<script type"text/javascript">// 函数定义function fnAlert(){alert(hello!);} </script>2. 函数调用函数调用就是函数名…...
使用VNC远程连接Ubuntu - 内网穿透实现公网远程办公
写在前面:博主是一只经过实战开发历练后投身培训事业的“小山猪”,昵称取自动画片《狮子王》中的“彭彭”,总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域,如今终有小成…...
JavaScript Date 日期对象
文章目录JavaScript Date 日期对象Date 对象Date 对象属性Date 对象方法创建日期设置日期两个日期比较JavaScript Date 日期对象 日期对象用于处理日期和时间。 Date 对象 Date 对象用于处理日期与实际。 创建 Date 对象: new Date(). 以上四种方法同样可以创建…...
婴幼儿常见八大疾病及护理方法
在1岁之前,婴儿的体质还没有完全发育,很容易生病,大多数婴儿在1岁之后都会更好。今天,新的稀有婴儿育儿专家组织了一些婴儿最容易患的疾病和护理方法。1、新生儿黄疸宝宝出生后,你可能会注意到他的皮肤发黄。别担心&am…...
UVa 817 According to Bartjens 数字表达式 DFS ID 迭代加深搜 逆波兰表达式
题目链接:According to Bartjens 题目描述: 给定一个由数字和一个组成的字符串,你需要在数字之间添加,−,∗,-,*,−,∗三种符号,在保证表达式合法的情况下(同时形成的新的数字不能有前导零),使表…...
c++基础/类和对象
c基础 2.1名字空间 namespace 防止命名冲突 说明:名字空间可以在全局作用域或其他作用域(另一个名字空间)内部定义,但不能在函数或类的内部定义。 使用: #include<iostream> using namespace std; //std中包…...
2023年中国人工智能产业趋势报告
易观:尽管2022年人工智能市场发展活跃度不及预期,但2022年对人工智能产业来说无疑是令人激动的一年。年中由DALL-E 2以及其后Stable Diffusion和Midjourney等文本-图像生成模型引起公众对人工智能生成内容的大量关注,年末ChatGPT的横空出世刷…...
性价比高可代理的油烟分离油烟机的厂家
最近跟10多个开厨电店的老板喝茶,一半人唉声叹气:去年赚的钱全压库存里了,3个做了十几年的老老板说,再找不到好产品,今年打算把店转了。为啥好好的店做成这样?说白了就是选品选错了,风口变了&am…...
小熊猫Dev-C++:5分钟搞定C++开发环境的终极解决方案 [特殊字符]
小熊猫Dev-C:5分钟搞定C开发环境的终极解决方案 🚀 【免费下载链接】Dev-CPP A greatly improved Dev-Cpp 项目地址: https://gitcode.com/gh_mirrors/dev/Dev-CPP 你是否曾为复杂的C开发环境配置而头疼?是否厌倦了臃肿的IDE占用大量系…...
EDA工具链互操作性:从概念到实践,破解芯片设计数据孤岛
1. 互操作性:一个被误解的工程圣杯 在半导体和电子设计自动化(EDA)这个行当里干了十几年,我听到“互操作性”这个词的频率,可能比听到“摩尔定律”还要高。每次行业巨头们坐下来,宣布要共同制定一个新标准时…...
ARM A64指令集架构解析与优化实践
1. A64指令集架构概述A64指令集作为ARMv8-A架构的64位执行状态核心,采用固定32位长度编码设计,这种设计在指令获取和流水线处理上具有显著优势。与传统的变长指令集相比,固定长度编码使得指令预取和译码阶段更加高效,尤其适合现代…...
ScrollNice:用虚拟滚动区域替代鼠标滚轮的Windows效率工具
1. 项目概述:当鼠标滚轮失灵时,我们如何优雅地“滚动”?作为一名长期与代码和文档打交道的开发者,我深知一个顺手的鼠标滚轮有多重要。但现实往往很骨感——无论是用了多年的老鼠标滚轮开始“打滑”,还是在某些需要单手…...
KouriChat + DeepSeek + 微信接入:本地 AI 角色聊天机器人搭建实录
🎁个人主页:User_芊芊君子 🎉欢迎大家点赞👍评论📝收藏⭐文章 🔍系列专栏:AI 文章目录: 前言1 KouriChat项目简介2 环境准备3 环境安装及项目部署3.1 Python3.11 安装3.2 启动KouriC…...
RO-ViT:区域感知预训练如何革新开放词汇目标检测
1. 项目概述:从“闭门造车”到“开箱即用”的视觉检测新范式在计算机视觉领域,目标检测一直是个硬骨头。传统的检测模型,比如我们熟悉的Faster R-CNN、YOLO系列,都遵循一个“闭集”范式:模型在训练时见过多少类物体&am…...
革命性HTTP API设计指南:Heroku实战经验全解析
革命性HTTP API设计指南:Heroku实战经验全解析 【免费下载链接】http-api-design HTTP API design guide extracted from work on the Heroku Platform API 项目地址: https://gitcode.com/gh_mirrors/ht/http-api-design GitHub 加速计划 / ht / http-api-d…...
GitAhead本地化配置详解:打造最适合你的中文Git环境
GitAhead本地化配置详解:打造最适合你的中文Git环境 【免费下载链接】gitahead Understand your Git history! 项目地址: https://gitcode.com/gh_mirrors/gi/gitahead GitAhead是一款功能强大的Git客户端工具,旨在帮助开发者更直观地理解和管理G…...
德国工业4.0工程师指南:从系统融合到职业发展
1. 项目概述:为什么德国是工业工程师的理想目的地?如果你是一名工业、自动化或机器人领域的工程师,正在寻找一个能将你的技术抱负与前沿产业实践深度结合的职业舞台,那么德国很可能就是你一直在寻找的答案。这不仅仅是因为德国拥有…...
