Spirng 當中 Bean的作用域

来源:https://www.cnblogs.com/TheMagicalRainbowSea/p/18166738
-Advertisement-
Play Games

Spirng 當中 Bean的作用域 @目錄Spirng 當中 Bean的作用域每博一文案1. Spring6 當中的 Bean的作用域1.2 singleton 預設1.3 prototype1.4 Spring 中的 bean 標簽當中scope= 屬性其他的值說明1.5 自定義作用域,一個線程 ...


Spirng 當中 Bean的作用域

@

目錄


每博一文案

青年,青年!無論受怎樣的挫折和打擊,都要咬著牙關挺住,因為你們完全有機會重建生活;只要不灰心喪氣,每一次挫折就只不過是通往新境界的一塊普通絆腳石,而絕不會置人於死命
									_____路遙《平凡的世界》
飛機上鄰座的姐姐
獨自一人坐飛機去見異地的男友
異地戀赤誠的人好像越來越少
我不自覺地問她
如果以後分手了不會覺得可惜麽
她一邊低頭和男友報備自己落座了
一邊回答說“我不是確認了不會分手才去愛他的,我恰恰是因為確定了我們有可能會分手才更要
用力去愛他的,更何況,人是用來擁有的,不是嗎”
								———————《網友評論》

1. Spring6 當中的 Bean的作用域

1.2 singleton 預設

預設情況下,Spring的IoC容器創建的Bean對象是單例的。

我們來檢驗一下:

首先,方便大家處理,下麵明確出對應相關的 maven配置信息pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.rainbowsea</groupId>
    <artifactId>spring6-007-circular-dependency</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.11</version>
        </dependency>


        <!-- junit4 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

對應配置的 bean 的類是 User 這個類 ,為了方便辨析,簡單明瞭,這個 類,就不設置屬性了。就是一個空空的類。

package com.rainbowsea.spirngBean;

public class User {
    public User() {
        System.out.println("User() 的無參數構成方法");
    }
}

配置 Spring框架當中的xml 配置文件,讓 Spring 知道我們的 User 這個類,併進行管理

在這裡插入圖片描述

<?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 name="user" class="com.rainbowsea.spirngBean.User"></bean>
</beans>

下麵編寫測試:代碼,進行一個測試,驗證,Spring 預設是否是 單例的 。這裡我們啟動多線程,進行一個測試

在這裡插入圖片描述

package com.ranbowsea.test;

import com.rainbowsea.spirngBean.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class testScope {

    @Test
    public void test01() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring6.xml");
        User user = applicationContext.getBean("user", User.class);
        User user1 = applicationContext.getBean("user", User.class);
        System.out.println(user);
        System.out.println(user1);

        // 啟動線程
        new Thread(new Runnable() {
            @Override
            public void run() {
                User user2 = applicationContext.getBean("user", User.class);
                User user3 = applicationContext.getBean("user", User.class);
                System.out.println(user2);
                System.out.println(user3);
            }
        }).start();
    }
}

在這裡插入圖片描述

從結果上看:

  1. 無參構造方法僅僅只被調用了一次
  2. 四個user對象,的地址是一樣的

說明:無論是執行多少次,applicationContext.getBean ,還是啟動多個線程,都是同一個User對象. 是單例的

這個對象在什麼時候創建的呢?可以為SpringBean提供一個無參數構造方法,測試一下,如下:

在這裡插入圖片描述

從結果上來看:是在 new ClassPathXmlApplicationContext() 的時候就已經,執行了構造方法(Bean對象的創建是在初始化Spring上下文的時候就完成的。)

其中: singletonSpring框架 預設的,也是單例的。

我們可以使用:可以在bean標簽中指定 scope屬性的值為 singleton 。我們測試如下。

在這裡插入圖片描述

<?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 name="user" class="com.rainbowsea.spirngBean.User" scope="singleton"></bean>
</beans>

在這裡插入圖片描述

通過測試得知,沒有指定scope屬性時,預設是singleton單例的。

1.3 prototype

如果想讓Spring的Bean對象以多例 的形式存在,可以在bean標簽中指定 scope屬性的值為:prototype,這樣Spring會在每一次執行getBean()方法的時候創建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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean name="user" class="com.rainbowsea.spirngBean.User" scope="prototype"></bean>
</beans>

我們來是:用 User 這個類進行測試,使用:

在這裡插入圖片描述

在這裡插入圖片描述


import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class testScope {
    @Test
    public void test() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring6.xml");
        User user = applicationContext.getBean("user", User.class);
        User user1 = applicationContext.getBean("user", User.class);
        System.out.println(user);
        System.out.println(user1);

    }
}

