spring思想分析

摘要: EveryBody in the world should learn how to program a computer...because it teaches you how to think. --Steve Jobs前端

一切都是從Bean開始的

 

        在1996年,Java還只是一個新興的、初出茅廬的編程語言。人們之因此關注她僅僅是由於,可使用Java的Applet來開發Web應用。但這些開發者很快就發現這個新興的語言還能作更多的事情。與以前的全部語言不一樣,Java讓模塊化構建複雜的系統成爲可能(當時的軟件行業雖然在業務上日新月異,但當時開發用的是傳統的面向過程開發思想,軟件的開發效率一直踟躕不前。伴隨着業務複雜性的不斷加深,開發也變得愈加困難。其實,當時也是面向對象思想飛速發展的時期,她在80年代末被提出,成熟於90年代,現今大多數編程語言都是面向對象的,固然這是後話了)。他們爲Applet而來,爲組件化而留。這即是最先的Java。java

        一樣在這一年的12月,Sun公司發佈了當時還名不見經傳但後來人盡皆知的JavaBean 1.00-A規範。早期的JavaBean規範針對於Java,她定義了軟件組件模型。這個規範規定了一整套編碼策略,使簡單的Java對象不只能夠被重用,並且還能夠輕鬆地構建更爲複雜的應用。儘管JavaBean最初是爲重用應用組件而設計的,但當時他們倒是主要用做構建窗體控件,畢竟在PC時代那纔是主流。但相比於當時正如日中天的Delphi、VB和C++,他看起來仍是太簡易了,以致於沒法勝任任何"實際的"工做。程序員

        複雜的應用一般須要諸如事物、安全、分佈式等服務的支持,但JavaBean並未直接提供。因此到了1998年3月,Sun發佈了EJB 1.0規範,該規範把Java組件的設計理念延伸到了服務器端,並提供了許多必須的企業級服務,但他也再也不像早期的JavaBean那麼簡單了。實際上,除了名字,EJB Bean已經和JavaBean 沒有任何關係了。web

        儘管現實中有不少系統是基於EJB構建的,但EJB歷來沒有實現它最初的設想:簡化開發。EJB的聲明式編程模型的確簡化了不少基礎架構層面的開發,例如事務和安全;但另外一方面EJB在部署描述符和配套代碼實現等方面變得異常複雜。隨着時間的推移,不少開發者對EJB已經再也不抱有幻想,開始尋求更簡潔的方法。算法

        如今Java組件開發理念從新迴歸正軌。新的編程技術AOP和DI的不斷出現,他們爲JavaBean提供了以前EJB才能擁有的強大功能。這些技術爲POJO提供了相似EJB的聲明式編程模型,而沒有引入任何EJB的複雜性。當簡單的JavaBean足以勝任時,人們便不肯編寫笨重的EJB組件了。spring

        客觀地講,EJB的發展甚至促進了基於POJO的編程模型。引入新的理念,最新的EJB規範相比以前的規範有了史無前例的簡化,但對不少開發者而言,這一切的一切都來得太遲了。到了EJB 3規範發佈時,其餘基於POJO的開發架構已經成爲事實的標準了,而Spring框架也是在這樣的大環境下出現的。數據庫

 

 

 

