Spring中Bean的單例和多例簡單總結

2021-03-02 Java編程技術樂園

做一個積極的人
編碼、改bug、提升自己

我有一個樂園,面向編程,春暖花開!

在Spring中,有兩個類型,一個是單例一個和多例,一個Bean同學,要麼是單例要麼是多例。不管你認不認這兩個類型,它們依然在哪裡,不吵不鬧。想要和Bean同學成為哥們,那這兩個類型務必要知道。

prototype(多例)和singleton(單例)

在Spring中,bean的Scope常被定義的兩種模式:prototype(多例)和singleton(單例)

singleton(單例):只有一個共享的實例存在,所有對這個bean的請求都會返回這個唯一的實例。

此取值時表明容器中創建時只存在一個實例,所有引用此bean都是單一實例。如同每個國家都有一個總統,國家的所有人共用此總統,而這個國家就是一個spring容器,總統就是spring創建的類的bean,國家中的人就是其它調用者,總統是一個表明其在spring中的scope為singleton,也就是單例模型。

此外,singleton類型的bean定義從容器啟動到第一次被請求而實例化開始,只要容器不銷毀或退出,該類型的bean的單一實例就會一直存活,典型單例模式,如同servlet在web容器中的生命周期。

prototype(多例):對這個bean的每次請求都會創建一個新的bean實例,類似於new。

spring容器在進行輸出prototype的bean對象時,會每次都重新生成一個新的對象給請求方,雖然這種類型的對象的實例化以及屬性設置等工作都是由容器負責的,但是只要準備完畢,並且對象實例返回給請求方之後,容器就不在擁有當前對象的引用,請求方需要自己負責當前對象後繼生命周期的管理工作,包括該對象的銷毀。也就是說,容器每次返回請求方該對象的一個新的實例之後,就由這個對象「自生自滅」。

如同分蘋果,將蘋果的bean的scope屬性聲明為prototype,在每個人領取蘋果的時候,我們都是發一個新的蘋果給他,發完之後,別人愛怎麼吃就怎麼吃,愛什麼時候吃什麼時候吃,但是注意吃完要把蘋果核扔到垃圾箱!對於那些不能共享使用的對象類型,應該將其定義的scope設為prototype。

再次強調:Spring bean 默認是單例模式。

在Spring中 使用註解 @Scope進行標識一個Bean範圍。其中@Scope的源碼如下:

public @interface Scope {
/** * scopeName的別名 */ @AliasFor("scopeName") String value() default "";
/** * 默認 SCOPE_SINGLETON * @since 4.2 * 四種類型可以選擇: * ConfigurableBeanFactory#SCOPE_PROTOTYPE :prototype * ConfigurableBeanFactory#SCOPE_SINGLETON :singleton * org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST :request * org.springframework.web.context.WebApplicationContext#SCOPE_SESSION : */ @AliasFor("value") String scopeName() default "";
/** *指定組件是否應配置為作用域代理,如果是,則該代理應基於接口還是基於子類。 *默認為ScopedProxyMode。預設值,它通常指示,除非在組件掃描指令級別配置了不同的預設值,否則不應該創 *建任何作用域代理。 *類似於Spring XML中的支持 <aop:scoped-proxy/> */ ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
}

其中還有 request 和 session,感興趣的朋友可以自行進行了解。

為什麼用單例或者多例?何時用?

之所以用單例,是因為沒必要每個請求都新建一個對象,這樣子既浪費CPU又浪費內存;

之所以用多例,是為了防止並發問題;即一個請求改變了對象的狀態,此時對象又處理另一個請求,而之前請求對對象狀態的改變導致了對象對另一個請求做了錯誤的處理;

當對象含有可改變的狀態時(更精確的說就是在實際應用中該狀態會改變),則多例,否則單例。

如何在單例bean中注入一個多例bean

使用xml放設置Scope

使用註解方式設置Scope

往期精彩回顧

