Java輕量級業務層框架Spring兩大核心IOC和AOP原理


IoC(Inversion of Control):

  IOC的基本概念是:不創建對象,但是描述創建它們的方式。在代碼中不直接與對象和服務連接,但在配置文件中描述哪一個組件需要哪一項服務。容器負責將這些聯系在一起。   

      其原理是基於OO設計原則的The Hollywood Principle:Don't call us, we'll call you(別找我,我會來找你的)。也就是說,所有的組件都是被動的(Passive),所有的組件初始化和調用都由容器負責。組件處在一個容器當中,由容 器負責管理。   

      簡單的來講,就是由容器控制程序之間的關系,而非傳統實現中,由程序代碼直接操控。這也就是所謂“控制反轉”的概念所在:控制權由應用代碼中轉到了外部容器,控制權的轉移,是所謂反轉。

  (1)IoC(Inversion of Control)是指容器控制程序對象之間的關系,而不是傳統實現中,由程序代碼直接操控。控制權由應用代碼中轉到了外部容器,控制權的轉移是所謂反轉。對於Spring而言,就是由Spring來控制對象的生命周期和對象之間的關系;IoC還有另外一個名字——“依賴注入(Dependency Injection)”。從名字上理解,所謂依賴注入,即組件之間的依賴關系由容器在運行期決定,即由容器動態地將某種依賴關系注入到組件之中。

  (2)在Spring的工作方式中,所有的類都會在spring容器中登記,告訴spring這是個什么東西,你需要什么東西,然后spring會在系統運行到適當的時候,把你要的東西主動給你,同時也把你交給其他需要你的東西。所有的類的創建、銷毀都由 spring來控制,也就是說控制對象生存周期的不再是引用它的對象,而是spring。對於某個具體的對象而言,以前是它控制其他對象,現在是所有對象都被spring控制,所以這叫控制反轉。

  (3)在系統運行中,動態的向某個對象提供它所需要的其他對象。

  (4)依賴注入的思想是通過反射機制實現的,在實例化一個類時,它通過反射調用類中set方法將事先保存在HashMap中的類屬性注入到類中。

   總而言之,在傳統的對象創建方式中,通常由調用者來創建被調用者的實例,而在Spring中創建被調用者的工作由Spring來完成,然后注入調用者,即所謂的依賴注入or控制反轉。

   注入方式有兩種:依賴注入和設置注入;

   IoC的優點:降低了組件之間的耦合,降低了業務對象之間替換的復雜性,使之能夠靈活的管理對象。

 

AOP(Aspect Oriented Programming):

  AOP即Aspect-Oriented Programming的縮寫,中文意思是面向切面編程,也有譯作面向方面編程的,因為Aspect有“方面、見地”的意思。AOP實際上是一種編程思 想,由Gregor Kiczales在Palo Alto研究中心領導的一個研究小組於1997年提出[1]。在傳統的面向對象(Object-Oriented Progr amming,OOP)編程中,對垂直切面關注度很高,橫切面關注卻很少,也很難關注。也就是說,我們利用OOP思想可以很好的處理業務流程,卻不能把系 統中的某些特定的重復性行為封裝在某個模塊中。比如在很多的業務中都需要記錄操作日志,結果我們不得不在業務流程種嵌入大量的日志記錄代碼。無論是對業務 代碼還是對日志記錄代碼來說,今后的維護都是非常復雜的。由於系統種嵌入了這種大量的與業務無關的其它重復性代碼,系統的復雜性、代碼的重復性增加了,從 而使bug的發生率也大大的增加。

       在OOP面向對象編程中,我們總是按照某種特定的執行順序來實現業務流程,各個執行步驟之間是相互銜接、相互耦合的。比如某個對象拋出了異常,我們就必須 對異常進行處理后才能進行下一步的操作;又比如我們要把一個學生記錄插入到教務管理系統的學生表中去,那么我們就必須按照注冊驅動程序、連接數據庫、創建 一個statement、生成並執行SQL語句、處理結果、關閉JDBC對象等步驟按部就班的編寫我們的代碼。可以看到上面的步驟種除了執行SQL和處理 結果是我們業務流程所必須的外,其它的都是重復的准備和殿后工作,與業務流程毫無關系,另外我們還得要考慮程序執行過程中的異常。天!我們只是需要向一張 表中插入數據而已,可是卻不得不和這些大量的重復代碼糾纏在一起,我們不得不把大量的精力用在這些代碼上而無法專心的設計業務流程。

       那么什么可以解決這個問題呢?這時候,我們需要AOP,關注系統的“截面”,在適當的時候“攔截”程序的執行流程,把程序的預處理和后處理交給某個攔截器 來完成。比如在操作數據庫時要記錄日志,如果使用AOP的編程思想,那么我們在處理業務流程時不必再考慮日志記錄,而是把它交給一個特定的日志記錄模塊去 完成。這樣,業務流程就完全的從其它無關的代碼中解放出來,各模塊之間的分工更加明確,程序維護也變得容易多了。

      正如上所說,AOP不是一種技術,而是編程思想。凡是符合AOP思想的技術,都可以看成是AOP的實現。目前的AOP實現有AspectJ、 JBoss4.0、nanning、spring等項目。其中Spring對AOP進行了很好的實現,同時Spring AOP也是Spring的兩大核心之一。

     下面介紹一些關於AOP的一些概念,如果覺得有些晦澀,也可以先不必仔細關注。

     連接點(join point):它是指應用中執行的某個點,即程序執行流程中的某個點。如執行某個語句或者語句塊、執行某個方法、裝載某個類、拋出某個異常……,如下:

 

  1. public   static   void  main(String[] args)  throws  Exception {  
  2.    
  3.      int  i =  0 ;  
  4.    
  5.      i++;  
  6.      CallMyMethod();  
  7.    
  8.      throw   new  Exception( "哈哈,一個異常!" );  
  9.    
  10. }

 

