java設計最佳化之代理模式_java

來源:互聯網
上載者:User

代理模式使用代理對象完成使用者的請求,屏蔽使用者對真實對象的訪問。

代理模式的用途很多,比如因為安全原因,需要屏蔽用戶端直接存取真實對象;或者在遠程調用中,需要使用代理對象處理遠程方法中的技術細節;或者為了提升系統,對真是對象進行封裝,從而達到消極式載入的目的。

在系統啟動時,將消耗資源最多的方法使用代理模式分離,就可以加快系統的啟動速度,減少使用者的等待時間。在使用者真正在做查詢是,再由代理類載入真實的類,完成使用者請求。這就是使用代理模式達到消極式載入的目的。

1.靜態代理實現:

主題介面:

public interface IDBQuery {   String request(); }

真實主題:

public class DBQuery implements IDBQuery {  public DBQuery(){    try {      Thread.sleep(10000);    } catch (Exception e) {      e.printStackTrace();    }  }  public String request() {    return "string request";  }}

代理類:

public class IDBQueryProxy implements IDBQuery {  private DBQuery dbquery;   public String request() {    if(dbquery==null)      dbquery = new DBQuery();    return dbquery.request();  }}

最後,主函數:

public class ProxyText {  public static void main(String[] args) {    IDBQuery dbquery = new IDBQueryProxy();    System.out.println(dbquery.request());   }}

靜態代理注意,代理類是真實類實現共同的介面,並且代理類引用真實類對象,將耗時操作放在代理類方法中實現。

動態代理:

動態代理即運行時,動態組建代理程式類。即:代理類的位元組碼在運行時產生並載入當前的classloader。與靜態代理相比,動態代理不需要為真實注意封裝一個形式上完全一樣的封裝類,假如主題介面很多,就要為每一個介面寫一個代理方法是很煩人的,如果介面有變動,真實類和代理類都需要變化,這樣不利於系統維護;其次,使用一些動態代理的產生方法甚至可以在運行是指定代理類的執行邏輯,從而大大提高的系統的靈活性。

主題介面:

public interface IDBQuery {   String request(); }

jdk代理類:

public class JdbDbqueryHandler implements InvocationHandler{  IDBQuery idbquery = null;  @Override  public Object invoke(Object proxy, Method method, Object[] args)      throws Throwable {    if(idbquery==null){      idbquery = new DBQuery();    }    return idbquery.request();  }  public static IDBQuery createJdbProxy(){    IDBQuery jdkProxy = (IDBQuery) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),        new Class[]{IDBQuery.class}, new JdbDbqueryHandler());    System.out.println("JdbDbqueryHandler.createJdbProxy()");    return jdkProxy;  }}

主函數:

public class ProxyText {  public static void main(String[] args) {    IDBQuery idbQuery = JdbDbqueryHandler.createJdbProxy();    System.out.println(idbQuery.request());  }}

另外,也可以使用CGLIB和javassist動態代理與jdk動態代理類似,但是jdk動態類的建立過程最快,因為這個內建實現的difineclass()方法被定義為native實現,故效能優於其他。在代理類的函數調用上,JDK的動態代理不如CGLIB和javassist動態代理,而javassist動態代理效能品質最差,甚至不如JDK的實現。在實際開發應用中,代理類的方法調用頻率要遠遠高於代理類的實際產生頻率,故動態代理的方法調用效能應該成為效能的關注點。JDK動態代理強制要求代理類和真是主題實現統一介面,CGLIB和javassist動態代理沒有這樣的要求。

在java中,動態代理的實現涉及到classloader的使用,以CGLIB為例,簡要描述下動態類的載入過程。使用CGLIB產生動態代理,首先需要產生Enhancer類的執行個體,並制定用於處理代理業務的回調類。在enhancer.create()方法中,會使用DefaultGeneratorStrategy.Generate()方法組建代理程式類的位元組碼,並儲存在byte數組中。接著調用reflectUtils.defineClass()方法,通過反射,調用ClassLoader.defineClass()方法,將位元組碼裝載到classloader中,完成類的載入。最後,通過reflectUtils.newInstance()方法,通過反射產生動態類執行個體,並返回該執行個體。其他與該過程細節不同,但是產生邏輯相同。

以上就是本文的全部內容,希望對大家的學習有所協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.