spring in action 第一章

spring in action 第一章

spring是從何而來?

spring是爲了解決企業級應用開發的複雜性而創建的,使用spring可以讓簡單的javaBeans實現以前EJB才能完成的事情。而且spring不僅僅侷限於服務器端開發,任何java應用都能在簡單性,可測試性和松耦合性等方面從spring中獲益。spring可以做很多事情。但歸根結底,支撐spring的僅僅是少許的基本理念,所有的理念都可以追溯到spring的的最根本使命上:簡化java開發。
降低java開發的複雜性,spring採取了以下四個策略:
1.基於POJO(簡單java類)的輕量級和最小侵入性編程
2.通過依賴注入和麪向接口實現松耦合
3.基於切面和慣例進行聲明式編程
4.通過切面和模板減少樣板式代碼

1簡化java開發

1.1激發pojo潛能

在以前的框架中我們的程序或許會被他們的規則焊死。而spring盡力避免自身api弄亂我們的代碼。spring不會強迫你你實現spring規範的接口或者繼承spring規範的類,相反,在基於spring構建的應用中,它的類通常沒有任何痕跡表明你使用了spring。最壞的場景是,一個類或許會使用spring註解,但它仍然是POJO(簡單java類)
在這裏插入圖片描述
就像是上圖的樣子,在HelloWorldBean上沒有任何過分的要求。這就是一個POJO(簡單Java類),沒有任何證據表明它是一個spring組件。spring的非侵入編程模型意味着這個類在spring應用和非spring應用中都可以發揮同樣的作用。

監管POJO看起來很簡單,但spring可以通過DI(依賴注入)來裝配它們。讓我們看看DI是如何幫助應用對象之間保持松耦合的。

1.2依賴注入

依賴注入看起來一個nb plus的詞語,現在也已經演變成爲一項複雜的編程技巧或設計模式理念。其實依賴注入並不像聽上去那樣複雜。在項目中應用DI,你會發現你的代碼會變得異常簡單而且更加容易理解和測試。

任何一個項目都會有兩個或者更多的類組成,這些類相互協作完成特定的業務邏輯。按照一貫做法,每個對象負責管理與自己相互協作的對象的引用,這將會導致高度耦合和難以測試的代碼。
在這裏插入圖片描述
如上DamselResuingKnight只能執行DamselResuingQuest的探險任務。這兩個類之間的耦合度太高了,以至於少女守護者只能做很單一的任務,他能隨時保護女孩但是如果要去殺掉惡龍或者給女孩打飯呢,那這個守護者是做不到這些的。

更糟糕的是爲這個類編寫單元測試出奇的困難,編寫測試我們要保證守護者被召喚來的時候他的方法會被調用,沒有簡單明瞭的方法可以實現這一點。

耦合具有兩面性。一方面,緊密耦合的代碼難以測試,難以複用,難以理解,並且典型的表現出“打地鼠”式的bug特性(修復一個bug會有更多bug出現)。另一方面耦合是不可避免的,爲了完成特定任務總有類在交互,所以我們應該謹慎管理耦合。

通過DI,對象的依賴關係由系統中的第三方組件在創建對象的時候進行設定,對象無需創建或者管理它們的依賴關係。
在這裏插入圖片描述
如上圖這次我們傳入一個quest他不是一個具體的探險任務,而是一個任務接口,只要實現了這個接口的探險任務BraveKnight都可以勝任。這樣BraveKnight沒有和任何特定探險任務有耦合,這就是DI的最大收益松耦合。

我們爲BraveKnight編寫一個測試是很輕鬆地,只需給quest一個mock實現即可
在這裏插入圖片描述
知道了spring松耦合的原理那麼我們該注入quest了有下圖一個殺龍的探險任務
在這裏插入圖片描述
可以看到這個類實現了Quest接口那麼它可以注入BraveKnight,我們不僅要把這個類注入到BraveKnight裏,而且要把stream注入到這個類裏面。spring將創建組件之間的協作行爲稱爲裝配(wiring)。spring多種裝配方式,第一種xml文件
在這裏插入圖片描述
第二種java配置
在這裏插入圖片描述
兩種帶來的DI收益是一樣的,並且它們都符合上面的松耦合規則,被裝配對象不知道要裝配什麼具體的對象,但是這些對象都有相同的接口,在裝配時才知道是什麼類型。

接下來要使用裝配好的對象,這時需要spring應用上下文,它全權負責對象的創建和組裝。spring有多種應用上下文,這裏選擇ClassPathXmlApplicationContext這個類加載類路徑下的一個或多個xml文件,如下圖
在這裏插入圖片描述
這裏可以看出來我們不知道knight的具體細節只有xml文件知道,我們不知道誰在執行任務,更不知道在執行什麼樣的任務。

1.3應用切面(這裏大都引用原文,原文很清晰)

DI能夠保證對象之間的松耦合,而面向切面允許編程允許把遍佈在各處的功能分離出可重用組件

在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
的理念
例子見原文這裏理解原理即可

1.4使用模板消除樣板式代碼

有時我們會將一些代碼一遍又一遍得寫,比如JDBC的代碼如圖
在這裏插入圖片描述
在這裏插入圖片描述
下面是spring jdbcTemplate的代碼
在這裏插入圖片描述
模板代碼可以讓你只關注代碼自身的職責。
在這裏插入圖片描述

2.容納你的bean

在spring應用中,你的應用對象生存於spring容器中,spring容器負責創建對象並且裝配它們,配置和管理它們的整個生命週期,從創建到死亡(從new 到 finalize)
在這裏插入圖片描述
在這裏插入圖片描述

2.1使用上下文

在這裏插入圖片描述
這裏不談web應用,剩餘的上下文使用方法如下
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
最後我們只需要用getBean方法獲取類就可以了

2.1bean的生命週期

一般的java bean生命週期從new開始一直到沒有引用的時候會被垃圾回收機制自動回收

相比而言spring bean生命週期要複雜得多,正確理解spring bean 生命週期非常重要,因爲你或許要利用spring提供的擴展點來自定義bean的創建過程。下圖展示了bean裝載到spring上下文中的一個完整的生命週期過程
在這裏插入圖片描述
在這裏插入圖片描述
spring的功能很強大,上面所述的DI AOP 和消除版樣式代碼只是spring的簡化java開發的基本功能,它還有許多超乎想象的功能。
在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章