1. 程式人生 > >讀書筆記 Spring In Action 4th 第一章 Spring 之旅

讀書筆記 Spring In Action 4th 第一章 Spring 之旅

裝配 遍布 模塊化 處的 nfa cati const mar 驗證

第一章的主要內容介紹

  • Spring的bean容器
  • 介紹Spring的核心模塊
  • 更為強大的Spring生態系統
  • Spring的新功能

Tips: POJO的內在含義是指那些沒有從任何類繼承、也沒有實現任何接口,更沒有被其它框架侵入的java對象。

當一個Pojo可序列化,有一個無參的構造函數使用getter和setter方法來訪問屬性時,他就是一個JavaBean。

簡化JAVA開發

Spring 目的是解決了企業級應用開發的復雜性,javabean的實現變得簡單,全方面的簡化java 開發的復雜性

  • 基於POJO的輕量級和最小侵入性編程;
  • 通過依賴註入和面向接口實現松耦合;
  • 基於切面和慣例進行聲明式編程;
  • 通過切面和模板減少樣板式代碼。

激發POJO的潛能

Spring 不會強迫實現 Spring 規範的接口,並且類沒有任何痕跡表明使用了Spring

eg:一個類或許有Spring 註解,但是仍然是POJO

技術分享圖片

如圖,這是一個簡單的JAVA類,POJO沒有任何的地方看出使用了Spring

依賴註入(DI)

傳統的做法是,每個對象自己負責管理與自己協作的對象的引用(依賴的對象)。 但是會導致高度耦合和難以測試。

技術分享圖片

DamselRescuingKnight在它的構造函數中自行創建了Rescue DamselQuest。這使得DamselRescuingKnight緊密地和RescueDamselQuest耦合到了一起,特定的類型。

並且編寫測試很困難,必須保證當騎士的embarkOnQuest()方法被調用的時候,探險的embark()方法也要被調用。 困難在於無法確保實例quest 已經被創建)

耦合具有兩面性:一方面使得代碼難以測試,復用,難以理解。另一方面,一定程度的耦合是必須的,不然完成不了任何功能(類之間不能交互和調用)。

通過DI 對象的依賴關系由系統中的第三方組件在創建對象的時候設定,對象無需自行的創建和管理依賴關系。依賴關系會自動交給對象,而不是由對象自己獲取依賴。

技術分享圖片

BraveKnight沒有自行創建探險任務,而是在構造的時候把探險任務作為構造器參數傳入。這是依賴註入的方式之一,即構造器註入(constructor injection)。

並且BraveKnight 可以實現任何類型的Quest 接口,這就是DI最大的收益,松耦合

測試BraveKnight

技術分享圖片

mock框架Mockito去創建一個Quest接口的mock實現。通過這個mock對象,就可以創建一個新的BraveKnight實例,並通過構造器註入這個mock Quest。

調用embarkOnQuest()方法時,可以要求Mockito框架驗證Quest的mock實現的embark()方法僅僅被調用了一次。

將Quest註入到Knight中

技術分享圖片

SlayDragonQuest實現了Quest接口,這樣它就適合註入到BraveKnight中去了。

So,現在有兩個問題:

如何將SlayDragonQuest交給BraveKnight呢?

如何將PrintStream交給SlayDragonQuest呢?

采用XML 的方式裝配bean

技術分享圖片

BraveKnight和SlayDragonQuest被聲明為Spring中的bean。

BraveKnight bean來講,它在構造時傳入了對SlayDragonQuest bean的引用,將其作為構造器參數

基於Java 的裝配

技術分享圖片

盡管BraveKnight依賴於Quest,但是它並不知道傳遞給它的是什麽類型的Quest,也不知道這個Quest來自哪裏。編碼階段並不知道具體的實現。

Spring通過應用上下文(Application Context)XML裝載bean的定義並把它們組裝起來,Spring自帶了很多種上下文實現。區別僅僅是如何裝配

技術分享圖片

註意這個類完全不知道我們的英雄騎士接受哪種探險任務,而且完全沒有意識到這是由BraveKnight來執行的。只有knights.xml文件知道哪個騎士執行哪種探險任務。

應用切面AOP

DI可以讓相互協作的軟件保持松耦合,面向切面編程(aspect-oriented programming,AOP)允許你把遍布應用各處的功能分離出來形成可重用的組件。

日誌、事務管理和安全這樣的系統服務可以跨越多個系統組件。

技術分享圖片

如果AOP可以使得這些服務模塊化,並且以聲明的方法,加入到需要的組件中,使得組件會具有高內聚的特定,更加關註自身業務實現。AOP能夠確保POJO的簡單性

技術分享圖片

借助AOP可以使用各種功能層去包裹核心業務層,這些層可以以聲明的方式加入到切入點。

AOP應用

在之前的程序中,加入吟遊詩人的角色

技術分享圖片

改變Knight 的代碼

技術分享圖片

這個程序中,騎士對吟遊詩人進行了管理,這是不符合邏輯的。騎士需要知道吟遊詩人,所以就必須把吟遊詩人註入到BarveKnight類中。這不僅使BraveKnight的代碼復雜化了。並且吟遊詩人不可復用,

利用AOP 可以將吟遊詩人聲明為一個切面,然後註入騎士的類中。

技術分享圖片

首先,需要把Minstrel聲明為一個bean,然後在<aop:aspect>元素中引用該bean。

兩種通知方法:

前置通知(before advice):(使用<aop:before>)在embarkOnQuest()方法執行前調用Minstrel的singBeforeQuest()方法。

後置通知(after advice):同時聲明(使用<aop:after>)在embarkOnQuest()方法執行後調用singAfter Quest()方法。

模板消除樣版式代碼 (感覺不重要)

樣板式代碼的一個常見範例是使用JDBC訪問數據庫查詢數據。舉個例子,如果你曾經用過JDBC,那麽你或許會寫出類似下面的代碼。

技術分享圖片

使用Spring的JdbcTemplate(利用了 Java 5特性的JdbcTemplate實現)重寫的getEmploy

eeById()方法僅僅關註於獲取員工數據的核心邏輯,而不需要迎合JDBC API的需求

技術分享圖片

容納BEAN

在Spring中,應用對象生存於Spring容器(container)Spring容器負責創建對象,裝配它們,配置它們並管理它們的整個生命周期,從生存到死亡。

容器是Spring的核心,容器使用DI構成應用組件。

Spring容器可以歸為兩種:

bean 工廠(由org.springframework. beans.factory.eanFactory接口定義)是最簡單的容器

應用上下文(由org.springframework.context.ApplicationContext接口定義)基於BeanFactory構建,並提供應用框架級別的服務

讀書筆記 Spring In Action 4th 第一章 Spring 之旅