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

公司主營(yíng)業(yè)務(wù):網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、移動(dòng)網(wǎng)站開(kāi)發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。成都創(chuàng)新互聯(lián)公司是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開(kāi)放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。成都創(chuàng)新互聯(lián)公司推出鐵東免費(fèi)做網(wǎng)站回饋大家。
今天開(kāi)始,我們就來(lái)一一突破這些大廠的面試題,好了,開(kāi)始今天的正文。
問(wèn)題:
正如題目所說(shuō):Spring IOC容器中只存放單例Bean嗎?
先給出結(jié)論吧
這里,想來(lái)想去,我還是直接了當(dāng)?shù)恼f(shuō)吧:是的,Spring IOC容器中只存放單例Bean。接下來(lái),且聽(tīng)我細(xì)細(xì)道來(lái)為哈只存放單例Bean。
問(wèn)題分析
既然,我們已經(jīng)知道Spring IOC容器中只存放單例Bean,但是在面試的時(shí)候不能只說(shuō)這一句話呀,否則,面試官就會(huì)把你直接Pass掉。為啥?如果你只說(shuō)這一句話,面試官可能就會(huì)認(rèn)為你是懵的,而且懵對(duì)的概率為50%,如果你懵錯(cuò)了,面試官認(rèn)為你不會(huì),如果你懵對(duì)了,面試官有可能也會(huì)認(rèn)為你不會(huì)。所以,除了答對(duì)結(jié)論之外,還要清晰的說(shuō)出Spring IOC容器中為啥只存放單例Bean。
好了,我們正式開(kāi)始分析這個(gè)問(wèn)題。
IOC容器初始化的時(shí)候,會(huì)將所有的bean初始化在singletonObjects這個(gè)ConcurrentHashMap中, bean是單例的。
在獲取bean的時(shí)候,首先會(huì)從singletonObjects去取,通過(guò)debug,發(fā)現(xiàn)如果scope是單例,則可以獲取到bean,如果scope是多例,則獲取不到bean,需要從一個(gè)叫mergedBeanDefinitions的ConcurrentHashMap中去獲取bean的定義,然后再根據(jù)bean的scope去決定如何創(chuàng)建bean,如果scope=prototype,則每次都會(huì)創(chuàng)建一個(gè)新的實(shí)例。
這里,我們可以大概得出這樣的結(jié)論:
IOC在初始化時(shí),只會(huì)將scope= singleton(單例)的對(duì)象進(jìn)行實(shí)例化,而不會(huì)去實(shí)例化scope=prototype的對(duì)象(多例)。
接下來(lái),我們就來(lái)debug一下Spring的源碼。
首先,我們創(chuàng)建一個(gè)用于測(cè)試作用域?yàn)槎嗬@取不同實(shí)例的Person類,如下所示。
- public class Person {
- @Value("張三")
- private String name;
- @Value("#{20-2}")
- private Integer age;
- @Value("${person.nickName}")
- private String nickName;
- public Person() {
- }
- public Person(String name, Integer age) {
- this.name = name;
- this.age = age;
- }
- //省略get/set
- }
接下來(lái),創(chuàng)建一個(gè)MainConfig類,如下所示。
- @Configuration
- public class MainConfig {
- @Bean("person")
- @Scope("prototype")
- public Person person(){
- System.out.println("給容器中添加Person...");
- return new Person("張三", 25);
- }
- }
可以看到,此時(shí)MainConfig測(cè)試的是作用域?yàn)槎嗬?,獲取不同實(shí)例的場(chǎng)景。而如果要想測(cè)試作用域?yàn)閱卫?,獲取相同實(shí)例的場(chǎng)景,則只需要將MainConfig類中的person()方法上的 @Scope("prototype")注解去掉即可,如下所示。
- @Configuration
- public class MainConfig {
- @Bean("person")
- public Person person(){
- System.out.println("給容器中添加Person...");
- return new Person("張三", 25);
- }
- }
接下來(lái),再編寫(xiě)一個(gè)main方法用于啟動(dòng)測(cè)試程序。
- public static void main(String[] args){
- ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
- Person person = applicationContext.getBean(Person.class);
- Person person2 = applicationContext.getBean(Person.class);
- if(person.equals(person2)){
- System.out.println("同一個(gè)實(shí)例");
- }else{
- System.out.println("不同的實(shí)例");
- }
- }
啟動(dòng)程序,開(kāi)始debug測(cè)試單例情況。
調(diào)試單例作用域
經(jīng)過(guò)debug調(diào)試,在單例情況下,首次從singletonObjects 這個(gè)Map中獲取的bean為空,以后每次獲取時(shí),從singletonObjects這個(gè)Map中獲取的bean就不為空了,會(huì)直接返回從這個(gè)Map中獲取的值。
第一次從singletonObjects 中獲取值的情況如下所示。
第二次再?gòu)膕ingletonObjects這個(gè)Map中獲取的bean就不為空了。
此時(shí),命令行會(huì)打印同一個(gè)實(shí)例。
說(shuō)明單例作用域下,每次共用一個(gè)bean實(shí)例,并且這個(gè)bean實(shí)例是被保存到容器中的。
調(diào)試多例作用域
如果是多例情況,則外界無(wú)論獲取多少個(gè)bean,從singletonObjects 這個(gè)Map中都獲取不到對(duì)應(yīng)的bean實(shí)例,每次都需要新建一個(gè)bean返回。
通過(guò)調(diào)試源碼,可以發(fā)現(xiàn),當(dāng)bean是多例時(shí),每次都會(huì)從一個(gè)叫做 mergedBeanDefinitions 的HashMap中獲取一個(gè)RootBeanDefinition對(duì)象,里面包含了bean的一些基礎(chǔ)信息,如下所示。
接下來(lái),再根據(jù)bean的scope屬性來(lái)做處理,如果作用域是單例,則直接從容器中獲取,如果作用域是多例,則每次會(huì)創(chuàng)建一個(gè)實(shí)例。
此時(shí),命令行會(huì)打印出不同的實(shí)例。
說(shuō)明多例作用域下,每次都會(huì)創(chuàng)建一個(gè)bean實(shí)例并返回。
綜上所述:Spring IOC容器中只存放單例Bean。
本文轉(zhuǎn)載自微信公眾號(hào)「冰河技術(shù)」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系冰河技術(shù)公眾號(hào)。
網(wǎng)頁(yè)標(biāo)題:頭條一面:Spring IOC容器中只存放單例Bean嗎?
網(wǎng)站URL:http://fisionsoft.com.cn/article/dhhodgc.html


咨詢
建站咨詢