代碼簡潔之路

        Rod Johnson的思考

        Rod Johnson這位澳大利亞的Java大師,很難想象,他除了在悉尼大學得到計算機學士學位之外還得到了音樂的博士學位,或許正是他音樂的細胞成就了Spring獨特簡約和優雅。他在1996年就踏足Java開發,而且在C++方面也已經有了很深厚的造詣。他常年從事保險、銀行等企業的開發,是一個一切從現實出發的設計者以及勇敢的創新者。express

         Rod Johnson在2002年編著的《Expert One-to-One J2EE Design and Development》一書中,對EJB框架的臃腫、低效、脫離現實等種種現狀提出了質疑,並積極尋求革新之道。以此書爲指導思想,他編寫了interface21框架,這是一個力圖衝破Java EE傳統開發困境,從實際需求出發,着眼於輕便、靈巧,易於開發、測試和部署的輕量級開發框架。Spring框架即以interface21框架爲基礎,通過從新設計,並不斷豐富其內涵,於2004年3月24日,發佈了Spring 1.0正式版。同年他又推出了另外一部堪稱經典的力做《Expert One-to-One J2EE Development without EJB》,該書在Java世界掀起了軒然大波,不斷地改變着Java開發者程序設計和開發的思考方式。在該書中,做者根據本身多年豐富的實踐經驗,對EJB的各項笨重臃腫的結構進行了逐一的分析和否認,並分別以簡潔實用的方法代替。能夠說,這本書中的代碼誕生了Spring Framework。藉此,Rod Johnson也奠基了他在Java世界中大師級人物的地位。編程

        設計伊始

      Spring 是爲解決企業級應用開發的複雜性而設計,她能夠作不少事。但歸根到底支撐Spring的僅僅是少量的基本理念,而全部地這些的基本理念都能能夠追溯到一個最根本的使命:簡化開發。這是一個鄭重的承諾,其實許多框架都聲稱在某些方面作了簡化。設計模式

        而Spring則立志於全方面的簡化Java開發。對此,她主要採起了4個關鍵策略:

            1,基於POJO的輕量級和最小侵入性編程;

            2,經過依賴注入和麪向接口鬆耦合;

            3,基於切面和慣性進行聲明式編程;

            4,經過切面和模板減小樣板式代碼;

        而他主要是經過:面向Bean、依賴注入以及面向切面這三種方式來達成的。

        面向Bean

        Spring 是面向 Bean 的編程(Bean Oriented Programming, BOP),Bean 在 Spring 中才是真正的主角。Bean 在 Spring 中做用就像 Object 對 OOP 的意義同樣,Spring 中沒有 Bean 也就沒有 Spring 存在的意義。Spring 提供了 IoC容器經過配置文件或者註解的方式來管理對象之間的依賴關係。

        控制反轉( 其中最多見的方式叫作依賴注入(Dependency Injection,DI),還有一種方式叫「依賴查找」(Dependency Lookup,DL),她在C++、Java、PHP以及.NET中都運用。在最先的Spring中是包含有依賴注入方法和依賴查詢的,但由於依賴查詢使用頻率太低,不久就被Spring移除了,因此在Spring中控制反轉也被稱做依賴注入),她的基本概念是:不建立對象,可是描述建立它們的方式。在代碼中不直接與對象和服務鏈接,但在配置文件中描述哪個組件須要哪一項服務。容器 (在 Spring 框架中是 IoC容器) 負責將這些聯繫在一塊兒。

        在典型的 IoC場景中,容器建立了全部對象,並設置必要的屬性將它們鏈接在一塊兒,決定什麼時間調用方法。

        依賴注入

        Spring 設計的核心 org.springframework.beans 包(架構核心是org.springframework.core包),它的設計目標是與 JavaBean 組件一塊兒使用。這個包一般不是由用戶直接使用,而是由服務器將其用做其餘多數功能的底層中介。下一個最高級抽象是 BeanFactory 接口,它是工廠設計模式的實現,容許經過名稱建立和檢索對象。BeanFactory 也能夠管理對象之間的關係。

        BeanFactory 支持兩個對象模型。

            1,單例:模型提供了具備特定名稱的對象的共享實例,能夠在查詢時對其進行檢索。Singleton 是默認的也是最經常使用的對象模型。對於無狀態服務對象很理想。

            2,原型:模型確保每次檢索都會建立單獨的對象。在每一個用戶都須要本身的對象時,原型模型最適合。

        bean 工廠的概念是 Spring 做爲 IoC容器的基礎。IoC則將處理事情的責任從應用程序代碼轉移到框架。

        面向切面

        面向切面編程,即 Aop,是一種編程技術,它容許程序員對橫切關注點或橫切典型的職責分界線的行爲(例如日誌和事務管理)進行模塊化。Aop的核心構造是方面,它將那些影響多個類的行爲封裝到可重用的模塊中。

        Aop和 IoC是補充性的技術,它們都運用模塊化方式解決企業應用程序開發中的複雜問題。在典型的面向對象開發方式中,可能要將日誌記錄語句放在全部方法和 Java 類中才能實現日誌功能。在 Aop方式中,能夠反過來將日誌服務模塊化,並以聲明的方式將它們應用到須要日誌的組件上。固然,優點就是 Java 類不須要知道日誌服務的存在,也不須要考慮相關的代碼。因此,用 Spring Aop編寫的應用程序代碼是鬆散耦合的。

        Aop的功能徹底集成到了 Spring 事務管理、日誌和其餘各類特性的上下文中。

 

