Spring 源碼分析(一) —— 邁向Spring之路(轉載)

看到很好的相關Spring的源碼分析專題,就轉了,若對作者有影響,請聯繫我刪除該專題文章。

一切都是從Bean開始的

        在1996年,Java還只是一個新興的、初出茅廬的編程語言。人們之所以關注她僅僅是因爲,可以使用Java的Applet來開發Web應用。但這些開發者很快就發現這個新興的語言還能做更多的事情。與之前的所有語言不同,Java讓模塊化構建複雜的系統成爲可能(當時的軟件行業雖然在業務上突飛猛進,但當時開發用的是傳統的面向過程開發思想,軟件的開發效率一直踟躕不前。伴隨着業務複雜性的不斷加深,開發也變得越發困難。其實,當時也是面向對象思想飛速發展的時期,她在80年代末被提出,成熟於90年代,現今大多數編程語言都是面向對象的,當然這是後話了)。他們爲Applet而來,爲組件化而留。這便是最早的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 沒有任何關係了。

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

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

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

 

 

 

代碼簡潔之路

        Rod Johnson的思考

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

         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和其他部分。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章