Spring理解

看了Spring in Action(第四版)開頭初嘹,覺得說的很好碴裙。Spring的根本使命是什么,簡化Java開發(fā)陶缺。

為了降低Java開發(fā)的復(fù)雜性钾挟,Spring采取了以下4種關(guān)鍵策略:

  • 基于POJO的輕量級和最小侵入性編程;
  • 通過依賴注入和面向接口實現(xiàn)松耦合饱岸;
  • 基于切面和慣例進行聲明式編程掺出;
  • 通過切面和模板減少樣板式代碼。
激發(fā)POJO的潛能

很多框架的使用都會“強迫”我們的應(yīng)用繼承他們的類或者實現(xiàn)他們的接口苫费,這種侵入式編程會導(dǎo)致應(yīng)用于框架綁死汤锨。Spring不會強迫你實現(xiàn)Spring規(guī)范的接口或繼承Spring規(guī)范的類,相反百框,在基于Spring構(gòu)建的應(yīng)用中闲礼,它的類通常沒有任何痕跡表明你使用了Spring。最壞的場景是铐维,一個類或許會使用Spring注解位仁,但它依舊是POJO。
`package com.habuma.spring

public class HelloWorldBean{
public String sayHello(){
return "Hello World";
}
}`
可以看到方椎,這是一個簡單普通的Java類——POJO。沒有任何地方表明它是一個Spring組件钧嘶。Spring的非侵入編程模型意味著這個類在Spring應(yīng)用和非Spring應(yīng)用中都可以發(fā)揮同樣的作用棠众。


依賴注入

依賴注入是個聽上去個很高端的詞,很多人都不懂是什么意思有决,我覺得Spring in Action就解釋的很清楚闸拿。

我們?yōu)槭裁葱枰蕾囎⑷肽兀?/p>

任何一個有實際意義的應(yīng)用(肯定比Hello World示例更復(fù)雜)都會由兩個或者更多的類組成,這些類相互之間進行協(xié)作來完成特定的業(yè)務(wù)邏輯书幕。按照傳統(tǒng)的做法新荤,每個對象負責(zé)管理與自己相互協(xié)作的對象(即它所依賴的對象)的引用,這將會導(dǎo)致高度耦合和難以測試的代碼台汇。

package sia.knights;

public class DamselRescuingKnight implements Knight {

  private RescueDamselQuest quest;

  public DamselRescuingKnight() {
    this.quest = new RescueDamselQuest();
  }

  public void embarkOnQuest() {
    quest.embark();
  }

}

可以看到苛骨,DamselRescuingKnight在它的構(gòu)造函數(shù)中自行創(chuàng)建了RescueDamselQuest篱瞎。這使得DamselRescuingKnight緊密地和RescueDamselQuest耦合到了一起,因此極大地限制了這個騎士執(zhí)行探險的能力痒芝。如果一個少女需要救援俐筋,這個騎士能夠召之即來。但是如果一條惡龍需要殺掉严衬,或者一個圓桌……額……需要滾起來澄者,那么這個騎士就愛莫能助了。

更糟糕的是请琳,為這個DamselRescuingKnight編寫單元測試將出奇地困難粱挡。在這樣的一個測試中,你必須保證當(dāng)騎士的embarkOnQuest()方法被調(diào)用的時候俄精,探險的embark()方法也要被調(diào)用询筏。但是沒有一個簡單明了的方式能夠?qū)崿F(xiàn)這一點。很遺憾嘀倒,DamselRescuingKnight將無法進行測試屈留。

耦合具有兩面性(two-headed beast)。一方面测蘑,緊密耦合的代碼難以測試灌危、難以復(fù)用、難以理解碳胳,并且典型地表現(xiàn)出“打地鼠”式的bug特性(修復(fù)一個bug勇蝙,將會出現(xiàn)一個或者更多新的bug)。另一方面挨约,一定程度的耦合又是必須的——完全沒有耦合的代碼什么也做不了味混。為了完成有實際意義的功能,不同的類必須以適當(dāng)?shù)姆绞竭M行交互诫惭∥涛總而言之,耦合是必須的夕土,但應(yīng)當(dāng)被小心謹慎地管理馆衔。