注意:這里每一個語句都可以被稱作一個連接點。
      連接點是有“強弱”的,這種強弱可以用“粒度”來表示,Spring AOP支持到方法級的連接點粒度。

     切入點(pointcut): 切入點是連接點的集合,它通常和裝備聯系在一起,是切面和程序流程的交叉點。比如說,定義了一個pointcut,它將拋出異常ClassNotFoundException和某個裝備聯系起來,那么在程序執行過程中,如果拋出了該異常,那么相應的裝備就會被觸發執行。

     裝備(advice): 也可以叫做“通知”,指切面在程序運行到某個連接點所觸發的動作。在這個動作種我們可以定義自己的處理邏輯。裝備需要利用切入點和連接點聯系起來才會被觸 發。目前AOP定義了五種裝備:前置裝備(Before advice)、后置裝備(After advice)、環繞裝備(Around Advice)、異常裝備(After throwing advice)、返回后裝備(After returning advice)。這些裝備以后會逐一介紹。

    目標對象(target object): 被一個或者多個切面裝備的對象。所以它有時候也被稱為Advised Object。

    引入(introduction): 聲明額外的成員字段或者成員方法。它可以給一個確定的對象新增某些字段或者方法。

     織入(weaving): 將切面和目標對象聯系在一起的過程。這個過程可以在編譯期完成,也可以在類加載時和運行時完成。Spring AOP是在運行期完成織入的。

     切面(aspect): 一個關注點的模塊化。它實際上是一段將被織入到程序流程中的一段代碼。

  (1)AOP面向方面編程基於IoC,是對OOP的有益補充;

  (2)AOP利用一種稱為“橫切”的技術,剖解開封裝的對象內部,並將那些影響了多個類的公共行為封裝到一個可重用模塊,並將其名為“Aspect”,即方面。所謂“方面”,簡單地說,就是將那些與業務無關,卻為業務模塊所共同調用的邏輯或責任封裝起來,比如日志記錄,便於減少系統的重復代碼,降低模塊間的耦合度,並有利於未來的可操作性和可維護性。

  (3)AOP代表的是一個橫向的關系,將“對象”比作一個空心的圓柱體,其中封裝的是對象的屬性和行為;則面向方面編程的方法,就是將這個圓柱體以切面形式剖開,選擇性的提供業務邏輯。而剖開的切面,也就是所謂的“方面”了。然后它又以巧奪天功的妙手將這些剖開的切面復原,不留痕跡,但完成了效果。

  (4)實現AOP的技術,主要分為兩大類:一是采用動態代理技術,利用截取消息的方式,對該消息進行裝飾,以取代原有對象行為的執行;二是采用靜態織入的方式,引入特定的語法創建“方面”,從而使得編譯器可以在編譯期間織入有關“方面”的代碼。

  (5)Spring實現AOP:JDK動態代理和CGLIB代理

     JDK動態代理:其代理對象必須是某個接口的實現,它是通過在運行期間創建一個接口的實現類來完成對目標對象的代理;其核心的兩個類是InvocationHandler和Proxy。

     CGLIB代理:實現原理類似於JDK動態代理,只是它在運行期間生成的代理對象是針對目標類擴展的子類。CGLIB是高效的代碼生成包,底層是依靠ASM(開源的java字節碼編輯類庫)操作字節碼實現的,性能比JDK強;需要引入包asm.jar和cglib.jar。

    使用AspectJ注入式切面和@AspectJ注解驅動的切面實際上底層也是通過動態代理實現的。

  (6)AOP使用場景:             

        Authentication 權限檢查

        Caching 緩存

        Context passing 內容傳遞

        Error handling 錯誤處理

        Lazy loading 延遲加載

        Debugging  調試

        logging, tracing, profiling and monitoring 日志記錄,跟蹤,優化,校准

        Performance optimization 性能優化,效率檢查

        Persistence  持久化

        Resource pooling 資源池

        Synchronization 同步

        Transactions 事務管理

   另外Filter的實現和struts2的攔截器的實現都是AOP思想的體現。

 

總結:

 (1)spring有以下的優點:     

  1.降低了組件之間的耦合性 ,實現了軟件各層之間的解耦 

  2.可以使用容易提供的眾多服務,如事務管理,消息服務等

  3.容器提供單例模式支持

  4.容器提供了AOP技術,利用它很容易實現如權限攔截,運行期監控等功能

  5.容器提供了眾多的輔助類,能加快應用的開發

  6.spring對於主流的應用框架提供了集成支持,如hibernate,JPA,Struts等

  7.spring屬於低侵入式設計,代碼的污染極低

  8.獨立於各種應用服務器

  9.spring的DI機制降低了業務對象替換的復雜性

  10.Spring的高度開放性,並不強制應用完全依賴於Spring,開發者可以自由選擇spring的部分或全部

 (2)AOP可以動態的添加或者刪除在切面上的邏輯而不影響原來代碼的執行,體現了源代碼無關性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM