為什么要把對象交給Spring管理

????我們程序中對象的運行有兩個目標(biāo)?第一要解決業(yè)務(wù)問題,第二要高效低耗的優(yōu)化業(yè)務(wù)的執(zhí)行。那么如何才能達(dá)成這樣的目標(biāo)?第一充分分析業(yè)務(wù),確定其對象,第二要思考解決業(yè)務(wù)的這些對象的運行性能。

????在Spring框架中不會幫我們解決業(yè)務(wù)問題,但可以從對象運行時的性能方面給予一定的設(shè)計槽畔。例如Spring為我們的對象賦予了很多個更加科學(xué)的特性,例如延遲加載膛薛,Bean的作用域迷捧,生命周期方法以及運行時的自動依賴注入(降低耦合,提高程序的可維護性)幸乒。

1. 延遲加載(懶加載 @Lazy)

? ? 當(dāng)一個對象占用內(nèi)存較大時懦底,或者創(chuàng)建之后暫時用不到的時候,可以配置延遲加載罕扎。延遲加載并不是延遲對類進行加載聚唐,而是在啟動時,暫時不創(chuàng)建類的實例腔召。如果想看一下內(nèi)存中的類是否被加載了杆查,可以通過JVM參數(shù)進行檢測,參數(shù)為-XX:+TraceClassLoading臀蛛。

2. 對象作用域分析(@Scope)

? ? 在實際的項目中內(nèi)存中的對象有一些可能要反復(fù)應(yīng)用很多次亲桦,有一些可能用完以后再也不用了或者說應(yīng)用次數(shù)很少了。對于經(jīng)常要重復(fù)使用的對象我們可以考慮存儲到池中(例如交給spring框架進行管理)浊仆,應(yīng)用次數(shù)很少的對象那就沒必要放到池中了客峭,用完以后讓它自己銷毀就可以了。在Spring項目工程中為了對這樣的對象進行設(shè)計和管理抡柿,提供了作用域特性的支持桃笙。

? ? 使用@Scope注解對類進行描述,用于指定類的實例作用域沙绝。不寫@Scope默認(rèn)就是單例(singleton)作用域搏明,這個作用域會配合延遲加載(@Lazy)特性使用,表示此類的實例在需要時可以創(chuàng)建一份并且將其存儲到spring的容器中(Bean池),需要的時候從池中取闪檬,以實現(xiàn)對象的可重用星著。假如一些對象應(yīng)用次數(shù)非常少,可以考慮不放入池中粗悯,進而使用@Scope("prototype")作用域?qū)︻愡M行描述,讓此類的對象何時需要何時創(chuàng)建虚循,用完以后,當(dāng)此對象不可達(dá)了样傍,則可以直接被GC系統(tǒng)銷毀横缔。

3. 對象生命周期方法

????程序中的每個對象都有生命周期丙曙,對象創(chuàng)建必盖,初始化化撕,應(yīng)用福侈,銷毀的這個過程稱之為對象的生命周期耸黑。在對象創(chuàng)建以后要初始化颜屠,應(yīng)用完成以后要銷毀時執(zhí)行的一些方法搀罢,我們可以稱之為生命周期方法艘绍。但不見得每個對象都會定義生命周期方法。在實際項目中往往一些池對象通常會定義這樣的一些生命周期方法(例如連接池)初狰。那這樣的方法在spring工程中如何進行標(biāo)識呢莫杈?通常要借助@PostConstruct和@PreDestroy注解對特定方法進行描述,例如:

package com.zhf.common.pool;

@Scope("singleton")

@Lazy

@Component

public class ObjectPool{//假設(shè)此對象為一個對象池

? ? public ObjectPool(){

? ? ? Systemd.out.println("ObjectPool()...")

? ? }

? ? @PostConstruct

? ? public void init(){?????//生命周期初始化方法

? ? ? System.out.println("init()");

? ? }

? ? @PreDestroy

? ? public void destory(){? ? // 生命周期銷毀方法

? ? System.out.println("destory()");

? ? }

}

其中:

1)@PostConstruct 注解描述的方法為生命周期初始化方法,在對象構(gòu)建以后執(zhí)行;

2)@PreDestroy 注解描述的方法為生命周期銷毀方法,此方法所在的對象,假如存儲到了spring容器,那這個對象在從spring容器移除之前會先執(zhí)行這個生命周期銷毀方法(prototype作用域?qū)ο蟛粓?zhí)行此方法);

4. SpringBoot 項目中的依賴注入過程分析

在這個案例中單元測試類CacheTests中定義一個Cache接口類型的屬性奢入,然后由Spring框架完成對cache類型屬性值的注入筝闹。