通過DI,對象的依賴關(guān)系將由系統(tǒng)中負責(zé)協(xié)調(diào)各對象的第三方組件在創(chuàng)建對象的時候進行設(shè)定怨绣。對象無需自行創(chuàng)建或管理它們的依賴關(guān)系角溃,依賴關(guān)系將被自動注入到需要它們的對象當(dāng)中去。

package sia.knights;
  
public class BraveKnight implements Knight {

  private Quest quest;

  public BraveKnight(Quest quest) {
    this.quest = quest;
  }

  public void embarkOnQuest() {
    quest.embark();
  }

}

我們可以看到篮撑,不同于之前的DamselRescuingKnight减细,BraveKnight沒有自行創(chuàng)建探險任務(wù),而是在構(gòu)造的時候把探險任務(wù)作為構(gòu)造器參數(shù)傳入赢笨。這是依賴注入的方式之一未蝌,即構(gòu)造器注入(constructor injection)驮吱。

更重要的是,傳入的探險類型是Quest树埠,也就是所有探險任務(wù)都必須實現(xiàn)的一個接口糠馆。所以,BraveKnight能夠響應(yīng)RescueDamselQuest怎憋、 SlayDragonQuest又碌、 MakeRoundTableRounderQuest等任意的Quest實現(xiàn)。

這里的要點是BraveKnight沒有與任何特定的Quest實現(xiàn)發(fā)生耦合绊袋。對它來說毕匀,被要求挑戰(zhàn)的探險任務(wù)只要實現(xiàn)了Quest接口,那么具體是哪種類型的探險就無關(guān)緊要了癌别。這就是DI所帶來的最大收益——松耦合皂岔。如果一個對象只通過接口(而不是具體實現(xiàn)或初始化過程)來表明依賴關(guān)系,那么這種依賴就能夠在對象本身毫不知情的情況下展姐,用不同的具體實現(xiàn)進行替換躁垛。

至入如何注入,我們后續(xù)再討論圾笨。


應(yīng)用切面

DI能夠讓相互協(xié)作的軟件組件保持松散耦合教馆,而面向切面編程(aspect-orientedprogramming,AOP)允許你把遍布應(yīng)用各處的功能分離出來形成可重用的組件擂达。

面向切面編程往往被定義為促使軟件系統(tǒng)實現(xiàn)關(guān)注點的分離一項技術(shù)土铺。系統(tǒng)由許多不同的組件組成,每一個組件各負責(zé)一塊特定功能板鬓。除了實現(xiàn)自身核心的功能之外悲敷,這些組件還經(jīng)常承擔(dān)著額外的職責(zé)。諸如日志俭令、事務(wù)管理和安全這樣的系統(tǒng)服務(wù)經(jīng)常融入到自身具有核心業(yè)務(wù)邏輯的組件中去后德,這些系統(tǒng)服務(wù)通常被稱為橫切關(guān)注點,因為它們會跨越系統(tǒng)的多個組件抄腔。

如果將這些關(guān)注點分散到多個組件中去探遵,你的代碼將會帶來雙重的復(fù)雜性:

  • 實現(xiàn)系統(tǒng)關(guān)注點功能的代碼將會重復(fù)出現(xiàn)在多個組件中。這意味著如果你要改變這些關(guān)注點的邏輯妓柜,必須修改各個模塊中的相關(guān)實現(xiàn)。即使你把這些關(guān)注點抽象為一個獨立的模塊涯穷,其他模塊只是調(diào)用它的方法棍掐,但方法的調(diào)用還是會重復(fù)出現(xiàn)在各個模塊中。
  • 組件會因為那些與自身核心業(yè)務(wù)無關(guān)的代碼而變得混亂拷况。一個向地址簿增加地址條目的方法應(yīng)該只關(guān)注如何添加地址作煌,而不應(yīng)該關(guān)注它是不是安全的或者是否需要支持事務(wù)掘殴。

