<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    鷹翔宇空

    學習和生活

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      110 Posts :: 141 Stories :: 315 Comments :: 1 Trackbacks
    引自:http://www.3doing.net/forums/dispbbs.asp?boardID=11&ID=138&page=1


    發貼心情?AOP研究

    為什么要區分J2EE容器和J2EE應用系統?

      我們知道,J2EE應用系統只有部署在J2EE容器中才能運行,那么為什么劃分為J2EE容器和J2EE應用系統? 通過對J2EE容器運行機制的分析(見我的電子教材“EJB實用原理”),我們可以發現:實際上J2EE容器分離了一般應用系統的一些通用功能,例如事務機制、安全機制以及對象池或線程池等性能優化機制。

      這些功能機制是每個應用系統幾乎都需要的,因此可以從具體應用系統中分離出來,形成一個通用的框架平臺,而且,這些功能機制的設計開發有一定難度,同時運行的穩定性和快速性都非常重要,必須經過長時間調試和運行經驗積累而成,因此,形成了專門的J2EE容器服務器產品,如Tomcat JBoss、Websphere、WebLogic等。

      從J2EE系統劃分為J2EE容器和J2EE應用系統兩個方面,我們已經看到一種分散關注的思路(separation of concerns)。

    分散關注

      將通用需求功能從不相關類之中分離出來;同時,能夠使得很多類共享一個行為,一旦行為發生變化,不必修改很多類,只要修改這個行為就可以。

       AOP就是這種實現分散關注的編程方法,它將“關注”封裝在“方面”中。

    AOP是什么?

      AOP是OOP的延續,是Aspect Oriented Programming的縮寫,意思是面向方面編程。AOP實際是GoF設計模式的延續,設計模式孜孜不倦追求的是調用者和被調用者之間的解耦,AOP可以說也是這種目標的一種實現。

      舉例:假設有在一個應用系統中,有一個共享的數據必須被并發同時訪問,首先,將這個數據封裝在數據對象中,稱為Data Class,同時,將有多個訪問類,專門用于在同一時刻訪問這同一個數據對象。

      為了完成上述并發訪問同一資源的功能,需要引入鎖Lock的概念,也就是說,某個時刻,當有一個訪問類訪問這個數據對象時,這個數據對象必須上鎖Locked,用完后就立即解鎖unLocked,再供其它訪問類訪問。

      使用傳統的編程習慣,我們會創建一個抽象類,所有的訪問類繼承這個抽象父類,如下:

    abstract class Worker{

      abstract void locked();
      abstract void accessDataObject();
      abstract void unlocked();

    }


      缺點:


    • accessDataObject()方法需要有“鎖”狀態之類的相關代碼。


    • Java只提供了單繼承,因此具體訪問類只能繼承這個父類,如果具體訪問類還要繼承其它父類,比如另外一個如Worker的父類,將無法方便實現。


    • 重用被打折扣,具體訪問類因為也包含“鎖”狀態之類的相關代碼,只能被重用在相關有“鎖”的場合,重用范圍很窄。

      仔細研究這個應用的“鎖”,它其實有下列特性:


    • “鎖”功能不是具體訪問類的首要或主要功能,訪問類主要功能是訪問數據對象,例如讀取數據或更改動作。


    • “鎖”行為其實是和具體訪問類的主要功能可以獨立、區分開來的。


    • “鎖”功能其實是這個系統的一個縱向切面,涉及許多類、許多類的方法。如下圖:

      因此,一個新的程序結構應該是關注系統的縱向切面,例如這個應用的“鎖”功能,這個新的程序結構就是aspect(方面)

      在這個應用中,“鎖”方面(aspect)應該有以下職責:

      提供一些必備的功能,對被訪問對象實現加鎖或解鎖功能。以保證所有在修改數據對象的操作之前能夠調用lock()加鎖,在它使用完成后,調用unlock()解鎖。

    AOP應用范圍

      很明顯,AOP非常適合開發J2EE容器服務器,目前JBoss 4.0正是使用AOP框架進行開發。
      具體功能如下:
    Authentication 權限
    Caching 緩存
    Context passing 內容傳遞
    Error handling 錯誤處理
    Lazy loading 懶加載
    Debugging  調試
    logging, tracing, profiling and monitoring 記錄跟蹤 優化 校準
    Performance optimization 性能優化
    Persistence  持久化
    Resource pooling 資源池
    Synchronization 同步
    Transactions 事務

    AOP有必要嗎?

      當然,上述應用范例在沒有使用AOP情況下,也得到了解決,例如JBoss 3.XXX也提供了上述應用功能,但是沒有使用AOP。

      但是,使用AOP可以讓我們從一個更高的抽象概念來理解軟件系統,AOP也許提供一種有價值的工具。可以這么說:因為使用AOP結構,現在JBoss 4.0的源碼要比JBoss 3.X容易理解多了,這對于一個大型復雜系統來說是非常重要的。

      從另外一個方面說,好像不是所有的人都需要關心AOP,它可能是一種架構設計的選擇,如果選擇J2EE系統,AOP關注的上述通用方面都已經被J2EE容器實現了,J2EE應用系統開發者可能需要更多地關注行業應用方面aspect。

    AOP具體實現

      AOP是一個概念,并沒有設定具體語言的實現,它能克服那些只有單繼承特性語言的缺點(如Java),目前AOP具體實現有以下幾個項目:

      AspectJ (TM): 創建于Xerox PARC. 有近十年歷史,成熟
      缺點:過于復雜;破壞封裝;需要專門的Java編譯器。

      動態AOP:使用JDK的動態代理API或字節碼Bytecode處理技術。

     動態AOP:使用JDK的動態代理API或字節碼Bytecode處理技術。

      基于動態代理API的具體項目有:
      JBoss 4.0 JBoss 4.0服務器
      nanning 這是以中國南寧命名的一個項目,搞不清楚為什么和中國相關?是中國人發起的?

      基于字節碼的項目有:
      aspectwerkz 
      spring 
    在以后其它文章中,我將繼續對AOP概念進行分析,和大家一起學習進步。

    發貼心情?

    AOP和AspectJ

    板橋里人http://www.jdon.com 2004/01/10

    需求和問題

      以上篇《AOP是什么》中并發訪問應用為例子:

      多個訪問類同時訪問一個共享數據對象時,每個訪問類在訪問這個數據對象時,需要將數據對象上鎖,訪問完成后,再實行解鎖,供其它并發線程訪問,這是我們處理并發訪問資源的方式。

      為了實現這個需求,先實現傳統的編程,這里我們假定有一個寫鎖,對數據對象實行寫之前,首先對這個對象進行上寫鎖,寫操作完畢后,必須釋放寫鎖。

      首先,我們需要一個鎖,這個鎖可以是數據對象中一個字段或其它,這里使用Doug Lea的ReentrantWriterPreferenceReadWriteLock作為我們的鎖資源。

    import EDU.oswego.cs.dl.util.concurrent.*;

    public class Worker extends Thread {

      Data data;

      ReentrantWriterPreferenceReadWriteLock rwl = 
        new ReentrantWriterPreferenceReadWriteLock();

      public boolean createData() {
       try {
        rwl.writeLock().acquire(); //上鎖

        //對data實行寫邏輯操作 
           
       }catch() {
         return false;
       }finally{
         rwl.writeLock().release();  //解鎖
       }
       return true;
      }

      public boolean updateData() {
       try {
        rwl.writeLock().acquire();//上鎖

        //對data實行寫邏輯操作 
           
       }catch() {
         return false;
       }finally{
         rwl.writeLock().release(); //解鎖
       }
       return true;
      }

      public void run() {
        //執行createData()或updateData()
      }
    }

    假設可能存在另外一個訪問類,也將對數據對象實現寫操作,代碼如下:

    import EDU.oswego.cs.dl.util.concurrent.*;

    public class AnotherWorker extends Thread {

      Data data;

      ReentrantWriterPreferenceReadWriteLock rwl = 
        new ReentrantWriterPreferenceReadWriteLock();
      
      public boolean updateData() {
       try {
        rwl.writeLock().acquire();//上鎖

        //對data實行寫邏輯操作 
           
       }catch() {
         return false;
       }finally{
         rwl.writeLock().release(); //解鎖
       }
       return true;
      }

      public void run() {
        //執行updateData()
      }
    }

      以上是Java傳統編程的實現,這種鎖的實現方式是在每個具體類中實現,如下圖:

    這種實現方式的缺點很多:

    • 冗余:有很多重復的編碼,如rwl.writeLock().acquire()等;
    • 減少重用:worker的updateData()方法重用性幾乎為零。
    • "數據對象寫操作必須使用鎖控制這個設計目的"不容易顯現,如果更換了一個新的程序員,他可能編寫一段不使用鎖機制就對這個數據對象寫操作的代碼。
    • 如果上述代碼有讀功能,那么我們需要在代碼中實現先上讀鎖,當需要寫時,解讀鎖,再上寫鎖等等,如果稍微不小心,上鎖解鎖次序搞錯,系統就隱含大的BUG,這種可能性會隨著這個數據對象永遠存在下去,系統設計大大的隱患啊!

      那么我們使用AOP概念來重新實現上述需求,AOP并沒有什么新花招,只是提供了觀察問題的一個新視角度。

      這里我們可以拋開新技術迷人霧障,真正核心還是新思維、新視點,人類很多問題如果換一個腦筋看待理解,也許結果真的是翻天覆地不一樣啊,所以,作為人自身,首先要重視和你世界觀和思維方式不一樣的人進行交流和溝通。

      現實生活中有很多"不公平",例如某個小學畢業生成了千萬富翁,你就懷疑知識無用,也許你認為他的機會好,其實你可能不知道,他的觀察問題的視角比你獨特,或者他可能會經常換不同的角度來看待問題和解決問題,而你由于過分陷入一個視角的具體實現細節中,迷失了真正的方向,要不說是讀書人腦子僵化呢?

      言歸正傳,我們看看AOP是如何從一個新的視角解決上述問題的。

      如果說上面代碼在每個類中實現上鎖或解鎖,類似橫向解決方式,那么AOP是從縱向方面來解決上述問題,縱向解決之道示意圖如下:

      AOP把這個縱向切面cross-cuts稱為Aspect(方面),其實我認為AOP翻譯成面向切面編程比較好,不知哪個糊涂者因為先行一步,翻譯成“面向方面編程”如此抽象,故弄玄虛。

    AspectJ實現

      下面我們使用AOP的實現之一AspectJ來對上述需求改寫。AspectJ是AOP最早成熟的Java實現,它稍微擴展了一下Java語言,增加了一些Keyword等,pointcut的語法如下:

    public pointcut 方法名:call(XXXX)

      AspectJ增加了pointcut, call是pointcut類型,有關AspectJ更多基本語法見這里。因為AspectJ使用了一些特別語法,所以Java編譯器就不能用SUN公司提供javac了,必須使用其專門的編譯器,也許SUN在以后JDK版本中會引入AOP。

      使用AspectJ如何實現上圖所謂切面式的編程呢?首先,我們將上圖縱向切面稱為Aspect,那么我們建立一個類似Class的Aspect,Java中建立一個Class代碼如下:

    public class MyClass{
      //屬性和方法 ...
    }

      同樣,建立一個Aspect的代碼如下:

    public aspect MyAspect{
      //屬性和方法 ...
    }

    建立一個Aspect名為Lock,代碼如下:

    import EDU.oswego.cs.dl.util.concurrent.*;

    public aspect Lock {

      ......
      ReentrantWriterPreferenceReadWriteLock rwl = 
        new ReentrantWriterPreferenceReadWriteLock();

      public pointcutwriteOperations():
        execution(public boolean Worker.createData()) ||
        execution(public boolean Worker.updateData()) ||
        execution(public boolean AnotherWorker.updateData()) ;


      before() : writeOperations() {
        rwl.writeLock().acquire();//上鎖 advice body
      }

      after() : writeOperations() {
         rwl.writeLock().release(); //解鎖 advice body
      }

      ......
    }

      上述代碼關鍵點是pointcut,意味切入點或觸發點,那么在那些條件下該點會觸發呢?是后面紅字標識的一些情況,在執行Worker的createData()方法,Worker的update方法等時觸發。

      before代表觸發之前做什么事情?
      答案是上鎖。

      after代表觸發之后做什么事情?
      答案是上鎖。

      通過引入上述aspect,那么Worker代碼可以清潔如下:

    public class Worker extends Thread {

      Data data;

      public boolean createData() {
       try {
        //對data實行寫邏輯操作        
       }catch() {
         return false;
       }
       return true;
      }

      public boolean updateData() {
       try {
        //對data實行寫邏輯操作        
       }catch() {
         return false;
       }finally{
       }
       return true;
      }

      public void run() {
        //執行createData()或updateData()
      }
    }

      Worker中關于“鎖”的代碼都不見了,純粹變成了數據操作的主要方法。

    AOP術語

      通過上例已經知道AspectJ如何從切面crosscutting來解決并發訪問應用需求的,其中最重要的是引入了一套類似事件觸發機制。

      Pointcut類似觸發器,是事件Event發生源,一旦pointcut被觸發,將會產生相應的動作Action,這部分Action稱為Advice。

      Advice在AspectJ有三種:before、 after、Around之分,上述aspect Lock代碼中使用了Advice的兩種before和after。

      所以AOP有兩個基本的術語:Pointcut和Advice。你可以用事件機制的Event和Action來類比理解它們。上述并發訪問應用中pointcut和advice如下圖所示:

    小結如下:
    advice - 真正的執行代碼,或者說關注的實現。 類似Action。
    join point - 代碼中激活advice被執行的觸發點。
    pointcut - 一系列的join point稱為pointcut,pointcut有時代指join point

    其中advice部分又有:
    Interceptor - 解釋器并沒有在AspectJ出現,在使用JDK動態代理API實現的AOP框架中使用,解釋有方法調用或對象構造或者字段訪問等事件,是調用者和被調用者之間的紐帶,綜合了Decorator/代理模式甚至職責鏈等模式。

    Introduction - 修改一個類,以增加字段、方法或構造或者執行新的接口,包括Mixin實現。

    例如上述并發訪問應用中,如果想為每個Data對象生成相應的aspect Lock,那么可以在aspect Lock中人為數據對象增加一個字段lock,如下:

    aspect Lock {

      Data sharedDataInstance;
      Lock( Data d ) {
         sharedDataInstance = d;
      }

      introduce Lock Data.lock; //修改Data類,增加一字段lock

      advise Data() { //Data構造時觸發
         static after {
           //當Data對象生成時,將Data中lock字段賦值為aspect Lock
           //為每個Data對象生成相應的aspect Lock
           thisObject.lock = new Lock( thisObject );
         }
       }
      ....

    }

    上述代碼等于在Data類中加入一行:

    public class Data{
      ......
      Lock lock = new Lock();
      ......
    }

    還有其它兩個涉及AOP代碼運行方式:

    weaving - 將aspect代碼插入到相應代碼中的過程,一般是編譯完成或在運行時動態完成。取決于具體AOP產品,例如AspectJ是使用特殊編譯器在編譯完成weaving,而nanning、JBoss AOP是使用動態代理API,因此在運行時動態完成weaving的。
    instrumentor - 用來實現weaving功能的工具。

    發貼心情?

    AOP與權限控制實現

    板橋里人http://www.jdon.com 2004/01/10

      以往在J2EE系統中,訪問權限控制系統的實現主要有兩種:應用程序實現和J2EE容器實現。

    傳統的應用程序實現

      這是最直接的、傳統的一種解決方式,通常是在具體方法前加一個權限判斷語句,如下:

    public class ForumFactoryProxy extends ForumFactory {
      ......
      public Forum createForum(String name, String description)
        throws UnauthorizedException, ForumAlreadyExistsException
      {
        if (permissions.get(ForumPermissions.SYSTEM_ADMIN)) {
          Forum newForum = factory.createForum(name, description);
          return new ForumProxy(newForum, authorization, permissions);
        }else {
          throw new UnauthorizedException();
        }
      }
      ......
    }

      上述代碼是Jive論壇中一段創建論壇功能的代碼,在創建論壇前,首先進行權限角色檢驗,如果當前用戶是系統管理員,那么可以實現真正的創建。

      這種在具體功能前加入權限操作檢驗的實現方式有很多缺點:
      1.每個功能類都需要相應的權限檢驗代碼,將程序功能和權限檢驗混淆在一起,存在緊密的耦合性,擴展修改難度大。
      2.如果類似Jive,以代理模式為每個功能類實現一個相應的代理類,雖然解耦了程序功能和權限檢驗,但是,從某個角色的權限檢驗這個切面考慮,涉及具體Proxy類太多,擴展修改難度大。

    J2EE容器實現

      在AOP概念沒有誕生前,J2EE規范已經提供了關于權限控制的容器實現標準,這種變遷結果如下圖所示:

      原來需要每個應用程序實現的權限Proxy轉為整個容器的Proxy實現,其中JDK1.3以后的動態代理API為這種轉換實現提供了技術保證。

      非常明顯,通過容器實現權限控制驗證可以大大簡化應用程序的設計,分離了應用系統的權限關注,將權限控制變成了對J2EE容器服務器的配置工作,具體技術細節參考我的書籍《Java實用系統開發指南》第六章。

      其實,容器的權限實現也是一種從一個切面來解決問題方式,AOP概念誕生后,權限控制實現由此也帶來了兩個方向的變化:
      1. J2EE容器級別的權限實現,也就是容器自身的權限實現。
      2. J2EE應用程序級別的權限實現。

      權限控制在容器級別實現似乎使得J2EE開發者感覺沒有靈活性和可擴展性,其實象JBoss 4.0這樣的J2EE容器,由于引入了AOP概念,使得J2EE開發者在自己的應用系統中能夠直接操縱容器的一些行為。容器和應用系統由于AOP引入的Aspect切面,變得可以成為一體了。(如果使用BEA的EJBC編輯要浪費多少時間?)

      對于J2EE應用系統開發者,能夠做到上述境界,必須的條件是對JBoss之類J2EE容器必須有足夠的了解,因為這些方式并不是J2EE標準,有可能在移植到新的J2EE容器,這些知識和投入變得無用(也有可能將來J2EE擴展其標準)。

      很顯然,使用AOP實現J2EE應用系統級別的權限控制,是解決上述移植風險的一個主要方法,但是帶來的缺點是必須親自從零開始做起,耗費時間不會很短。

    AOP下的應用程序權限控制實現

      引入AOP概念后的權限實現已經不是前面Jive實例那樣“落后”,我們對這個實例進行重整(Refactorying)如下:

    創建一個Aspect,專門用于權限檢查,如下:

    private static aspect PermissionCheckAspect {

      private pointcut permissionCheckedExecution() :
       execution ( public Forum ForumFactory.createForum(String , String ));

      before () : permissionCheckedExecution() {
        if !(permissions.get(ForumPermissions.SYSTEM_ADMIN)) {
          throw new UnauthorizedException();
        }
       }

    }

    該段代碼功能是:當系統運行ForumFactory.createForum方法之前,將首先檢查是否有權限操作。

    代碼中pointcut觸發的條件是createForum方法執行,如果有其它需要系統管理員身份才能執行的方法加入,將寫成如下代碼:

    private pointcut permissionCheckedExecution() :
       execution ( public Forum ForumFactory.createForum(String , String )) ||
       execution ( public Forum ForumFactory.deleteForum(String , String )) ||
       ......
       execution ( public Forum ForumFactory.deleteThread(String , String ));

    這些方法陳列比較瑣碎,依據AspectJ語法,可以簡化如下:
    private pointcut permissionCheckedExecution() :
       execution ( public * ForumFactory .*(..));

    有興趣者可以將Jive論壇中相關權限Proxy部分使用AOP重整,另外,由于Jive沒有引入角色概念,導致權限和用戶HardCode在編碼中,如何實現權限和用戶解耦,最小限度的降低HardCode量,角色概念在其中起著不可忽視的重要作用。這是另外一個研究課題了。

    發貼心情?

    Ioc模式

    板橋里人http://www.jdon.com 2004/01/31

      分離關注( Separation of Concerns : SOC)是Ioc模式和AOP產生最原始動力,通過功能分解可得到關注點,這些關注可以是 組件Components, 方面Aspects或服務Services。

      從GoF設計模式中,我們已經習慣一種思維編程方式:Interface Driven Design 接口驅動,接口驅動有很多好處,可以提供不同靈活的子類實現,增加代碼穩定和健壯性等等,但是接口一定是需要實現的,也就是如下語句遲早要執行:

      AInterface a = new AInterfaceImp();

      AInterfaceImp是接口AInterface的一個子類,Ioc模式可以延緩接口的實現,根據需要實現,有個比喻:接口如同空的模型套,在必要時,需要向模型套注射石膏,這樣才能成為一個模型實體,因此,我們將人為控制接口的實現成為“注射”。

      Ioc英文為 Inversion of Control,即反轉模式,這里有著名的好萊塢理論:你呆著別動,到時我會找你。

      其實Ioc模式也是解決調用者和被調用者之間的一種關系,上述AInterface實現語句表明當前是在調用被調用者AInterfaceImp,由于被調用者名稱寫入了調用者的代碼中,這產生了一個接口實現的原罪:彼此聯系,調用者和被調用者有緊密聯系,在UML中是用依賴 Dependency 表示。

      但是這種依賴在分離關注的思維下是不可忍耐的,必須切割,實現調用者和被調用者解耦,新的Ioc模式 Dependency Injection 模式由此產生了, Dependency Injection模式是依賴注射的意思,也就是將依賴先剝離,然后在適當時候再注射進入。

    Ioc模式(Dependency Injection模式)有三種:

    第一種類型從JNDI或ServiceManager等獲得被調用者,這里類似ServiceLocator模式。1. EJB/J2EE
    2. Avalon(Apache的一個復雜使用不多的項目)
    第二種類型使用JavaBeans的setter方法1. Spring Framework,
    2. WebWork/XWork
    第三種類型在構造方法中實現依賴1. PicoContainer,
    2. HiveMind

      有過EJB開發經驗的人都知道,每個EJB的調用都需要通過JNDI尋找到工廠性質的Home接口,在我的教程EJB是什么章節中,我也是從依賴和工廠模式角度來闡述EJB的使用。

      在通常傳統情況下,為了實現調用者和被調用者解耦,分離,一般是通過工廠模式實現的,下面將通過比較工廠模式和Ioc模式不同,加深理解Ioc模式。

    工廠模式和Ioc

      假設有兩個類B 和 C:B作為調用者,C是被調用者,在B代碼中存在對C的調用:

    public class B{
       private C comp;
      ......
    }

      實現comp實例有兩種途徑:單態工廠模式和Ioc。

    工廠模式實現如下:

    public class B{
       private C comp;
      private final static MyFactory myFactory = MyFactory.getInstance();

      public B(){
        this.comp = myFactory.createInstanceOfC();

      }
       public void someMethod(){
        this.comp.sayHello();
      }
      ......
    }

    特點:

    • 每次運行時,MyFactory可根據配置文件XML中定義的C子類實現,通過createInstanceOfC()生成C的具體實例。

    使用Ioc依賴性注射( Dependency Injection )實現Picocontainer如下,B類如同通常POJO類,如下:

    public class B{
       private C comp;
      public B(C comp){
        this.comp = comp;
       }
       public void someMethod(){
        this.comp.sayHello();
       }
      ......
    }

    假設C接口/類有有一個具體實現CImp類。當客戶端調用B時,使用下列代碼:

    public class client{
       public static void main( String[] args ) {
        DefaultPicoContainer container = new DefaultPicoContainer();
        container.registerComponentImplementation(CImp.class);
        container.registerComponentImplementation(B.class);
        B b = (B) container.getComponentInstance(B.class);
        b.someMethod();
       }
    }

      因此,當客戶端調用B時,分別使用工廠模式和Ioc有不同的特點和區別:

      主要區別體現在B類的代碼,如果使用Ioc,在B類代碼中將不需要嵌入任何工廠模式等的代碼,因為這些工廠模式其實還是與C有些間接的聯系,這樣,使用Ioc徹底解耦了B和C之間的聯系。

      使用Ioc帶來的代價是:需要在客戶端或其它某處進行B和C之間聯系的組裝。

      所以,Ioc并沒有消除B和C之間這樣的聯系,只是轉移了這種聯系。
      這種聯系轉移實際也是一種分離關注,它的影響巨大,它提供了AOP實現的可能。

    Ioc和AOP

      AOP我們已經知道是一種面向切面的編程方式,由于Ioc解放自由了B類,而且可以向B類實現注射C類具體實現,如果把B類想像成運行時的橫向動作,無疑注入C類子類就是AOP中的一種Advice,如下圖:

      通過下列代碼說明如何使用Picocontainer實現AOP,該例程主要實現是記錄logger功能,通過Picocontainer可以使用簡單一行,使所有的應用類的記錄功能激活。

    首先編制一個記錄接口:

    public interface Logging {

      public void enableLogging(Log log);

    }

    有一個LogSwitcher類,主要用來激活具體應用中的記錄功能:

    import org.apache.commons.logging.Log;
    public class LogSwitcher
    {
      protected Log m_log;
      public void enableLogging(Log log) {
        m_log = log;
        m_log.info("Logging Enabled");
      }
    }

    一般的普通應用JavaBeans都可以繼承這個類,假設PicoUserManager是一個用戶管理類,代碼如下:

    public class PicoUserManager extends LogSwitcher
    {

      ..... //用戶管理功能
    }
    public class PicoXXXX1Manager extends LogSwitcher
    {

      ..... //業務功能
    }
    public class PicoXXXX2Manager extends LogSwitcher
    {

      ..... //業務功能
    }

    注意LogSwitcher中Log實例是由外界賦予的,也就是說即將被外界注射進入,下面看看使用Picocontainer是如何注射Log的具體實例的。


    DefaultPicoContainer container = new DefaultPicoContainer();
    container.registerComponentImplementation(PicoUserManager.class);
    container.registerComponentImplementation(PicoXXXX1Manager.class);
    container.registerComponentImplementation(PicoXXXX2Manager.class);
    .....

    Logging logging = (Logging) container.getComponentMulticaster();

    logging.enableLogging(new SimpleLog("pico"));//激活log

      由上代碼可見,通過使用簡單一行logging.enableLogging()方法使所有的應用類的記錄功能激活。這是不是類似AOP的advice實現?

      總之,使用Ioc模式,可以不管將來具體實現,完全在一個抽象層次進行描述和技術架構,因此,Ioc模式可以為容器、框架之類的軟件實現提供了具體的實現手段,屬于架構技術中一種重要的模式應用。J道的JdonSD框架也使用了Ioc模式。




    posted on 2006-06-01 09:42 TrampEagle 閱讀(468) 評論(0)  編輯  收藏 所屬分類: java
    主站蜘蛛池模板: 99精品视频免费观看| 少妇中文字幕乱码亚洲影视| 91久久青青草原线免费| 无码毛片一区二区三区视频免费播放| 1区1区3区4区产品亚洲| 国产成人精品亚洲精品| 色播在线永久免费视频| 色影音免费色资源| 国产精品免费观看调教网| 日本高清免费中文在线看| 亚洲精品无码久久久久A片苍井空| 亚洲影院在线观看| 国产亚洲精久久久久久无码AV| 日韩人妻无码免费视频一区二区三区 | 久久精品国产亚洲αv忘忧草| 丝袜熟女国偷自产中文字幕亚洲| 国产精品公开免费视频| 青春禁区视频在线观看直播免费 | 亚洲AV无码国产在丝袜线观看| 亚洲欧洲中文日韩av乱码| 国产精品无码素人福利免费| 男女超爽刺激视频免费播放| 日日麻批免费40分钟无码| 大地资源网高清在线观看免费| 一区二区三区免费电影| 无遮挡国产高潮视频免费观看| 国产亚洲综合精品一区二区三区| 亚洲人成电影网站色| 亚洲最大av资源站无码av网址| 亚洲人成人77777在线播放| 亚洲成aⅴ人片在线观| 亚洲欧洲国产精品久久| 亚洲综合色丁香麻豆| 亚洲成aⅴ人在线观看| 亚洲人成7777影视在线观看| 亚洲人成网站日本片| 亚洲乱码在线卡一卡二卡新区| 亚洲综合在线一区二区三区| 亚洲高清乱码午夜电影网| 国产亚洲综合久久| 中文字幕免费观看视频|