聊一聊new對(duì)象與Spring對(duì)bean的初始化的差別
new對(duì)象與Spring對(duì)bean初始化差別
這個(gè)問題是一次我將老系統(tǒng)代碼遷移到基于Spring構(gòu)建的新系統(tǒng)中時(shí)遇到的,老代碼中有很多地方使用了new方法來初始化對(duì)象,當(dāng)時(shí)也沒有特別注意,最后聯(lián)調(diào)的時(shí)候發(fā)現(xiàn)所有new出來的對(duì)象中使用Autowired自動(dòng)依賴注入的屬性全都拋出了NullPointerException。
什么意思呢?
@Component Class A { ? ? ... }?
@Component Class B { ? ? ... }?
@Component Class C { ? ? @Autowired ? ? A a; ? ? @Autowired ? ? B b; }?
當(dāng)我使用C c = new C()時(shí),c中的a和b都是null,也就是無法完成注入。
說實(shí)話,在聯(lián)調(diào)的那一刻我有一瞬間是懵逼的,但現(xiàn)在回想起來,哦,真是太傻了。
簡(jiǎn)單來理解
Spring首先會(huì)通過new方法創(chuàng)建一個(gè)對(duì)象,然后去完成屬性的填充,而這種填充在我們外界看來是“自動(dòng)”的;而我們直接通過new方法創(chuàng)建對(duì)象時(shí),是沒有誰去完成屬性的填充的,因而內(nèi)部屬性值全為null。
Spring類的注入和new簡(jiǎn)單理解
springboot
main.run
方法進(jìn)入refreshContext
refresh
finishBeanFactoryInitialization
(完成beanFactory的初始化)preInstantiateSingletons
(初始化單例)getBean
(獲取Bean)doGetBean
createBean
doCreateBean
(此方法內(nèi)部會(huì)createBean,創(chuàng)建bean即構(gòu)造方法執(zhí)行)populateBean
(進(jìn)行autowired自動(dòng)注入)applyPropertyValues
(進(jìn)行屬性注入)
PS:new對(duì)象,不能導(dǎo)致對(duì)象依賴的注入屬性自動(dòng)賦值,只有對(duì)對(duì)象進(jìn)行注入,對(duì)象依賴的注入屬性才能賦值;
且注入的屬性不能在構(gòu)造函數(shù)中操作,因?yàn)閎ean沒有創(chuàng)建完成,屬性也沒有注入,此時(shí)是為null的
問題:spring默認(rèn)是單例模式,還有必要?jiǎng)?chuàng)建單例類嗎?
自己理解:有必要,如果不使用autowired進(jìn)行自動(dòng)注入,使用new操作還是可以生成多個(gè)對(duì)象,
spring的單例是針對(duì)自動(dòng)注入
例子:
? ? ?@Component ? ? ?public class CxfClient{undefined ? ? ? ? ? @Value("${address }") ? ? ? ? ? private String address; ? ? ? ? ? private CxfClient(){undefined ? ? ? ? ? ? ? ?System.out.println(address ); //此時(shí)為null.bean沒有加載完成,屬性也沒有加載 ? ? ? ? ? } ? ? ? ? ? public void createClient(){undefined ? ? ? ? ? ? ? ?System.out.println(address );//此時(shí)為配置文件中的值 ? ? ? ? ? } ? ? ? ? ? private static class SingletonHolder {undefined ? ? ? ? ? ? ? private static final CxfClient INSTANCE = new CxfClient(); ? ? ? ? ? } ? ? ? ? ? public static final CxfClient getInstance() {undefined ? ? ? ? ? ? ? ?return SingletonHolder.INSTANCE; ? ? ? ? ? } ? ? ?}
? ? ?public class Test{undefined ? ? ? ? ? @Autowired ? ? ? ? ? private CxfClient cxfClient; ? ? ? ? ? public void testClient(){undefined ? ? ? ? ? ? ? ?CxfClient.getInstance().createClient();//打印為null.無法注入 ? ? ? ? ? ? ? ?cxfClient.createClient();//打印為配置文件中的值 ? ? ? ? ? } ? ? ?}
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Boot中使用Spring-data-jpa的配置方法詳解
今天小編就為大家分享一篇關(guān)于Spring Boot中使用Spring-data-jpa的配置方法詳解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-03-03JAVA基礎(chǔ)之注解與反射的使用方法和場(chǎng)景
這篇文章主要給大家介紹了關(guān)于JAVA基礎(chǔ)之注解與反射的使用方法和場(chǎng)景的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03java中Redisson的看門狗機(jī)制的實(shí)現(xiàn)
本文主要介紹了java中Redisson的看門狗機(jī)制的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01通過代碼實(shí)例了解SpringBoot啟動(dòng)原理
這篇文章主要介紹了通過代碼實(shí)例了解SpringBoot啟動(dòng)原理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12java -D參數(shù)設(shè)置系統(tǒng)屬性無效問題及解決
這篇文章主要介紹了java -D參數(shù)設(shè)置系統(tǒng)屬性無效問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12詳解maven的setting配置文件中mirror和repository的區(qū)別
這篇文章主要介紹了詳解maven的setting配置文件中mirror和repository的區(qū)別,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12springboot整合Nginx實(shí)現(xiàn)負(fù)載均衡反向代理的方法詳解
這篇文章主要給大家介紹了關(guān)于springboot整合Nginx實(shí)現(xiàn)負(fù)載均衡反向代理的相關(guān)資料,文中通過圖文以及實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-01-01