圖1.2展示了這種復(fù)雜性。左邊的業(yè)務(wù)對象與系統(tǒng)級服務(wù)結(jié)合得過于緊密粟誓。每個對象不但要知道它需要記日志奏寨、進行安全控制和參與事務(wù)望浩,還要親自執(zhí)行這些服務(wù)祸泪。

圖1.2 在整個系統(tǒng)內(nèi)溉瓶,關(guān)注點(例如日志和安全) 的調(diào)用經(jīng)常散布到各個模塊中拷橘,而這些關(guān)注點并不是模塊的核心業(yè)務(wù)

AOP能夠使這些服務(wù)模塊化拙寡,并以聲明的方式將它們應(yīng)用到它們需要影響的組件中去拗踢。所造成的結(jié)果就是這些組件會具有更高的內(nèi)聚性并且會更加關(guān)注自身的業(yè)務(wù)尔觉,完全不需要了解涉及系統(tǒng)服務(wù)所帶來復(fù)雜性环戈∩枰祝總之逗柴,AOP能夠確保POJO的簡單性。

如圖1.3所示顿肺,我們可以把切面想象為覆蓋在很多組件之上的一個外殼戏溺。應(yīng)用是由那些實現(xiàn)各自業(yè)務(wù)功能的模塊組成的。借助AOP屠尊,可以使用各種功能層去包裹核心業(yè)務(wù)層旷祸。這些層以聲明的方式靈活地應(yīng)用到系統(tǒng)中,你的核心應(yīng)用甚至根本不知道它們的存在知染。這是一個非常強大的理念肋僧,可以將安全、事務(wù)和日志關(guān)注點與核心業(yè)務(wù)邏輯相分離控淡。

圖1.3 利用AOP嫌吠,系統(tǒng)范圍內(nèi)的關(guān)注點覆蓋在它們所影響組件之上

至入如何應(yīng)用切面,我們后續(xù)再討論掺炭。

還有使用模板消除樣板式代碼就不討論了辫诅,比如JDBC Templete。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末涧狮,一起剝皮案震驚了整個濱河市炕矮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌者冤,老刑警劉巖肤视,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異涉枫,居然都是意外死亡邢滑,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門愿汰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來困后,“玉大人乐纸,你說我怎么就攤上這事∫∮瑁” “怎么了汽绢?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長侧戴。 經(jīng)常有香客問我宁昭,道長,這世上最難降的妖魔是什么救鲤? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任久窟,我火速辦了婚禮,結(jié)果婚禮上本缠,老公的妹妹穿的比我還像新娘斥扛。我一直安慰自己,他們只是感情好丹锹,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布稀颁。 她就那樣靜靜地躺著,像睡著了一般楣黍。 火紅的嫁衣襯著肌膚如雪匾灶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天租漂,我揣著相機與錄音阶女,去河邊找鬼。 笑死哩治,一個胖子當(dāng)著我的面吹牛秃踩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播业筏,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼憔杨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蒜胖?” 一聲冷哼從身側(cè)響起消别,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎台谢,沒想到半個月后寻狂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡朋沮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年荆虱,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡怀读,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出骑脱,到底是詐尸還是另有隱情菜枷,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布叁丧,位于F島的核電站啤誊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏拥娄。R本人自食惡果不足惜蚊锹,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望稚瘾。 院中可真熱鬧牡昆,春花似錦、人聲如沸摊欠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽些椒。三九已至播瞳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間免糕,已是汗流浹背赢乓。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留石窑,地道東北人牌芋。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像尼斧,于是被迫代替她去往敵國和親姜贡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

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