從結果上看:

1.調用了兩次無參數構成方法()

2.是兩個不同的 user對象的地址

啟動多個線程,也是會存在多個,user對象的地址的,同時調用多次無參數構成方法()——> 是多例 的。 不像 singleton(預設)的那樣是無論是執行多少次,applicationContext.getBean ,還是啟動多個線程,都是同一個User對象單例的。

在這裡插入圖片描述


import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class testScope {
    @Test
    public void test() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring6.xml");
        User user = applicationContext.getBean("user", User.class);
        User user1 = applicationContext.getBean("user", User.class);
        System.out.println(user);
        System.out.println(user1);

        // 啟動多線程
        new Thread(new Runnable() {
            @Override
            public void run() {
                User user2 = applicationContext.getBean("user", User.class);
                User user3 = applicationContext.getBean("user", User.class);
                System.out.println(user2);
                System.out.println(user3);
            }
        }).start();

    }


}

1.4 Spring 中的 bean 標簽當中scope= 屬性其他的值說明

scope屬性的值不止兩個,它一共包括8個選項:

      1. singleton:預設的,單例。
      2. prototype:原型。每調用一次getBean()方法則獲取一個新的Bean對象。或每次註入的時候都是新對象。
      3. request:一個請求對應一個Bean。僅限於在WEB應用中使用
      4. session:一個會話對應一個Bean。僅限於在WEB應用中使用
      5. global sessionportlet應用中專用的。如果在Servlet的WEB應用中使用global session的話,和session一個效果。(portlet和servlet都是規範。servlet運行在servlet容器中,例如Tomcat。portlet運行在portlet容器中。)
      6. application:一個應用對應一個Bean。僅限於在WEB應用中使用。
      7. websocket:一個websocket生命周期對應一個Bean。僅限於在WEB應用中使用。
      8. 自定義scope:很少使用。

特殊說明: 如果大家,進行了一個實踐測試代碼,可能會發現,IDE工具,僅僅只提示了 scope屬性值的兩個值(singleton,prototype)。就算我們自己手動敲出了其他的值,也是會報 。如下圖所示:

在這裡插入圖片描述

在這裡插入圖片描述

哈哈哈,這個IDE不給我們提示就算了,還給我們報錯。

其實這個並不是IDE工具的問題,而是,我們其他的對應的scope其他屬性的值,是需要在特定的情況下才有用的。比如:我們這裡的 request 是需要在 web 項目當中才是有用的 ,所以 IDE才給我們來了這麼一個錯誤——》爆紅了。

我們可以,在 pom.xml 項目配置文件上,加上一個web 框架,比如:這裡我們加上SpringMVC 就可以了。試試

在這裡插入圖片描述

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.18</version>
        </dependency>

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.rainbowsea</groupId>
    <artifactId>spring6-007-circular-dependency</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.11</version>
        </dependency>


        <!-- junit4 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.18</version>
        </dependency>

    </dependencies>

</project>

在這裡插入圖片描述

1.5 自定義作用域,一個線程一個 Bean

接下來咱們自定義一個Scope,關於線程級別的Scope,

作用:在同一個線程中,獲取的Bean都是同一個。跨線程則是不同的對象。

  • 第一步:自定義Scope。(實現Scope介面)

  • spring內置了線程範圍的類:org.springframework.beans.factory.config.CustomScopeConfigurer,和 org.springframework.context.support.SimpleThreadScope可以直接用。

    • 第二步:將自定義的Scope註冊到Spring容器中。

在這裡插入圖片描述

<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
  <property name="scopes">
    <map>
      <entry key="myThread">
        <bean class="org.springframework.context.support.SimpleThreadScope"/>
      </entry>
    </map>
  </property>
</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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!-- 自定義一個 scope屬性值:作用:在同一個線程中,獲取的Bean都是同一個。跨線程則是不同的對象。-->
    <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
        <property name="scopes"> <!-- set 註入,為該類當中的 name 屬性賦值-->
            <map> <!-- map集合 註入,為該類當中的 key 屬性賦值,也就是我們自定義的 scope的屬性值的名字-->
                <entry key="myThread">
                    <bean class="org.springframework.context.support.SimpleThreadScope"/>
                </entry>
            </map>
        </property>
    </bean>



    <bean name="user" class="com.rainbowsea.spirngBean.User" scope="myThread"></bean>
</beans>

我們還是使用 User 這個類,作為 Bean 進行一個測試。

