Changes between Version 1 and Version 2 of waue/2011/spring


Ignore:
Timestamp:
Aug 24, 2011, 4:54:49 PM (13 years ago)
Author:
waue
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • waue/2011/spring

    v1 v2  
     1
     2{{{
     3#!html
     4<div style="text-align: center; color:#151B8D"><big style="font-weight: bold;"><big><big>
     5Spring 學習
     6</big></big></big></div> <div style="text-align: center; color:#7E2217"><big style="font-weight: bold;"><big>
     7
     8</big></big></div>
     9}}}
     10[[PageOutline]]
     11
     12
     13
     14= 理由 =
     15
     16閱讀「iT人甘苦談─穩定的工作並非人生的全部」
     17最後一段描述:「對於掌握程式外包的品質,具有相當程度的信心。….比如開發一個以Java為主的專案.....會要求,團隊必須遵照Spring Framework的應用程式框架開發。..只要依照標準,基本上品質不會差到哪裡去。」
     18
     19= spring =
     20
     21Spring 的核心是個輕量級(Lightweight)容器(Container),實現了IoC(Inversion of Control)模式的容器,基於此核心容器所建立的應用程式,可以達到程式元件的鬆散耦合(Loose coupling),讓程式元件可以進行測試(Testability),這些特性都使得整個應用程式可以在架構上與維護上都能得到相當程度的簡化。
     22
     23 * 輕量級(Lightweight)
     24   * 核心在檔案容量上只有不到 1MB 的大小
     25   * 使用核心所需要的資源也是很小的
     26   * 非侵入性(Nonintrusive)框架,它的目的之一,是讓應用程式不感受到框架的存在,減低應用程式從框架移植時的負擔。
     27
     28 * 容器(Container)
     29   * 管理物件的生命週期、物件的組態、相依注入等
     30   * 控制物件在創建時是以 原型(Prototype) 或 單例(Singleton) 的方式來建立。
     31 * IoC(Inversion of Control)
     32   * Spring 的核心概念是IoC,更具體而易懂的名詞是依賴注入(Dependency Injection)
     33   * 不必自己在程式碼中維護物件的依賴關係,只需在組態檔中加以設定
     34
     35除了這些特性之外,Spring 的目標是實現一個全方位的整合框架,在 Spring 框架下實現多個子框架的組合,這些子框架之間彼此可以獨立,也可以使用其它的框架方案加以替代,Spring 希望提供 one-stop shop 的框架整合方案。
     36
     37 * AOP 框架
     38   * 支援AOP(Aspect-oriented programming)
     39 * 持久層
     40   * JDBC、O/R Mapping工具(Hibernate、iBATIS)、事務處理等。
     41 * Web 框架
     42   * 提供 Web 框架的解決方案
     43   * 也可以將自己所熟悉的 Web 框架與 Spring 整合
     44   * 如 Struts、Webwork 等
     45
     46對於一些服務,例如 JNDI、Mail、排程、遠程等,Spring 不直接提供實作,而是採取抽象層方式進行包裝,讓這些服務在使用時可以有一致的使用模式且更為方便。
     47
     48= IoC 模式 =
     49
     50
    151IoC模式基本上是一個高層的概念,在 Martin Fowler 的 Inversion of Control Containers and the Dependency Injection pattern 中談到,實現IoC有兩種方式:Dependency Injection與Service Locator,Spring 所採用的是Dependency Injection 來實現 IoC,中文翻譯為依賴注入,依賴注入的意義是:「保留抽象介面,讓組件依賴於抽象介面,當組件要與其它實際的物件發生依賴關係時,藉過抽象介面來注入依賴的實際物件。」
    252
     
    108158
    109159Spring的核心是個IoC容器,您可以用Setter或Constructor的方式來實現您的業務物件,至於物件與物件之間的關係建立,則透過組態設定,讓Spring在執行時期根據組態檔的設定來為您建立物件之間的依賴關係,您不必特地撰寫一些Helper來自行建立這些物件之間的依賴關係,這不僅減少了大量的程式撰寫,也降低了物件之間的耦合程度。
     160
     161 == Dependency Injection ==
     162
     163Spring 所採用的是Dependency Injection 來實現 IoC,中文翻譯為依賴注入,依賴注入的意義是:「保留抽象介面,讓組件依賴於抽象介面,當組件要與其它實際的物件發生依賴關係時,藉過抽象介面來注入依賴的實際物件。」
     164
     165 == Type 2 IoC ==
     166
     167BusinessObject 依賴於實際的 FloppyWriter,為了讓 BusinessObject 獲得重用性,不讓 BusinessObject 直接依賴於實際的 FloppyWriter,而是依賴於抽象的介面:
     168{{{
     169#!java
     170public interface IDeviceWriter {
     171    public void saveToDevice();
     172}
     173
     174public class BusinessObject {
     175    private IDeviceWriter writer;
     176
     177    public void setDeviceWriter(IDeviceWriter writer) {
     178        this.writer = writer;
     179    }
     180
     181    public void save() {
     182        ....
     183        writer.saveToDevice();
     184    }
     185}
     186
     187public class FloppyWriter implement IDeviceWriter {
     188    public void saveToDevice() {
     189        ....
     190        // 實際儲存至Floppy的程式碼
     191    }
     192}
     193
     194public class UsbDiskWriter implement IDeviceWriter {
     195    public void saveToDevice() {
     196        ....
     197        // 實際儲存至UsbDisk的程式碼
     198    }
     199}
     200
     201}}}
     202
     203如果今天BusinessObject想要與UseDiskWriter物件發生依賴關係,可以這麼建立:
     204businessObject.setDeviceWriter(new UsbDiskWriter());
     205
     206
     207由於BusinessObject依賴於抽象介面,在需要建立依賴關係時,可以透過抽象介面注入依賴的實際物件。
     208
     209依賴注入在Martin Fowler的文章中談到了三種實現方式:Interface injection、Setter injection 與 Constructor injection。並分別稱其為Type 1 IoC、Type 2 IoC 與 Type 3 IoC。
     210
     211上面的BusinessObject所實現的是Type 2 IoC,透過Setter注入依賴關係,
     212
     213 == Type 3 IoC ==
     214
     215Type 3 IoC,則在是建構式上注入依賴關係,例如:
     216public class BusinessObject {
     217    private IDeviceWriter writer;
     218
     219    public BusinessObject(IDeviceWriter writer) {
     220        this.writer = writer;
     221    }
     222
     223    public void save() {
     224        ....
     225        writer.saveToDevice();
     226    }
     227}
     228
     229
     230Spring 鼓勵的是 Setter injection,但也允許您使用 Constructor injection,使用 Setter 或 Constructor 來注入依賴關係視您的需求而定,使用 Constructor 的好處之一是,您可以在建構物件的同時一併完成依賴關係的建立,然而如果要建立的物件關係很多,則會在建構式上留下一長串的參數,這時使用 Setter 會是個不錯的選擇,另一方面,Setter 可以有明確的名稱可以瞭解注入的物件會是什麼,像是setXXX()這樣的名稱會比記憶Constructor上某個參數位置代表某個物件來得好。
     231
     232 == Type 1 IoC ==
     233
     234Type 1 IoC是Interface injection,使用Type 1 IoC時會要求實作介面,這個介面是為容器所用的,容器知道介面上所規定的方法,它可以呼叫實作介面的物件來完成依賴關係的注入,例如:
     235public interface IDependencyInjection {
     236    public void createDependency(Map dependObjects);
     237}
     238
     239public class BusinessObject implement IDependencyInjection {
     240    private Map dependObjects;
     241
     242    public void createDependency(Map dependObjects) {
     243        this.dependObject = dependObjects;
     244        // 在這邊實現與BusinessObject的依賴關係
     245        ......
     246    }
     247
     248    public void save() {
     249        ....
     250        writer.saveToDevice();
     251    }
     252}
     253
     254
     255如果要完成依賴關係注入的物件,必須實現IDependencyInjection介面,並交由容器管理,容器會呼叫被管理物件的createDependency()方法來完成依賴關係的建立。
     256
     257在上面的例子中,Type 1 IoC要求BusinessObject實現特定的介面,這就使得BusinessObject依賴於容器,如果日後BusinessObject要脫離目前這個容器,就必須修改程式,想想在更複雜的依賴關係中產生更多複雜的介面,組件與容器(框架)的依賴會更加複雜,最後使得組件無法從容器中脫離。
     258
     259所以Type 1 IoC具有強的侵入性,使用它來實現依賴注入會使得組件相依於容器(框架),降低組件的重用性。
     260
     261Spring的核心是個IoC容器,您可以用Setter或Constructor的方式來實現您的業務物件,至於物件與物件之間的關係建立,則透過組態設定,讓Spring在執行時期根據組態檔的設定來為您建立物件之間的依賴關係,您不必特地撰寫一些Helper來自行建立這些物件之間的依賴關係,這不僅減少了大量的程式撰寫,也降低了物件之間的耦合程度。
     262