【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的横空出世刷…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...

【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...