自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

頭條一面:Spring IOC容器中只存放單例Bean嗎?

開發(fā) 架構
當我看到這些面試題時,快速在腦海中構建起了整個知識體系,從基礎到框架、從分布式到微服務,從數據結構到算法,從虛擬化到云原生,從大數據到云計算,從實戰(zhàn)項目到性能調優(yōu)。

[[396725]]

最近,很多小伙伴出去面試,感覺自己面的不是很理想,回來后,不少小伙伴把面試題做了記錄發(fā)給我,讓我給大家解析下,然后發(fā)出來。當我看到這些面試題時,快速在腦海中構建起了整個知識體系,從基礎到框架、從分布式到微服務,從數據結構到算法,從虛擬化到云原生,從大數據到云計算,從實戰(zhàn)項目到性能調優(yōu)。其實,這些面試本質上不難,很多都是對于基礎知識的考察。

今天開始,我們就來一一突破這些大廠的面試題,好了,開始今天的正文。

問題:

正如題目所說:Spring IOC容器中只存放單例Bean嗎?

先給出結論吧

這里,想來想去,我還是直接了當的說吧:是的,Spring IOC容器中只存放單例Bean。接下來,且聽我細細道來為哈只存放單例Bean。

問題分析

既然,我們已經知道Spring IOC容器中只存放單例Bean,但是在面試的時候不能只說這一句話呀,否則,面試官就會把你直接Pass掉。為啥?如果你只說這一句話,面試官可能就會認為你是懵的,而且懵對的概率為50%,如果你懵錯了,面試官認為你不會,如果你懵對了,面試官有可能也會認為你不會。所以,除了答對結論之外,還要清晰的說出Spring IOC容器中為啥只存放單例Bean。

好了,我們正式開始分析這個問題。

IOC容器初始化的時候,會將所有的bean初始化在singletonObjects這個ConcurrentHashMap中, bean是單例的。

在獲取bean的時候,首先會從singletonObjects去取,通過debug,發(fā)現如果scope是單例,則可以獲取到bean,如果scope是多例,則獲取不到bean,需要從一個叫mergedBeanDefinitions的ConcurrentHashMap中去獲取bean的定義,然后再根據bean的scope去決定如何創(chuàng)建bean,如果scope=prototype,則每次都會創(chuàng)建一個新的實例。

這里,我們可以大概得出這樣的結論:

IOC在初始化時,只會將scope= singleton(單例)的對象進行實例化,而不會去實例化scope=prototype的對象(多例)。

接下來,我們就來debug一下Spring的源碼。

首先,我們創(chuàng)建一個用于測試作用域為多例,獲取不同實例的Person類,如下所示。

  1. public class Person { 
  2.  
  3.     @Value("張三"
  4.     private String name
  5.  
  6.     @Value("#{20-2}"
  7.     private Integer age; 
  8.  
  9.     @Value("${person.nickName}"
  10.     private String nickName; 
  11.  
  12.     public Person() { 
  13.     } 
  14.  
  15.     public Person(String nameInteger age) { 
  16.         this.name = name
  17.         this.age = age; 
  18.     } 
  19.     //省略get/set 

接下來,創(chuàng)建一個MainConfig類,如下所示。

  1. @Configuration 
  2. public class MainConfig { 
  3.     @Bean("person"
  4.     @Scope("prototype"
  5.     public Person person(){ 
  6.         System.out.println("給容器中添加Person..."); 
  7.         return new Person("張三", 25); 
  8.     } 

可以看到,此時MainConfig測試的是作用域為多例,獲取不同實例的場景。而如果要想測試作用域為單例,獲取相同實例的場景,則只需要將MainConfig類中的person()方法上的 @Scope("prototype")注解去掉即可,如下所示。

  1. @Configuration 
  2. public class MainConfig { 
  3.     @Bean("person"
  4.     public Person person(){ 
  5.         System.out.println("給容器中添加Person..."); 
  6.         return new Person("張三", 25); 
  7.     } 

接下來,再編寫一個main方法用于啟動測試程序。

  1. public static void  main(String[] args){ 
  2.     ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class); 
  3.     Person person = applicationContext.getBean(Person.class); 
  4.     Person person2 = applicationContext.getBean(Person.class); 
  5.     if(person.equals(person2)){ 
  6.         System.out.println("同一個實例"); 
  7.     }else
  8.         System.out.println("不同的實例"); 
  9.     } 

啟動程序,開始debug測試單例情況。

調試單例作用域

經過debug調試,在單例情況下,首次從singletonObjects 這個Map中獲取的bean為空,以后每次獲取時,從singletonObjects這個Map中獲取的bean就不為空了,會直接返回從這個Map中獲取的值。

第一次從singletonObjects 中獲取值的情況如下所示。

第二次再從singletonObjects這個Map中獲取的bean就不為空了。

此時,命令行會打印同一個實例。

說明單例作用域下,每次共用一個bean實例,并且這個bean實例是被保存到容器中的。

調試多例作用域

如果是多例情況,則外界無論獲取多少個bean,從singletonObjects 這個Map中都獲取不到對應的bean實例,每次都需要新建一個bean返回。

通過調試源碼,可以發(fā)現,當bean是多例時,每次都會從一個叫做 mergedBeanDefinitions 的HashMap中獲取一個RootBeanDefinition對象,里面包含了bean的一些基礎信息,如下所示。

接下來,再根據bean的scope屬性來做處理,如果作用域是單例,則直接從容器中獲取,如果作用域是多例,則每次會創(chuàng)建一個實例。

此時,命令行會打印出不同的實例。

說明多例作用域下,每次都會創(chuàng)建一個bean實例并返回。

綜上所述:Spring IOC容器中只存放單例Bean。

本文轉載自微信公眾號「冰河技術」,可以通過以下二維碼關注。轉載本文請聯系冰河技術公眾號。

 

責任編輯:武曉燕 來源: 冰河技術
相關推薦

2025-03-13 10:01:47

2022-09-16 08:42:23

JavaAPI變量

2024-12-31 11:40:05

2025-03-20 08:00:00

@LazySpring開發(fā)

2022-08-13 12:07:14

URLHTTP加密

2022-12-27 08:12:27

IOC容器Bean

2022-05-11 22:15:51

云計算云平臺

2009-06-22 10:20:01

Spring IoC容

2021-05-06 07:58:57

Spring BeanIOCAOP

2025-04-15 08:00:00

Java開發(fā)服務網格

2024-05-15 16:41:57

進程IO文件

2025-03-18 08:30:00

Spring開發(fā)java

2024-10-15 10:59:18

Spring MVCJava開發(fā)

2025-03-28 08:10:00

Spring自動裝配Java

2025-03-20 09:59:55

Spring@ProfileJava

2022-08-18 17:44:25

HTTPS協議漏洞

2023-10-08 10:14:12

2009-07-30 14:38:36

云計算

2020-09-19 17:46:20

React Hooks開發(fā)函數

2025-03-25 12:00:00

@Value?Spring開發(fā)
點贊
收藏

51CTO技術棧公眾號