【Spring6】| Bean的作用域
创始人
2024-06-02 12:46:01
0

目录

一: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配置



测试程序

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 原型/多例



执行结果:

得到两次创建的内存地址就不一样了,多例!

 (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

org.springframeworkspring-webmvc6.0.0-M2

此时的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(自定义范围配置器)

 

第三步:使用Scope

完整的spring-cope.xml配置如下:



第四步:执行结果

还是同样的测试代码,可以看出:

对于同一个线程访问的是同一个Bean对象;对于不同的线程访问的是不同的对象!

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...