相遇
淺談Framework
框架是一個相對抽象的概念,簡單來說是大家對於複雜的軟體系統提出一套設計模式的思想
或是規範
,可以大大提升系統的開發效率
、可維護性
、擴展性
等等。
舉例來說,今天建設公司要蓋大樓,一定會參考業界的建築規範
跟設計模式
,不會因為要蓋一棟新的大樓而重新規劃所有的建築規範,因為那都是前人設計師用血淚總結出來的經驗與架構,我們要思考的是站在現有框架的角度上如何優化
或擴展
,而不是重複的製造輪子,這也是Spring Framework
很重要的核心精神之一。
Spring
Spring Framework 是一個開源的Java框架,號稱是世界上最受歡迎的Java framework,對Web application提供了大量擴展功能。理論上所有的Java application都可以導入Spring並應用其核心功能。其核心功能為提供IoC Container
與AOP
模組。
為甚麼需要Spring
前面提到了,框架是為了提高開發效率而引入一連串的規範跟思想,而Spring主要幫我們做到了以下幾件事:
- 基於
POJO輕量級
與非侵入式
開發 - 通過
IoC
與DI
、抽象化
的設計思想來實現系統的低耦合
- 基於
AOP
和約束
實作宣告式程式設計
集成框架
支持
名詞解釋
POJO
全名是Plain Ordinary Java Object,就是簡單的Java物件。含意是指沒有從任何類別繼承、也沒有實作任何界面的Java物件。
侵入式概念
侵入式
- 改變了Java class的結構
- 對於
EJB
、Struts2
等傳統框架來說通常要實作特定的介面或繼承特定的類別才可以實現功能的擴展
非侵入式
- 對於
Spring
來說則不需要對現有class結構做出改變即可增強JavaBean功能
低耦合
耦合是指系統間各種不同功能的模組
之間關聯度量。耦合程度的高低取決於模組間的控制關係
、調用方式
來決定。
抽象化
抽象化可以總結成從實體當中萃取出更高層的概念。譬如以前國中生物學學到的生物分類法,將所有生物歸類為「界門綱目科屬種」。「界門綱目科屬種」為抽象化的展現,將具備部分相同特徵(屬性或方法)的生物(物件)層層抽象歸類。
在Java中抽象化主要可以通過繼承abastract class
或實作interface
去實現。兩者的差異大致是abstract class抽象了類別(屬性與方法),而interface抽象了行為(方法)。
相知
Spring組成與架構
Spring主要分為八大模組:
- Spring Core Container - 提供IoC Cotainer,負責管理物件的創建與依賴
- Spring Web - Spring對
web
模組的支持- 可以與
struts2
整合,讓struts2
創建的Action
交由Spring管理 - 整合
Spring MVC
框架
- 可以與
- Spring Data Acess - 數據訪問及集成
- Spring Aspects
- Spring Instrumentation - 設備支持
- Spring Messaging - 報文發送
- Spring AOP -
Aspect Oriented Programming
- Spring Test
其中最核心的兩個模組分別是Spring Core Container
與Spring AOP
,以下分別將兩個模組拉出來介紹說明。
IoC
概念
在開始前我們先來看一個情境:
今天我們的電商系統,使用者下單的邏輯大致可分為:
- User發送請求給Server
- Controller接收請求並轉發給Service
- service調用Dao
- Dao操作資料庫
- 層層return回User
思考時間
- 物件創建的控制權在誰手上?
- 物件創建細節?
- 創建時間?
- 創建數量?
- 物件的依賴關係?
如果我們按照傳統的邏輯調用物件 : 在Controller中new Service()、在Service中new Dao()…
那物件的依賴關係就是Controller依賴Service、Service依賴Dao…
而物件的創建時間與數量則難以掌握。當有一天因為某種原因需要更換DB,則需要修改所有Dao物件,再來可能需要修改Service物件,再來可能需要修改Controller物件…牽一髮而動全身。
為了解決以上問題,IoC的設計原則因此誕生。
IoC全稱Inverse of Control
,是Spring的核心思想之一。
主要思想是將物件之間的依賴跟創建的控制權從物件中抽離,轉交給IoC Cotainer
來管理跟控制,資源不再由使用資源的雙方管理,而交由不使用資源的第三方管理。主要有以下優點:
- 資源集中管理,實現可配置性與易維護性
- 大幅降低資源雙方耦合度,達到解耦目的
而前面略提到的DI(Dependency Injection)
則是實現IoC思想的一種方式。
- Dependency : bean物件的創建依賴於Container
- Injection : bean物件中的屬性由Container注入
在Java中,當A模組要使用到B模組功能時,通常是這麼做的:
public B class(){
//code...
A a = new A();
//code...
}
這種耦合在軟工中稱為Content Coupling
,指一個模組直接呼叫另一模組的內容。這種耦合的耦合性最強
,模組獨立性最弱
。這不是我們所樂見的。透過Spring IoC
來管理並調用模組,就可以解決Content Coupling
的問題。無論是創建物件、處理物件間的依賴關係、物件創建的時間還是物件的數量,我們都可以通過Spring提供的IoC Container
來管理。
小結
- 在未導入IoC原則時系統耦合高,彼此互相依賴
- 由IoC Container來管理創建物件,控制權反轉
- 物件間不再互相依賴,達到解耦目的
延伸閱讀 - Spring IoC
AOP
概念
首先我們先思考一個問題:
今天我們希望在我們的應用程式中加入權限驗證,舉例來說有些東西只有老闆可以看,一般員工不行。
如果依循OOP物件導向
的思維,我們就會在業務邏輯程式碼前再加上驗證的程式碼去確認身分並做出判斷。
但如果基於AOP剖面導向
的思維,切開業務邏輯與驗證邏輯,把驗證邏輯放到業務邏輯之外去完成,就是AOP的核心概念。他與OOP一樣都是程式設計典範
。
一般來說我們的程式執行流程是由上而下的,譬如一個登入邏輯:
- User發送HTTP request
- Controller接收request並呼叫對應的Service
- Service呼叫DAO操作DB並return
- 層層return給User
但在這過程中會產生一些橫切性的問題,譬如進入Controller時我們需要紀錄日誌、DAO操作DB時希望進行Transaction管理、進入Service時我們希望做身分驗證等等等等…
AOP即是為了解決這種橫切性的問題而誕生。AOP不關心業務邏輯,只關心這些橫切性問題的執行方法、執行時機、執行的地方、執行順序等等。
延伸閱讀 - Spring AOP
相惜
這篇文章主要簡單介紹Spring並針對其兩個核心設計思想的概念做一個介紹,更多的設計思想實作會再通過一系列的文章慢慢介紹。如果覺得有幫助到你,可以幫我點個讚小小支持。也歡迎在底下留言交流。
本文已被收錄在Github