俯瞰Spring源碼架構

        系統架構

        Spring 總共大約有20個模塊,由1300多個不一樣的文件構成。而這些組件被分別整合在覈心容器(Core Container)、Aop(Aspect Oriented Programming)和設備支持(Instrmentation)、數據訪問及集成(Data Access/Integeration)、Web、報文發送(Messaging)、Test,6個模塊集合中。

        如下是 Spring 4 的系統架構圖。

 

        組成 Spring 框架的每一個模塊集合或者模塊均可以單獨存在,也能夠一個或多個模塊聯合實現。每一個模塊的組成和功能以下:

        1.核心容器由spring-beans、spring-core、spring-context和spring-expression(Spring Expression Language, SpEL) 4個模塊組成。

                spring-beans和spring-core模塊是Spring框架的核心模塊,包含了控制反轉(Inversion of Control, IoC)和依賴注入(Dependency Injection, DI)。BeanFactory 接口是Spring框架中的核心接口,它是工廠模式的具體實現。BeanFactory 使用控制反轉對應用程序的配置和依賴性規範與實際的應用程序代碼進行了分離。但 BeanFactory 容器實例化後並不會自動實例化 Bean,只有當 Bean 被使用時 BeanFactory 容器纔會對該 Bean 進行實例化與依賴關係的裝配。

                spring-contest模塊構架於核心模塊之上,他擴展了BeanFactory,爲她添加了Bean生命週期控制、框架事件體系以及資源加載透明化等功能。此外該模塊還提供了許多企業級支持,如郵件訪問、遠程訪問、任務調度等,ApplicationContext是該模塊的核心接口,她是 BeanFactory 的超類,與 BeanFactory 不一樣,ApplicationContext 容器實例化後會自動對全部的單實例 Bean 進行實例化與依賴關係的裝配,使之處於待用狀態。 

                spring-expression模塊是統一表達式語言(unified EL)的擴展模塊,能夠查詢、管理運行中的對象,同時也方便的能夠調用對象方法、操做數組、集合等。它的語法相似於傳統EL,但提供了額外的功能,最出色的要數函數調用和簡單字符串的模板函數。這種語言的特性是基於 Spring 產品的需求而設計,他能夠很是方便地同Spring IoC進行交互。

        2.Aop和設備支持:由spring-aop、spring-aspects和spring-instrumentation 3個模塊組成。

                spring-aop是Spring的另外一個核心模塊,是Aop主要的實現模塊。做爲繼OOP後,對程序員影響最大的編程思想之一,Aop極大地開拓了人們對於編程的思路。在Spring中,他是以JVM的動態代理技術爲基礎,而後設計出了一系列的Aop橫切實現,好比前置通知、返回通知、異常通知等,同時,Pointcut接口來匹配切入點,可使用現有的切入點來設計橫切面,也能夠擴展相關方法根據需求進行切入。

                spring-aspects模塊集成自AspectJ框架,主要是爲Spring Aop提供多種Aop實現方法。

                spring-instrumentation模塊是基於JAVA SE中的"java.lang.instrument"進行設計的,應該算是Aop的一個支援模塊,主要做用是在JVM啓用時,生成一個代理類,程序員經過代理類在運行時修改類的字節,從而改變一個類的功能,實現Aop的功能。在分類裏,我把他分在了Aop模塊下,在Spring 官方文檔裏對這個地方也有點含糊不清,這裏是純我的觀點。

        3.數據訪問及集成:由spring-jdbc、spring-tx、spring-orm、spring-jms和spring-oxm 5個模塊組成。

                spring-jdbc模塊是Spring 提供的JDBC抽象框架的主要實現模塊,用於簡化Spring JDBC。主要是提供JDBC模板方式、關係數據庫對象化方式、SimpleJdbc方式、事務管理來簡化JDBC編程,主要實現類是JdbcTemplate、SimpleJdbcTemplate以及NamedParameterJdbcTemplate。

                spring-tx模塊是Spring JDBC事務控制實現模塊。使用Spring框架,它對事務作了很好的封裝,經過它的Aop配置,能夠靈活的配置在任何一層;可是在不少的需求和應用,直接使用JDBC事務控制仍是有其優點的。其實,事務是以業務邏輯爲基礎的;一個完整的業務應該對應業務層裏的一個方法;若是業務操做失敗,則整個事務回滾;因此,事務控制是絕對應該放在業務層的;可是,持久層的設計則應該遵循一個很重要的原則:保證操做的原子性,即持久層裏的每一個方法都應該是不能夠分割的。因此,在使用Spring JDBC事務控制時,應該注意其特殊性。

                spring-orm模塊是ORM框架支持模塊,主要集成 Hibernate, Java Persistence API (JPA) 和 Java Data Objects (JDO) 用於資源管理、數據訪問對象(DAO)的實現和事務策略。

                spring-jms模塊(Java Messaging Service)可以發送和接受信息,自Spring Framework 4.1之後,他還提供了對spring-messaging模塊的支撐。

                spring-oxm模塊主要提供一個抽象層以支撐OXMOXM是Object-to-XML-Mapping的縮寫,它是一個O/M-mapper,將java對象映射成XML數據,或者將XML數據映射成java對象),例如:JAXB, Castor, XMLBeans, JiBX 和 XStream等。

        4.Web:由spring-web、spring-webmvc、spring-websocket和spring-webmvc-portlet 4個模塊組成。

                spring-web模塊爲Spring提供了最基礎Web支持,主要創建於核心容器之上,經過Servlet或者Listeners來初始化IoC容器,也包含一些與Web相關的支持。

                spring-webmvc模塊衆所周知是一個的Web-Servlet模塊,實現了Spring MVC(model-view-controller)的Web應用。

                spring-websocket模塊主要是與Web前端的全雙工通信的協議。(資料缺少,這是我的理解

                spring-webmvc-portlet模塊是知名的Web-Portlets模塊(Portlets在Web門戶上管理和顯示的可插拔的用戶界面組件。Portlet產生能夠聚合到門戶頁面中的標記語言代碼的片斷,如HTML,XML等),主要是爲SpringMVC提供Portlets組件支持。

        5.報文發送:即spring-messaging模塊。

                spring-messaging是Spring4 新加入的一個模塊,主要職責是爲Spring 框架集成一些基礎的報文傳送應用。

        6.Test:即spring-test模塊。

                spring-test模塊主要爲測試提供支持的,畢竟在不須要發佈(程序)到你的應用服務器或者鏈接到其餘企業設施的狀況下可以執行一些集成測試或者其餘測試對於任何企業都是很是重要的。

        依賴關係

        該圖是SPRING 3.2.X 的包結構,能夠從中清楚看出 Spring 各個模塊之間的依賴關係。

        

        從圖中能夠看出,IoC 的實現包 spring-beans 和 AOP 的實現包 spring-aop 是整個框架的基礎,而 spring-core 則是整個框架的核心,基礎的功能都在這三個包裏。

        在此基礎之上,spring-context 提供上下文環境,爲各個模塊提供粘合做用。

        在 spring-context 基礎之上提供了 spring-tx 和 spring-orm包,而web部分的功能,都是要依賴spring-web來實現的。

        因爲struts框架自身的Bug一直沒有修復,以及Spring MVC 已經足夠強大,因此在最新的spring 4 中已經移除了 spring-struts 模塊。

        若是你想加入spring源碼的學習,筆者的建議是從spring-core入手,其次是spring-beans和spring-aop,隨後是spring-context,再其次是spring-tx和spring-orm,最後是spring-web和其餘部分。

 

閒言小敘

        框架小結

            筆者將Spring的內部設計與操做系統 kernel(Linux內核)的設計方法進行類比,但願藉此能更形象的說明Spring體系。

            Spring體系的核心是IoC和Aop模塊。對於kernel而言,進程調度器就是其關鍵部位,kernel經過「進程」這個概念來抽象物理的計算資源,同時經過調度算法的設計來實現對計算資源的高效使用。而對於Spring來講,也是同樣的,一方面經過IoC容器來進行POJO對象管理,以及對他們進行鬆耦合處理,同時也讓信息資源能夠用最簡單的Java 語言來抽象和描述;另外一方面,能夠經過Aop來加強服務的功能。

            另外,在Spring體系中,Spring簡化了Java EE所進行的開發,這種簡化是指咱們可以在不EJB這麼厚重的環境中使用Java EE的基本服務——爲應用開發服務提供了許多即開即用的系統組件合服務,這些服務涵蓋了Java EE各個基本服務,對於其餘的服務,也能夠根據使用狀況動態擴展到Spring體系中。基原本說,Spring體系中已經涵蓋了Java EE中常常用到的許多服務,好比事務處理、Web MVC、JDBC、ORM、遠程調用,這些服務的價值是不可忽視的,就像kernel若是沒有實現許多驅動,那Linux對用戶而言也是沒有任何價值的。Spring經過本身的努力,提供了這些看起來不起眼,但對推廣起着關鍵做用的部分,從而構建起了一個豐富的生態圈。其實,這也是interface21和Spring之間的區別。

            和Linux同樣,做爲一個開源項目。其開源的特性也深深影響了Spring體系的設計,在發展的過程當中,其自身也吸取了很多好的社區項目,好比Spring的Security框架就是來源於社區Acegi,這個框架的原意是爲Spring設計一個安全框架,讓Spring應用更方便地處理一些安全性的問題,但慢慢的被Spring吸取,成爲Spring的一個子項目。

        太史公曰

            筆者坦言,文中的觀點創建於大量地書籍、博客、英文資料以及筆者親身經歷之上,其實中間有很多是他人觀點和創意,甚至有不少就是原文或者間接的翻譯。但筆者認爲借鑑他人觀點和創意並不可恥,畢加索說過,拙工偷,巧匠盜,但如何將他人的創意有機的結合爲一個總體,這就徹底看我的的品味了。

            本篇是帶你走入Spring世界,主要是着眼於架構設計和源碼角度編寫,其實這也是筆者的Spring 源碼分析的寫做計劃,筆者將她分爲了四個部分總共八篇,第一部分是本文主要介紹Spring源碼框架,其次是第二部分源碼分析第一階段主要分兩篇主要介紹Spring的核心容器和Aop,再其次是源碼分析第二階段分爲四篇主要介紹數據訪問及集成、Web、報文發送以及Test,最後是一篇總綱。慢工出細活,筆者預計會在一至三個月內編寫完一篇,所有完成,可能會花費半年到二年時間。很長對吧,但對於獨具匠心的Spring 框架,筆者認爲這一切都是值得的。固然筆者也但願,本身能從中得出啓示,從而開發出新的東西,畢竟創造的樂趣遠遠大於使用的樂趣。        

            最後筆者聲明,筆者的初衷是編寫筆者對Spring源碼分析的總結,平時的興趣也僅僅在於源碼分析、後臺以及系統架構。

相關文章
相關標籤/搜索