在這裡插入圖片描述

啟動多個線程,處理。

在這裡插入圖片描述


import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class testScope {
    @Test
    public void test() {
        // 第一個線程
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring6.xml");
        User user = applicationContext.getBean("user", User.class);
        User user1 = applicationContext.getBean("user", User.class);
        System.out.println(user);
        System.out.println(user1);

        // 啟動多線程
        // 第二個線程
        new Thread(new Runnable() {
            @Override
            public void run() {
                User user2 = applicationContext.getBean("user", User.class);
                User user3 = applicationContext.getBean("user", User.class);
                System.out.println(user2);
                System.out.println(user3);
            }
        }).start();

    }
}

從結果上,我們可以看出:

一個線程,調用了一次無參構造方法(),生產一個對象。

成功實現了。在同一個線程中,獲取的Bean都是同一個。跨線程則是不同的對象。

2. 總結:

  1. 預設情況下,Spring的IoC容器創建的Bean對象是單例的。預設是singleton(單例的)
  2. 可以在bean標簽中指定scope屬性的值為:**prototype(多例),預設是singleton(單例的) **
  3. 同時要註意:scope屬性的值不止兩個,它一共包括8個選項:,其他的要在特定的配置下,才能使用,例如:request和session 要是在 web 框架才可以使用。

3. 最後:

“在這個最後的篇章中,我要表達我對每一位讀者的感激之情。你們的關註和回覆是我創作的動力源泉,我從你們身上吸取了無盡的靈感與勇氣。我會將你們的鼓勵留在心底,繼續在其他的領域奮鬥。感謝你們,我們總會在某個時刻再次相遇。”

在這裡插入圖片描述


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • DevTools 非常強大除了常用的查看元素,進行斷點調試或許還有些你不知道的小技巧,小功能。如可以快速的重新發送請求,快速選擇元素,在控制臺中使用npm庫等,讓你能夠更加高效的進行開發。不定時更新~ ...
  • 大家好,我是 Java陳序員。 在日常的工作生活中,我們經常會遇到應付各類強制要求轉發朋友圈的行為,或者是朋友圈集贊的行為。 今天,給大家介紹一個工具,可以幫助你生成朋友圈轉發截圖。 關註微信公眾號:【Java陳序員】,獲取開源項目分享、AI副業分享、超200本經典電腦電子書籍等。 項目介紹 We ...
  • 拖放功能,即將一個元素從一個區域,通過拖拽,放置到另一個區域。常見的應用是將文件或圖片從一個區域,拖放到另一個區域。中文常常把這表述成拖拽,實際上拖拽的描述並不准確,應該叫拖放,因為drag事件和drop事件是成對使用的,即拖拽和放置。 drag在拖拽動作發生時觸發,攜帶被拖拽元素的信息,drop在 ...
  • 1. computed(計算屬性)和方法有什麼區別? 計算屬性本質上是包含 getter 和 setter 的方法 當獲取計算屬性時,實際上是在調用計算屬性的 getter 方法。vue 會收集計算屬性的依賴,並緩存計算屬性的返回結果。只有當依賴變化後才會重新進行計算。 方法沒有緩存,每次調用方法都 ...
  • 大家好,我是 Java陳序員。 今天,給大家介紹一個簡潔、開源的中後臺管理模板項目。 關註微信公眾號:【Java陳序員】,獲取開源項目分享、AI副業分享、超200本經典電腦電子書籍等。 項目介紹 nova-admin —— 一個基於Vue3、Vite5、Typescript、Naive UI, 簡 ...
  • Util UI 已經開發多年, 併在多家公司的項目使用. 不過一直以來, Util UI 存在一些缺陷, 始終未能解決. 最近幾個月, Util 團隊下定決心, 終於徹底解決了所有已知缺陷. Util 應用框架 UI 介紹 Util 應用框架 UI 建立在 Angular , Ng-Zorro, N ...
  • 一、Objects的創建 依據已有的class CPoint ,我們可以產生一個或多個object(對象),或者說是產生一個instance(實體): CPoint aPoint(7.2); // aPoint._x 初始值為 7.2 aPoint.x(5.3); // aPoint._x 現值為 ...
  • 操作系統 :CentOS 7.6_x64 FreeSWITCH版本 :1.10.9 Python版本:3.9.12 進行FreeSWITCH會議室相關功能開發過程中,會遇到需要解析會議室列表信息併進行特定操作的情況,比如設置特定通道變數、發送dtmf、錄音等。今天整理下CentOS7環境下,使用Py ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...