Proxy

參考鏈接:http://www.lxweimin.com/p/3ad3fb560ca1

首先看調用方式:
Subject realSubject = new RealSubject();
InvocationHandler handler = new DynamicProxyHandler(realSubject);
Subject subject = (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject
.getClass().getInterfaces(), handler);
通過Proxy的
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h);
函數中調用getProxyClass函數,動態生成一個RealSubject類相關的.Class類,newProxyInstance函數中將handler作為回調傳遞進去,里面調用Proxy類中的static的invoke回調出來也就是到RealSubject的invoke方法中,做一些額外的事情。

// 代理對象是可以序列化
public class Proxy implements Serializable {
一、定義的變量:
1、private static final long serialVersionUID = -2222568056686623797L;
serialVersionUID的作用:
通過判斷實體類的serialVersionUID來驗證版本一致性的。在進行反序列化時,JVM會把傳來的字節流中的serialVersionUID與本地相應實體類的serialVersionUID進行比較,如果相同就認為是一致的,可以進行反序列化,否則就會出現序列化版本不一致的異常。
生成實體類的serialVersionUID方法:1、寫上默認的1L,比如:private static final long serialVersionUID = 1L; 2、用idea自動生成。

// maps class loaders to created classes by interface names
/** 將代理類 加載器放在Proxy的maps結構中緩存起來 */
2、private static final Map<ClassLoader, Map<String, WeakReference<Class<?>>>> loaderCache = new WeakHashMap<ClassLoader, Map<String, WeakReference<Class<?>>>>();

/** 所有代理類的集合,用于isProxyClass方法的實現 */
3、private static final Map<Class<?>, String> proxyCache = new WeakHashMap<Class<?>, String>();

4、private static int NextClassNameIndex = 0;///** 下一個用于生成唯一代理類名字的數字 */

/**
 * The invocation handler on which the method calls are dispatched.
 * 代理實例的invocationHandler對象
 */

5、protected InvocationHandler h;

二:定義的方法:
作用類實現了InvocationHandler接口的代理類,其中主要方法有:
private Proxy() {} ("unused") //禁止實例化
protected Proxy(InvocationHandler h):構造方法,用于給內部的h賦值。

static Class getProxyClass(ClassLoader loader, Class[] interfaces):獲得一個動態代理類的Class對象。,其中loader是類裝載器,interfaces是真實類所擁有的全部接口的數組。 從緩存中取,如果沒有,則調用本地方法generateProxy(name, interfaces, loader, methodsArray, exceptionsArray);注意其中的幾個參數。

static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理類的一個實例,返回后的代理類可以當作被代理類使用。
InvocationHandler.invoke的第一個參數proxy值,是newProxyInstance返回的動態代理類的實例,不是被代理的實例(下方的demo輸出的className證明了這一點)。
動態代理類Proxy是結合java底層實現的,通過純粹的java代碼實現比較困難。
需要java動態生成類的支持。

根據class在Map 中查找是否是代理類
public static boolean isProxyClass(Class<?> cl) {}

返回指定代理實例的調用處理程序。
public static InvocationHandler getInvocationHandler(Object proxy) throws IllegalArgumentException {

兩個 native方法
native private static Class generateProxy(String name, Class[] interfaces,ClassLoader loader);

在生成代理類時,VM克隆該方法的描述符。沒有實現。
native private static void constructorPrototype(InvocationHandler h);

public static void main(String[] args) {
Subject realSubject = new RealSubject();
InvocationHandler handler = new DynamicProxyHandler(realSubject);
Subject subject = (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject
.getClass().getInterfaces(), handler);
System.out.println(subject.getClass().getName());
subject.rent();
subject.hello("world");
}
subject.getClass().getName()打印的值是:$Proxy0

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1 場景問題# 1.1 訪問多條數據## 考慮這樣一個實際應用:要一次性訪問多條數據。 這個功能的背景是這樣的;在...
    七寸知架構閱讀 3,038評論 1 52
  • 多年以前在學習設計模式時,一直以為代理就是這個事情我不做了,交給別人做。現在重學設計模式,才發現自己還是太天真,而...
    Mock2052閱讀 388評論 0 0
  • 版權聲明:本文為博主原創文章,未經博主允許不得轉載 PS:轉載請注明出處作者: TigerChain地址: htt...
    TigerChain閱讀 1,746評論 0 2
  • 記得剛工作那會,在異鄉聽不懂方言,回到出租房給有鄉音的人打電話,只要聽著就覺得被救贖了。 會喜歡加班,吃飯有人陪,...
    掉頁黃歷閱讀 220評論 1 4
  • 屋子里正在播放的音樂是電視劇《步步驚心》的主題曲《三寸天堂》,王軍對這首歌的印象很深刻,畢竟這部電視劇也算...
    君為客閱讀 637評論 0 0