引子
很早之前聽同事說:“要開會了。我都知道領導要問什么,就那幾板斧。”其實領導之所以為領導,人家問的問題確實很合情合理,甚至可以說一針見血。而之所以能問出來這些合理的問題,就是因為頭腦中有自己的思考框架。比如要做一件事情,一個思考框架就是:
1,我們現在是什么樣的?
2,我們要做成什么樣(解決什么問題、有什么收益)?
3,怎么才能達成(解決路徑)?
根據這個思考框架,開會的時候,給領導做匯報,一上來就說我做了什么什么。領導自然要問:“做這件事情有什么收益?” 如果一項任務指標特別好,領導就要問了:“那我們是怎么做到的呢?”
這種框架式自上而下的思考習慣,對做任何事情都會有幫助。比如想學習Spring,就先問自己3個問題:
1,出現Spring之前是什么樣子?
2,Spring的目標是什么?
3,Spring是怎么做到的呢?
出現Spring之前是什么樣子
出現Spring之前,MVC這種設計典范已經開始興起。在顯示層、模型層和控制層都有了一些工具的支持。比如顯示層有JQuery+JSON,模型層有ibatis,控制層有Struts。開發人員的主要精力應該放到業務邏輯的開發。但是開發前需要做一件事情:將MVC需要的這些東西組裝起來。每個人在新搭建一個工程時都需要進行組裝。那有沒有一個東西把開發人員需要的東西都弄好了,開發人員只需要將精力用戶業務邏輯開發呢?Spring就是為了解決這個問題而生。
Spring的目標是什么
Spring就是要最大限度的簡化開發工作,讓開發人員集中精力於自己的業務邏輯,也是DDD領域驅動開發。
Spring是怎么做到的呢
核心問題解決
1,解耦
開發人員希望聚焦DDD的開發,首先要解決的事情是我修改一個業務代碼,不希望顯示層、模型層和控制層都要改。不希望改一個類,依賴它的類也需要改。Spring為了應對這個問題使用了控制反轉的理念。將所有的依賴都由框架注入到一個上下文環境中(DI)。在這個環境中,Bean之間可以自由的使用。
2,復用
有了DI(依賴注入)的支持,開發人員可以具體聚焦DDD的開發了。一個優秀程序員的最大的美德是懶惰。一些邏輯,比如日志,鑒權,很多地方都需要用到。這個業務邏輯關系又不是很緊密,代碼基本上就是拷貝一下。那怎么能將這些業務特點不強的邏輯從開發人員的工作中剔除掉呢?這就用到了AOP(面向切面)編程。以上Spring要解決的核心問題解耦和復用的解決方案就是Spring的核心:控制反轉、依賴注入和AOP。
核心功能實現
為了將Spring的核心功能實現出來,就需要用到Robert Martin提出的SOLID原則。分別是單一職責、開放封閉、里氏替換、接口隔離和依賴倒置。控制反轉、依賴注入和AOP,分別對應了三個spring的jar包:spring-beans、spring-context、spring-aop。每個包單一的負責一個核心功能的實現。這些都需要先做對象的實例化,這個功能由spring-core這個jar包來實現。在Spring-beans中,Spring使用工廠模式來管理程序中使用的對象Bean。每個Bean實例以BeanDefinition的形式被創建,通過java的反射機制將需要初始化的字段寫入,最終保存在BeanDefinitionMap中。這整個過程由容器來實現,完成了控制反轉。有了控制反轉,開發者可以通過調用getBean獲取到所需要的對象。spring-context提供文件列表的讀入,將所有依賴的Bean放到一個Context中,就是常說的依賴注入。AOP的主要作用是不通過修改源代碼的方式將功能代碼織入來實現對方法的增強。實現的關鍵在於使用了代理模式。代理主要分為靜態代理和動態代理。靜態代理最簡單的實現就是創建一個代理類,將對象new出來之后,在調用方法前后都加上代碼。調用方調用代理類而不直接調用原始類。動態代理主要是JDK動態代理和Cglib動態代理,這里就不詳細展開了。
總結
本文從技術上,只介紹了Spring框架部分的核心功能。大家可以按照這個思路繼續將其他部分納入體系。當然,本文用的思考框架也只是思考框架的一種,是偏產品化的一個視角。完全可以用偏技術化的視角比如:「是什么、為什么、怎么辦」的思考框架,只要保持一個風格、梳理成體系就好。以上Spring相關的部分,用一張圖總結如下
溫故知新