談談java代理模式的認識二

來源:互聯網
上載者:User

標籤:java

 讓我們就接著上篇部落格的靜態代理來開始今天的動態代理。

一、動態代理

             靜態代理需要在運行之前就寫好代理類,這樣就造成了代碼的大量重複,所以我們通過動態代理在運行時期動態產生業務類的代理類,那麼動態代理類是如何?的呢?

        動態代理類的位元組碼在程式運行時由Java反射機制動態產生,無需程式員手工編寫它的原始碼。動態代理類不僅簡化了編程工作,而且提高了軟體系統的可擴充性,因為Java 反射機制可以產生任意類型的動態代理類。java.lang.reflect 包中的Proxy類和InvocationHandler 介面提供了產生動態代理類的能力。 原來是利用反射的機制來實現的,今天我們不討論反射,我們看JDK的動態代理的實現。

      JDK動態代理中包含一個類和一個介面: InvocationHandler介面,和我們定義的一個實作類別“Proxy“,這是一個萬能的代理類,我們就是通過這個代理類來動態代理的。
      InvocationHandler介面: 
      public interface InvocationHandler { 
      public Object invoke(Object proxy,Method method,Object[] args) throws Throwable; 
      } 
      參數說明: 
           Object proxy:指被代理的對象。 
           Method method:要調用的方法 
          Object[] args:方法調用時所需要的參數 

      可以將InvocationHandler介面的子類想象成一個代理的最終操作類,替換掉ProxySubject。


      Proxy類: 
      Proxy類是專門完成代理的操作類,可以通過此類為一個或多個介面動態地產生實作類別,此類提供了如下的操作方法: 
     public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 
                               throws IllegalArgumentException 
      參數說明: 
           ClassLoader loader:類載入器 
          Class<?>[] interfaces:得到全部的介面 
          InvocationHandler h:得到InvocationHandler介面的子類執行個體 


     Ps:類載入器 
      在Proxy類中的newProxyInstance()方法中需要一個ClassLoader類的執行個體,ClassLoader實際上對應的是類載入器,在Java中主要有一下三種類載入器; 
      Booststrap ClassLoader:此載入器採用C++編寫,一般開發中是看不到的; 
      Extendsion ClassLoader:用來進行擴充類的載入,一般對應的是jre\lib\ext目錄中的類; 
      AppClassLoader:(預設)載入classpath指定的類,是最常使用的是一種載入器。
二、使用JDK的動態代理

      還是使用上篇部落格的代碼,我們也是簡單的說三步來實現:業務介面,業務實作類別的建立;代理類的建立,業務的調用。

   我們看代碼實現:  

<span style="font-family:KaiTi_GB2312;font-size:18px;"> /**     * 定義一個業務介面       * @author Cassie       */        public interface Account {            // 查詢           public void queryAccount ();                // 修改            public void updateAccount ();          }          /**       * 介面實作類別(包含商務邏輯)       *  即:委託類      * @author Cassie        */        public class AccountImpl implements Account{                    @Override            public void queryAccount() {                System.out.println("查詢方法...");                  }                    @Override            public void updateAccount() {                System.out.println("修改方法...");                  }                }</span>
  

    關鍵的動態代理是如下幾行代碼:該處的代理類Proxy 不去實現具體的某個業務介面,而是實現了JDK提供的InvocationHander類。在Proxy中我們不需要知道具體的業務類,即委託類,在運行之前,講委託類和代理類進行解耦,在運行期才發生的聯絡,是通過這句話實現的:private object target。然後在調用的時候通過getInstance 在確定誰是委派物件。

  

<span style="font-family:KaiTi_GB2312;font-size:18px;">/**  * JDK動態代理代理類  *   * @author Cassie *   */  public class Proxy implements InvocationHandler {      private Object target;      /**      * 綁定委派物件並返回一個代理類      * @param target      * @return      */      public Object GetInstance(Object target) {          this.target = target;          //取得代理對象          return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);       }        @Override      /**      * 調用方法      */      public Object invoke(Object proxy, Method method, Object[] args)              throws Throwable {          Object result=null;          System.out.println("before");          //執行方法          result=method.invoke(target, args);          System.out.println("after");          return result;      }    } </span>

再看我們的用戶端調用:這時候才傳入真正的委託類。

<span style="font-family:KaiTi_GB2312;font-size:18px;">public class TestProxy {        public static void main(String[] args) {          Proxy proxy = new Proxy();  // 在這裡進行真正的對象傳入        Account account= (Account )proxy.getInstance(new AccountImpl());          proxy.queryAccount();      }    }</span>

以上過程就是JDK動態代理的實現,我們發現JDK動態代理幫我們講代理類和委託類的綁定關係延遲了,什麼時候用,什麼時候調,這樣我們的業務類不僅得到了增強,還簡化了代碼。

    當然,JDK的動態代理也有缺陷,不知道你發現了沒有,這裡的每個委託類都必須是要有介面的,也就是說JDK的動態代理依靠介面實現,要是我一個沒有介面的類想被代理怎麼辦?

    如果有些類並沒有實現介面,則不能使用JDK代理,這就要使用cglib動態代理了。請看下篇部落格。

  

   

談談java代理模式的認識二

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.