通過spring註解開發,簡單測試單例和多例區別

2022-09-28 01:33:14 字數 2522 閱讀 3920

目錄

配置版:

註解版:

注:以下測試均是註解版

(1)多例:程式設計客棧

配置類:

@configuration

public class personconfigure

}單元測試:

@test

public void test02()

}測試結果:

結論:多例情況下,容器建立完成時不呼叫方法建立物件到容器中,在程式中獲取時,才會將物件載入到容器中,而且每次呼叫生成的都是不同的物件。

(2)單例(註解版)

配置類:

//預設是單例

@configuration

public class pe

}單元測試:

@test

public void test02()

}測試結果:

結論:單例情況下,容器建立時呼叫方法建立物件到容器中,在程式中呼叫bean,直接從容器中拿取,且每次拿取的都是同乙個物件。如果上一次對bean裡的屬性做了修改,那下一次拿取的就是修改過的bean。

單例:所有請求用同乙個物件來處理。通過單例模式,可以保證系統中乙個類只有乙個例項。

多例:每個請求用乙個新的物件來處理。

spring ioc容器的bean都是預設單例的,即spring依賴注入bean例項預設是單例的。

spring提供了5中scope,分別是singleton,prototype,request,session,global session,常用是前兩種。點此檢視官網介紹。

單例bean與多例(原型)bean的區別:

如果乙個bean被宣告為單例的時候,在處理多次請求的時候,在spring容器裡只例項化出乙個bean,後續的請求都公用這個物件,這個物件會儲存在乙個map裡面。當有請求來的時候,會先從快取(map)裡檢視有沒有,有的話直接使用這個物件,沒有的話才例項化乙個新的物件,所以這是個單例的。但是對於原型(prototype)bean來說,當每次請求來的時候,會直接例項化新的bean,沒有快取以及快取查詢的過程。

優勢:由於不會建立新的物件,所以有以下幾個效能上的優勢:

減少新生成例項的消耗。新生成例項包括兩個方面,第一,spring會通過反射或者cglib來生成bean例項,這都是耗效能的操作。第二,給物件分配記憶體也會涉及負責演算法。

減少jvm垃圾**。由於不會給每個請求都生成bean例項,所以**的物件就少了。

可以快速獲取到bean。因為單例獲取操作,除了第一次生成之外,其餘都是從快取裡獲取的,所以很快。

劣勢:乙個很大的劣勢是它不能做到執行緒安全。由於所有請求都共享乙個bean例項,那麼如果這個bean是乙個有狀態的bean的話,在併發場景下就有可能出現問題。

當多使用者同時請求乙個服務時,容器會給每乙個請求分配乙個執行緒,這時多個執行緒會併發執行該請求所對應的業務邏輯(成員方法),此時就要注意了,如果該處理邏輯中有對該單例狀態的修改(體現為該單例的成員屬性),則必須考慮執行緒同步問題(此時該狀態就是乙個臨界資源(共享資料),如果多個執行緒同時操作(修改)這個臨界資源就會誘發執行緒安全問題)。

執行緒安全:如果你的**所在的程序中有多個執行緒在同時執行,而這些執行緒可能會同時執行這段**。如果每次執行的結果和單執行緒執行的結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是執行緒安全的。或者說:乙個類或者程式所提供的介面對於執行緒來說是原子操作,或者多執行緒之間的切換不會導致該介面的執行結果存在二義性,就是執行緒安全的。

執行緒安全問題都是由全域性變數及靜態變數引起的。

若每個執行緒中對全域性變數,靜態變數只有讀操作,而無寫操作,一般來說,這個全域性變數是執行緒安全的;若多個執行緒同時執行寫操作,一般都需要考慮執行緒同步,否則就可能影響執行緒安全。

常量始終是執行緒安全的,因為只存在讀操作;

每次呼叫方法前都新建乙個例項是執行緒安全的,因為不會訪問共享的資源www.cppcns.com;

區域性變數是執行緒安全的。因為每執行乙個方法,都會在獨立的空間建立區域性變數,它不是共享資源。區域性變數包括方法的引數變數和方法內的變數。

在關於spring單例與執行緒安全的很多文章中,會提到乙個概念,即有狀態bean和無狀態bean。

如何解決執行緒安全問題?

(1)使用執行緒同步機制:通過物件的鎖機制保證同一時間只有乙個執行緒訪問變數。這時該變數是多個執行緒共享的,使用同步機制要求程式縝密地分析什麼時候對變數進行讀寫,什麼時候需要鎖定某個物件,什麼時候釋放物件鎖等繁雜問題,程式設計和編寫難度相對較大。

(2)使用threadlocal:為每乙個執行緒提供乙個獨立的變數副本,從而隔離了多個執行緒對資料的訪問衝突。因為每乙個執行緒都擁有自己的變數副本,從而也就沒有必要對該變數進行同步了。

概括起來就是:對於多執行緒資源共享的問題,同步機制採用了「以時間換空間」的方式,而threadlocal採用了「以空間換時間」的方式。前者僅提供乙份變數,讓不同的執行緒排隊訪問,而後者為每乙個執行緒都提供了乙份變數,因此可以同時訪問而互不影響。

scope宣告為prototype,即

@scope(value = configurablebeanfactory.scope_prototype)

本文標題: 通過spring註解開發,簡單測試單例和多例區別

本文位址:

Spring註解開發

spring註解開發 dao層用的註解 repository service層的註解 service controller表現層的註解 controller 以上的三個註解都是用 componment新增三個衍生的註解 屬性依賴注入 value的屬性注入 value wwtmy love 注入的是屬...

spring註解開發

第一步,設定xml約束檔案 第一步,設定xml約束檔案 xmlns xsi xmlns context xsi schemalocation spring beans.xsd spring context.xsd 第二步,定義bean 除了 component外,spring提供了3個功能基本和 c...

Spring註解開發

在spring4之後,要使用註解開發,但是必須保證aop的包存在 使用註解必須保證匯入context約束增加註解的支援 xmlns xmlns xsi xmlns context xsi schemalocation spring beans.xsd spring context.xsd conte...