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
  • 前言 插件化的需求主要源於對軟體架構靈活性的追求,特別是在開發大型、複雜或需要不斷更新的軟體系統時,插件化可以提高軟體系統的可擴展性、可定製性、隔離性、安全性、可維護性、模塊化、易於升級和更新以及支持第三方開發等方面的能力,從而滿足不斷變化的業務需求和技術挑戰。 一、插件化探索 在WPF中我們想要開 ...
  • 歡迎ReaLTaiizor是一個用戶友好的、以設計為中心的.NET WinForms項目控制項庫,包含廣泛的組件。您可以使用不同的主題選項對項目進行個性化設置,並自定義用戶控制項,以使您的應用程式更加專業。 項目地址:https://github.com/Taiizor/ReaLTaiizor 步驟1: ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • Channel 是乾什麼的 The System.Threading.Channels namespace provides a set of synchronization data structures for passing data between producers and consume ...
  • efcore如何優雅的實現按年分庫按月分表 介紹 本文ShardinfCore版本 本期主角: ShardingCore 一款ef-core下高性能、輕量級針對分表分庫讀寫分離的解決方案,具有零依賴、零學習成本、零業務代碼入侵適配 距離上次發文.net相關的已經有很久了,期間一直在從事java相關的 ...
  • 前言 Spacesniffer 是一個免費的文件掃描工具,通過使用樹狀圖可視化佈局,可以立即瞭解大文件夾的位置,幫助用戶處理找到這些文件夾 當前系統C盤空間 清理後系統C盤空間 下載 Spacesniffer 下載地址:https://spacesniffer.en.softonic.com/dow ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • 一、ReZero簡介 ReZero是一款.NET中間件 : 全網唯一開源界面操作就能生成API , 可以集成到任何.NET6+ API項目,無破壞性,也可讓非.NET用戶使用exe文件 免費開源:MIT最寬鬆協議 , 一直從事開源事業十年,一直堅持開源 1.1 純ReZero開發 適合.Net Co ...
  • 一:背景 1. 講故事 停了一個月沒有更新文章了,主要是忙於寫 C#內功修煉系列的PPT,現在基本上接近尾聲,可以回頭繼續更新這段時間分析dump的一些事故報告,有朋友微信上找到我,說他們的系統出現了大量的http超時,程式不響應處理了,讓我幫忙看下怎麼回事,dump也抓到了。 二:WinDbg分析 ...
  • 開始做項目管理了(本人3年java,來到這邊之後真沒想到...),天天開會溝通整理需求,他們講話的時候忙裡偷閑整理一下常用的方法,其實語言還是有共通性的,基本上看到方法名就大概能猜出來用法。出去打水的時候看到外面太陽好好,真想在外面坐著曬太陽,回來的時候好兄弟三年前送給我的鍵盤D鍵不靈了,在打"等待 ...