代碼編寫及測試分析

第一步:定義Cache接口,代碼如下:

package com.zhf.common.cache;

public interface Cache {

}

第二步:定義Cache接口實現(xiàn)類SoftCache腥光,代碼如下:

package com.zhf.common.cache;

@Component

public class SoftCache implements Cache{

}

第三步:定義Cache接口實現(xiàn)類WeakCache关顷,代碼如下:

package com.zhf.common.cache;

@Component

public class WeakCache implements Cache{

}

第四步:定義CacheTests單元測試類,代碼如下:

package com.zhf.common.cache;

import org.junit.jupiter.api.Test;

?

@SpringBootTest ? ?

public class CacheTests {

?? @Autowired

?? @Qualifier("softCache")

?? private Cache cache;


?? @Test

?? public void testCache() {

? ? ?? System.out.println(cache);

?? }

}

????其中柴我,@Autowired由spring框架定義解寝,用于描述類中屬性或相關(guān)方法(例如構(gòu)造方法)。Spring框架在項目運行時假如發(fā)現(xiàn)由他管理的Bean對象中有使用@Autowired注解描述的屬性或方法艘儒,可以按照指定規(guī)則為屬性賦值(DI)聋伦。其基本規(guī)則是:首先要檢測容器中是否有與屬性或方法參數(shù)類型相匹配的對象,假如有并且只有一個則直接注入界睁。其次觉增,假如檢測到有多個,還會按照@Autowired描述的屬性或方法參數(shù)名查找是否有名字匹配的對象翻斟,有則直接注入逾礁,沒有則拋出異常。最后访惜,假如我們有明確要求嘹履,必須要注入類型為指定類型,名字為指定名字的對象還可以使用@Qualifier注解對其屬性或參數(shù)進行描述(此注解必須配合@Autowired注解使用)债热。

第五步:運行CacheTests檢測輸出結(jié)果砾嫉,基于結(jié)果理解其注入規(guī)則。

5.?依賴注入方式(DI)

public class CacheService {

? ?@Autowired

? ?@Qualifier("softCache")

? ? private Cache cache;

//1. 通過構(gòu)造函數(shù)實現(xiàn)值的注入

//? ? @Autowired//可以描述構(gòu)造方法,只有這一個構(gòu)造函數(shù)時窒篱,可以省略

//? ? public CacheService(@Qualifier("weakCache") Cache cache){ //@Qualifier可以描述參數(shù)

//? ? ? ? this.cache=cache;

//? ? }

? ? //當(dāng)類中有多個構(gòu)造函數(shù)時焕刮,但是構(gòu)造函數(shù)又沒有使用@Autowired注解修飾,優(yōu)先使用無參構(gòu)造

//? ? public CacheService(){}

? ? //2. 通過set方法為屬性賦值

//? ? @Autowired

//? ? public void setCache(@Qualifier("weakCache") Cache cache){

//? ? ? ? System.out.println("===setCache()===");

//? ? ? ? this.cache=cache;

//? ? }

? ? public Cache getCache() {

return cache;

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末墙杯,一起剝皮案震驚了整個濱河市配并,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌高镐,老刑警劉巖溉旋,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異避消,居然都是意外死亡低滩,警方通過查閱死者的電腦和手機召夹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門岩喷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恕沫,“玉大人,你說我怎么就攤上這事纱意∩羲荩” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵偷霉,是天一觀的道長迄委。 經(jīng)常有香客問我,道長类少,這世上最難降的妖魔是什么叙身? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮硫狞,結(jié)果婚禮上信轿,老公的妹妹穿的比我還像新娘。我一直安慰自己残吩,他們只是感情好财忽,可當(dāng)我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著泣侮,像睡著了一般即彪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上活尊,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天隶校,我揣著相機與錄音,去河邊找鬼蛹锰。 笑死深胳,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宁仔。 我是一名探鬼主播稠屠,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼翎苫!你這毒婦竟也來了权埠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤煎谍,失蹤者是張志新(化名)和其女友劉穎攘蔽,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體呐粘,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡满俗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年转捕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唆垃。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡五芝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辕万,到底是詐尸還是另有隱情枢步,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布渐尿,位于F島的核電站醉途,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏砖茸。R本人自食惡果不足惜隘擎,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望凉夯。 院中可真熱鬧货葬,春花似錦、人聲如沸恍涂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽再沧。三九已至尼夺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間炒瘸,已是汗流浹背淤堵。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留顷扩,地道東北人拐邪。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像隘截,于是被迫代替她去往敵國和親扎阶。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容