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

【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 {
    @Test
    public 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 {
    @Test
    public 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 {
    @Test
    public 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 {
    @Test
    public 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() {
            @Override
            public 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对象;对于不同的线程访问的是不同的对象!

相关文章:

  • Linux 命令复习
  • 智能家居项目(八)之树莓派+摄像头进行人脸识别
  • QT获取dll库文件详细信息
  • 常用Swagger注解汇总
  • 【Spring】掌握 Spring Validation 数据校验
  • 【Linux】项目自动化构建工具——make/Makefile
  • 部署OpenStack
  • 网络总结知识点(网络工程师必备)一
  • Java中常用的七种队列你了解多少?
  • 专治Java底子差,不要再认为泛型就是一对尖括号了
  • 《计算机系统基础》——数据的表示
  • 2023-3-2 刷题情况
  • 【数据结构】八大经典排序总结
  • 嵌入式学习笔记——基于Cortex-M的单片机介绍
  • 把数组里面数值排成最小的数
  • C# 免费离线人脸识别 2.0 Demo
  • co.js - 让异步代码同步化
  • CODING 缺陷管理功能正式开始公测
  • HTTP中的ETag在移动客户端的应用
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • Laravel 菜鸟晋级之路
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • MySQL用户中的%到底包不包括localhost?
  • nodejs调试方法
  • node入门
  • Spring框架之我见(三)——IOC、AOP
  • 搭建gitbook 和 访问权限认证
  • 机器学习学习笔记一
  • 前端自动化解决方案
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 突破自己的技术思维
  • 我的面试准备过程--容器(更新中)
  • 一些css基础学习笔记
  • 在electron中实现跨域请求,无需更改服务器端设置
  • 回归生活:清理微信公众号
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • ​HTTP与HTTPS:网络通信的安全卫士
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • #1015 : KMP算法
  • #etcd#安装时出错
  • #Lua:Lua调用C++生成的DLL库
  • (转)Windows2003安全设置/维护
  • (转)大型网站架构演变和知识体系
  • .NET Core 将实体类转换为 SQL(ORM 映射)
  • .NET 解决重复提交问题
  • .net获取当前url各种属性(文件名、参数、域名 等)的方法
  • .NET中两种OCR方式对比
  • [383] 赎金信 js
  • [C/C++]_[初级]_[关于编译时出现有符号-无符号不匹配的警告-sizeof使用注意事项]
  • [c++] 自写 MyString 类
  • [Design Pattern] 工厂方法模式
  • [elastic 8.x]java客户端连接elasticsearch与操作索引与文档
  • [iOS开发]iOS中TabBar中间按钮凸起的实现
  • [ITIL学习笔记]之事件管理(2)
  • [MSSQL]GROUPING SETS,ROLLUP,CUBE初体验