一文學會Java死鎖和CPU 100% 問題的排查技巧

【面試】MySQL 中NULL和空值的區別?

Mybatis 批量插入引發的血案

Java內存管理-Stackoverflow問答-Java是傳值還是傳引用?(十一)

你有遇到過MySQL因大小寫敏感導致的問題嗎

MySQL 的COUNT(x)性能怎麼樣?

共勉:作為一名程式設計師你應該怎麼提一個高質量的問題?

歡迎長按下圖關注公眾號


後臺回復【資源】,獲取珍藏乾貨!

99.9%的夥伴都很喜歡

  朕已閱 

相關焦點

  • Spring的Controller是單例還是多例?怎麼保證並發的安全
    正因為單例所以不是線程安全的。我們下面來簡單的驗證下:package com.riemann.springbootdemo.controller;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Controller
  • 再談Spring中Bean的生命周期
    一、Bean 的完整生命周期在傳統的Java應用中,bean的生命周期很簡單,使用Java關鍵字 new 進行Bean 的實例化,然後該Bean 就能夠使用了。一旦bean不再被使用,則由Java自動進行垃圾回收。
  • spring學習總結(一)_Ioc基礎(上)
    但是這些功能的底層都依賴於它的兩個核心特性,控制反轉(IOC)和面向切面(AOP)、本篇文章主要介紹IOC。輸出結果對象引用TyreCar測試輸出結果對象作用域在大多數情況下,單例bean是很理想的方案。
  • 面試官:你了解spring嗎?spring的兩大核心是什麼?
    IOC(DI) - 控制反轉(依賴注入)所謂的IOC稱之為控制反轉,簡單來說就是將對象的創建的權利及對象的生命周期的管理過程交由Spring框架來處理,從此在開發過程中不再需要關注對象的創建和生命周期的管理,而是在需要時由Spring框架提供,這個由spring框架管理對象創建和生命周期的機制稱之為控制反轉。
  • 詳解設計模式在 Spring 中的應用
    今天,螃蟹就設計模式的內在價值做一番探討,並以spring為例進行講解,只有領略了其設計的思想理念,才能在工作學習中運用到「無形」。Spring作為業界的經典框架,無論是在架構設計方面,還是在代碼編寫方面,都堪稱行內典範。好了,話不多說,開始今天的內容。
  • 深究Spring中Bean的生命周期
    一、Bean 的完整生命周期在傳統的Java應用中,bean的生命周期很簡單,使用Java關鍵字 new 進行Bean 的實例化,然後該Bean 就能夠使用了。一旦bean不再被使用,則由Java自動進行垃圾回收。
  • Spring是如何解決循環依賴的
    前言在面試的時候這兩年有一個非常高頻的關於spring的問題,那就是spring是如何解決循環依賴的。這個問題聽著就是輕描淡寫的一句話,其實考察的內容還是非常多的,主要還是考察的應聘者有沒有研究過spring的源碼。
  • 是時候了解一下Spring中常用的設計模式了
    2.單例模式單例模式是一種確保每個應用程式僅存在一個對象實例的機制。在管理共享資源或提供跨領域服務(例如日誌記錄)時,此模式很有用。2.1 單例beans通常,單例對於應用程式是全局唯一的,但是在Spring中,此約束更寬泛。Spring定義的單例是在spring IOC容器中唯一。實際上,這意味著Spring只會為每個應用程式上下文的每種類型創建一個bean。
  • Spring 源碼分析 : 非懶加載的單例 Bean 初始化過程 ( 下 ) ( 1 )
    (點擊上方公眾號,可快速關注)來源:五月的倉頡,www.cnblogs.com/xrq730/p/6363055.html如有好文章投稿,請點擊 → 這裡了解詳情doCreateBean方法上文《 Spring源碼分析:非懶加載的單例
  • 你知道Spring是怎麼將AOP應用到Bean的生命周期中的嗎?
    本文我們要分析的代碼還是位於org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean這個方法中,在《我們來談一談Spring中的屬性注入 》這篇文章中,我們已經分析過了populateBean這個方法,所以本文我們接著來看看
  • Java經典面試題Spring是什麼 Spring框架入門詳解
    新建一個pojo類User2並在User中作為變量引入,xml中新增一個bean user2,將User2對象交給spring創建,在User的Bean配置user2的引用,property的name還是變量名,這裡的value要換成ref,ref為要引用的對象的bean的name
  • 細說框架每日一解Spring @Bean Annotaion
    通常情況下,@Bean可以與@Configuration和@Component註解一起使用(@Configuration和@Component是方法級別的註解)。在默認情況下@Bean註解所產生的Bean是單例模式的,此外,@Bean還可以與@Scope,@Lazy,@DependOn和@Primary註解一起使用。
  • 如何記憶 Spring Bean 的生命周期
    而且這麼多步驟,太多了,該怎麼記啊!」。其實要記憶該過程,還是需要我們先去理解,本文將從以下兩方面去幫助理解 Bean 的生命周期:生命周期的概要流程:對 Bean 的生命周期進行概括,並且結合代碼來理解;擴展點的作用:詳細介紹 Bean 生命周期中所涉及到的擴展點的作用。2.
  • Spring 中那些讓你愛不釋手的代碼技巧
    前言最近越來越多的讀者認可我的文章,還是件挺讓人高興的事情。有些讀者私信我說希望後面多分享spring方面的文章,這樣能夠在實際工作中派上用場。正好我對spring源碼有過一定的研究,並結合我這幾年實際的工作經驗,把spring中我認為不錯的知識點總結一下,希望對您有所幫助。
  • spring解決循環依賴為什麼要用三級緩存?
    由於AService和BService都沒有提前實例化,在實例化過程中又相互依賴對方的實例作為參數,這樣構成了一個死循環,所以最終都無法再實例化了。spring要如何解決循環依賴?只需要將上面的例子稍微調整一下,不用構造函數注入,直接使用Autowired注入。
  • SpringFramework學習筆記
    簡單地說, IoC 是反轉控制, 類似於好萊塢原則, 主要有依賴查找和依賴注入實現依賴查找和依賴注入的區別?依賴查找是主動或手動的依賴查找方式, 通常需要依賴容器或標準 API 實現; 而依賴注入則是手動綁定或自動依賴綁定的方式, 無需依賴特定的容器和 API.Spring 作為 IoC 容器有什麼優勢?
  • Spring中bean的scope
    、session和global session,不過這三種類型只能在Web應用中使用。下圖是Spring參考文檔中給出的singleton的bean的實例化和注入語義示意圖,或許更能形象得說明問題。singleton scope需要注意的是,不要將Spring中的singleton bean的概念和GoF中提出的Singleton模式混淆,二者的語義並不相同:Spring中的singleton scope
  • Spring常用註解——JAVA成長之路
    作用:調用無參構造創建一個bean對象,並把對象存入spring的IOC容器,交由spring容器進行管理。相當於在xml中配置一個bean。屬性:value:指定bean的id。1.5 作用:用於把當前方法的返回值作為bean對象存入spring的ioc容器中屬性:name:用於指定bean的id。
  • 【119期】Spring是怎麼解決循環依賴的?
    // 初始化所有的非懶加載的單例bean,核心方法   finishBeanFactoryInitialization(beanFactory);   // Last step: publish corresponding event.
  • 面試必問:Spring 循環依賴的三種方式
    如果大家理解開頭那句話的話,這個報錯應該不驚訝,Spring容器先創建單例StudentA,StudentA依賴StudentB,然後將A放在「當前創建Bean池」中,此時創建StudentB,StudentB依賴StudentC ,然後將B放在「當前創建Bean池」中,此時創建StudentC,StudentC又依賴StudentA