網站首頁 編程語言 正文
1. DefaultListableBeanFactory
在Spring中,所有由Spring容器管理的Bean默認都是單例的。Spring框架中最經典的單例模式實現是在BeanFactory中。BeanFactory是Spring IoC容器的核心接口,其實現類DefaultListableBeanFactory在加載Bean定義時,會將單例的Bean實例化并緩存在ConcurrentHashMap中,以保證該Bean的唯一性。
DefaultListableBeanFactory定義了三個Map對象:singletonObjects、singletonFactories和earlySingletonObjects,它們都被設計為線程安全的ConcurrentHashMap。
- singletonObjects用于存儲已經實例化的單例Bean對象。
- singletonFactories用于存儲BeanFactory對象。
- earlySingletonObjects用于存儲未完全初始化的Bean對象。
當一個單例Bean實例被獲取時,DefaultListableBeanFactory會首先檢查singletonObjects是否存在該Bean實例,如果存在則直接返回,否則就從earlySingletonObjects或singletonFactories中獲取或創建該Bean實例。
2. SingletonBeanRegistry
單例相關的操作其實是被定義在SingletonBeanRegistry接口中。SingletonBeanRegistry是Spring框架中的一個接口,定義了向Spring IoC容器中添加和獲取單例Bean的方法。
public interface SingletonBeanRegistry {
// 將指定名稱的Bean實例注冊為單例Bean。如果該名稱已經存在于單例Bean注冊表中,則會拋出IllegalStateException異常。
void registerSingleton(String var1, Object var2);
// 獲取指定名稱的單例Bean實例。如果指定名稱的Bean實例不存在,則返回null。
@Nullable
Object getSingleton(String var1);
// 檢查指定名稱的單例Bean實例是否已經存在于單例Bean注冊表中。
boolean containsSingleton(String var1);
// 獲取所有已注冊的單例Bean名稱。
String[] getSingletonNames();
// 獲取當前容器中已經注冊的單例Bean的數量。
int getSingletonCount();
// 獲取一個用于同步單例Bean注冊表的對象。
Object getSingletonMutex();
}
3. Spring單例Bean與單例模式的區別
Spring單例Bean與單例模式的區別在于它們關聯的環境不一樣,單例模式是指在一個JVM進程中僅有一個實例,而Spring單例是指一個Spring Bean容器(ApplicationContext)中僅有一個實例。
首先看單例模式,在一個JVM進程中(理論上,一個運行的JAVA程序就必定有自己一個獨立的JVM)僅有一個實例,無論在程序中的何處獲取實例,始終都返回同一個對象。以Java內置的Runtime為例,下面的判斷始終為真:
// 在一個JVM實例中始終只有一個實例
Runtime.getRuntime() == Runtime.getRuntime();
與此相比,Spring的單例Bean是與其容器 ApplicationContext密切相關的,所以在一個JVM進程中,如果有多個Spring容器,即使是單例bean,也一定會創建多個實例,代碼示例如下:
public static void main(String[] args) {
System.out.println(Runtime.getRuntime() == Runtime.getRuntime());
// 第一個Spring Bean容器
ClassPathXmlApplicationContext context_1 = new ClassPathXmlApplicationContext("bean.xml");
Person msb1 = context_1.getBean("person", Person.class);
// 第二個Spring Bean容器
ClassPathXmlApplicationContext context_2 = new ClassPathXmlApplicationContext("bean.xml");
Person msb2 = context_2.getBean("person", Person.class);
// 這里絕對不會相等,因為創建了多個實例
System.out.println(msb1 == msb2);
}
以下是Spring的配置文件:
<!-- 即使聲明了為單例,只要有多個容器,也一定會創建多個實例 -->
<bean id="person" class="com.mashibing.spring01.demo03.Person" scope="singleton">
<constructor-arg name="username">
<value>mashibing</value>
</constructor-arg>
</bean>
如果不指定bean的類型,Spring框架生成的Bean默認就是單例的(在當前容器里)。
Spring的單例Bean與Spring Bean管理容器密切相關,每個容器都會創建自己獨有的實例,所以與GOF設計模式中的單例模式相差極大,但在實際應用中,如果將對象的生命周期完全交給Spring管理(不在其他地方通過new、反射等方式創建),其實也能達到單例模式的效果。
原文鏈接:https://blog.csdn.net/qq_26893655/article/details/140337231
- 上一篇:沒有了
- 下一篇:沒有了
相關推薦
- 2022-05-04 C#設計模式之單例模式_C#教程
- 2022-09-03 Python流程控制if條件選擇與for循環_python
- 2022-04-20 Python設計模式結構型代理模式_python
- 2022-06-08 VM配置Centos7虛擬機
- 2022-09-26 Pytorch模型訓練和模型驗證
- 2022-06-25 Android開發壁紙的驗證設置和確認功能實現demo_Android
- 2022-07-04 C#使用System.Buffer以字節數組Byte[]操作基元類型數據_C#教程
- 2022-10-12 深入淺出Golang中select的實現原理_Golang
- 欄目分類
-
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支