javascript
Spring bean相关
Spring中指定Bean的作用于的方式
以下四種為例:
-
單例(默認,可以不用特殊表明)
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON) -
多例
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) -
session
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.INTERFACES) -
request
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
session和request類型的作用域時,如果需要將該對象注入到單例Bean中,需要指明代碼模式
ps: 如果注入的是接口類型的話:proxyMode使用INTERFACES即可,如果是時一個類時,則需要為TARGET_CLASS類型(這個表示使用CGLIB代理)
spring中 bean在什么時候創建的?
singleton(單例):只有一個共享的實例存在,所有對這個bean的請求都會返回這個唯一的實例。
此取值時表明容器中創建時只存在一個實例,所有引用此bean都是單一實例。如同每個國家都有一個總統,國家的所有人共用此總統,而這個國家就是一個spring容器,總統就是spring創建的類的bean,國家中的人就是其它調用者,總統是一個表明其在spring中的scope為singleton,也就是單例模型。
此外,singleton類型的bean定義從容器啟動到第一次被請求而實例化開始,只要容器不銷毀或退出,該類型的bean的單一實例就會一直存活,典型單例模式,如同servlet在web容器中的生命周期。
prototype(多例):對這個bean的每次請求都會創建一個新的bean實例,類似于new。
spring容器在進行輸出prototype的bean對象時,會每次都重新生成一個新的對象給請求方,雖然這種類型的對象的實例化以及屬性設置等工作都是由容器負責的,但是只要準備完畢,并且對象實例返回給請求方之后,容器就不在擁有當前對象的引用,請求方需要自己負責當前對象后繼生命周期的管理工作,包括該對象的銷毀。也就是說,容器每次返回請求方該對象的一個新的實例之后,就由這個對象“自生自滅”。
懶加載bean使用: @Lazy
一般情況下,Spring容器在啟動時會創建所有的Bean對象,使用@Lazy注解可以將Bean對象的創建延遲到第一次使用Bean的時候
Spring 為啥默認把設計成單例的?
熟悉spring開發的朋友都知道spring 提供了5種scope分別是singleton, prototype, request, session,global session。如下圖是官方文檔上的截圖,感興趣的朋友可以進去看看這五種分別有什么不同。今天要介紹的是這五種中的前兩種,也是spring最初提供的bean scope singleton 和 prototype。
spring 官方文檔介紹如下圖:
更多內容可以看官方文檔介紹,非常詳細:Spring bean作用域
-
單例bean與原型bean的區別
如果一個bean被聲明為單例的時候,在處理多次請求的時候在spring 容器里只實例化出一個bean,后續的請求都公用這個對象,這個對象會保存在一個map里面。當有請求來的時候會先從緩存(map)里查看有沒有,有的話直接使用這個對象,沒有的話才實例化一個新的對象,所以這是個單例的。但是對于原型(prototype)bean來說當每次請求來的時候直接實例化新的bean,沒有緩存以及從緩存查的過程。
1.畫圖分析
2.源碼分析
生成bean時先判斷單例的還是原型的
如果是單例的則先嘗試從緩存里獲取,沒有在新創建
結論:
1.單例的bean只有第一次創建新的bean 后面都會復用該bean,所以不會頻繁創建對象。
2.原型的bean每次都會新創建
單例bean的優勢
由于不會每次都新創建新對象所以有一下幾個性能上的優勢:
1.減少了新生成實例的消耗 新生成實例消耗包括兩方面,第一,spring會通過反射或者cglib來生成bean實例這都是耗性能的操作,其次給對象分配內存也會涉及復雜算法
2.減少jvm垃圾回收 由于不會給每個請求都新生成bean實例,所以自然回收的對象少了
3.可以快速獲取到bean 因為單例的獲取bean操作除了第一次生成之外其余的都是從緩存里獲取的所以很快
單例bean的劣勢
單例的bean一個很大的劣勢就是他不能做到線程安全!!!,由于所有請求都共享一個bean實例,所以這個bean要是有狀態的一個bean的話可能在并發場景下出現問題,而原型的bean則不會有這樣問題(但也有例外,比如他被單例bean依賴),因為給每個請求都新創建實例。
總結
Spring 為啥把bean默認設計成單例?
答案:為了提高性能!!!從幾個方面,1.少創建實例2.垃圾回收3.緩存快速獲取
總結
以上是生活随笔為你收集整理的Spring bean相关的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Springboot消除switch-c
- 下一篇: html-mailto