spring中bean的五種作用域?Spring中的bean是線程安全的嗎?


spring中bean的五種作用域

當通過spring容器創建一個Bean實例時,不僅可以完成Bean實例的實例化,還可以為Bean指定特定的作用域。Spring支持如下5種作用域:

  • singleton:單例模式,在整個Spring IoC容器中,使用singleton定義的Bean將只有一個實例

  • prototype:原型模式,每次通過容器的getBean方法獲取prototype定義的Bean時,都將產生一個新的Bean實例

  • request:對於每次HTTP請求,使用request定義的Bean都將產生一個新實例,即每次HTTP請求將會產生不同的Bean實例。只有在Web應用中使用Spring時,該作用域才有效

  • session:對於每次HTTP Session,使用session定義的Bean豆漿產生一個新實例。同樣只有在Web應用中使用Spring時,該作用域才有效

  • globalsession:每個全局的HTTP Session,使用session定義的Bean都將產生一個新實例。典型情況下,僅在使用portlet context的時候有效。同樣只有在Web應用中使用Spring時,該作用域才有效

  其中比較常用的是singleton和prototype兩種作用域。對於singleton作用域的Bean,每次請求該Bean都將獲得相同的實例。容器負責跟蹤Bean實例的狀態,負責維護Bean實例的生命周期行為;如果一個Bean被設置成prototype作用域,程序每次請求該id的Bean,Spring都會新建一個Bean實例,然后返回給程序。在這種情況下,Spring容器僅僅使用new 關鍵字創建Bean實例,一旦創建成功,容器不在跟蹤實例,也不會維護Bean實例的狀態。

  如果不指定Bean的作用域,Spring默認使用singleton作用域。Java在創建Java實例時,需要進行內存申請;銷毀實例時,需要完成垃圾回收,這些工作都會導致系統開銷的增加。因此,prototype作用域Bean的創建、銷毀代價比較大。而singleton作用域的Bean實例一旦創建成功,可以重復使用。因此,除非必要,否則盡量避免將Bean被設置成prototype作用域。

 

參考鏈接:Spring中Bean的五個作用域

 

Spring中的bean是線程安全的嗎?

spring 管理的 bean 的線程安全跟 bean 的創建作用域和 bean 所在的使用環境是否存在競態條件有關,spring 並不能保證 bean 的線程安全。

原型Bean
  對於原型Bean,每次創建一個新對象,也就是線程之間並不存在Bean共享,自然是不會有線程安全的問題。
單例Bean
  對於單例Bean,所有線程都共享一個單例實例Bean,因此是存在資源的競爭。
  如果單例Bean,是一個無狀態Bean,也就是線程中的操作不會對Bean的成員執行查詢以外的操作,那么這個單例Bean是線程安全的。比如Spring mvc 的 Controller、Service、Dao等,這些Bean大多是無狀態的,只關注於方法本身。
spring單例,為什么controller、service和dao確能保證線程安全?
  Spring中的Bean默認是單例模式的,框架並沒有對bean進行多線程的封裝處理。
  實際上大部分時間Bean是無狀態的(比如Dao) 所以說在某種程度上來說Bean其實是安全的。
  但是如果Bean是有狀態的 那就需要開發人員自己來進行線程安全的保證,最簡單的辦法就是改變bean的作用域 把 "singleton"改為’‘protopyte’ 這樣每次請求Bean就相當於是 new Bean() 這樣就可以保證線程的安全了。
  有狀態就是有數據存儲功能
  無狀態就是不會保存數據
  controller、service和dao層本身並不是線程安全的,只是如果只是調用里面的方法,而且多線程調用一個實例的方法,會在內存中復制變量,這是自己的線程的工作內存,是安全的。

所以其實任何無狀態單例都是線程安全的。

 

參考鏈接:spring中的bean是線程安全的嗎?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM