1. 程式人生 > 程式設計 >Spring bean為什麼預設是單例

Spring bean為什麼預設是單例

熟悉Spring開發的朋友都知道Spring提供了5種scope分別是singleton、prototype、request、session、global session。

如下圖是官方文件上的截圖,感興趣的朋友可以進去看看這五種分別有什麼不同。今天要介紹的是這五種中的前兩種,也是Spring最初提供的bean scope singleton 和 prototype。

Spring官方文件介紹如下圖:

Spring bean為什麼預設是單例

更多內容可以看官方文件介紹,非常詳細:

https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s04.html

一、單例bean與原型bean的區別

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

1、畫圖分析

Spring bean為什麼預設是單例

Spring bean為什麼預設是單例

2、原始碼分析

生成bean時先判斷單例的還是原型的

Spring bean為什麼預設是單例

如果是單例的則先嚐試從快取裡獲取,沒有在新建立

Spring bean為什麼預設是單例

結論:

單例的bean只有第一次建立新的bean 後面都會複用該bean,所以不會頻繁建立物件原型的bean每次都會新建立

二、單例bean的優勢

由於不會每次都新建立新物件所以有一下幾個效能上的優勢。

1、減少了新生成例項的消耗

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

2、減少jvm垃圾回收

由於不會給每個請求都新生成bean例項,所以自然回收的物件少了。

3、可以快速獲取到bean

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

三、單例bean的劣勢

單例的bean一個很大的劣勢就是他不能做到執行緒安全!由於所有請求都共享一個bean例項,所以這個bean要是有狀態的一個bean的話可能在併發場景下出現問題,而原型的bean則不會有這樣問題(但也有例外,比如他被單例bean依賴),因為給每個請求都新建立例項。

四、總結

1、Spring 為啥把bean預設設計成單例?為了提高效能少建立例項垃圾回收快取快速獲取

2、單例有啥劣勢?

如果是有狀態的話在併發環境下執行緒不安全

3、什麼是有狀態物件?什麼是無狀態物件?有狀態物件:有例項變數可以標誌其物件所處的狀態。(有例項變數的物件,有儲存資料能力)- 白話:有屬性的物件無狀態物件:無例項變數可以標誌其物件所處的狀態。(無例項變數的物件,無儲存資料能力)- 白話:無屬性的物件

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。