回覆列表
  • 1 # 珠鄉二哥

    有些年頭沒寫程式碼了,記憶中大概還能想起一些線索,翻出老程式碼看了一下,試著回答一下你的問題,大概的思路是這樣的。

    Java 在寫動態代理的時候一般步驟是這樣, 一般來說這三個東西必須有:

    import java.lang.reflect.InvocationHandler;

    import java.lang.reflect.Proxy;

    import java.lang.reflect.Method;

    第一步, 我們要定義一個介面,比方就叫做 DInterface, 簡單些就兩個方法:

    第二步我們要定義一個類來實現上面這個介面,這個類就是我們的真實物件,名字就叫RealObject類,簡單些:

    第三步,我們就要定義動態代理類了,並且每一個動態代理類都必須要實現 InvocationHandler 這個介面,這是死理,不能例外,就是透過這個東西來關聯。

    如果沒記錯這地方應該會輸出一個xxxProxy.$Proxy0的類,所有的線路往$Proxy0原始碼裡找。

    寫個簡單的測試

    這裡透過Proxy.newProxyInstance方法來建立我們的代理物件,

    大約的過程是這樣:

    執行一下程式會發現它生成一個叫做$proxy0的類,它就是代理物件的真身。

    檢視這個$proxy0 原始碼就會發現它的構造器就直接呼叫了 super(invocationhandler),這裡invocationhandler在本例子就是 new DynamicProxyHandler(real),而它必須實現Invocationhandler介面,這個介面就一個方法invoke(), 所以動態代理自然然就轉換為呼叫invoke()方法了, 另外開啟$

    proxy0.class

    看一下里面方法的引數傳遞就更清楚了。

  • 2 # 一江一城一巷

    也不想回答太多,寫多了反而頭暈。動態代理底層就是java反射,動態生成了之後代理類,所以呼叫的反射裡的invoke

  • 3 # 程式猿W

    基本介紹代理物件,不需要實現介面,但是目標物件要實現介面,否則不能用動態代理。代理物件的生成,是利用JDK的API,動態的記憶體中構建代理物件動態代理也叫做: JDK代理、介面代理JDK中生成代理物件的API代理類所在包: java.lang.reflect.ProxyJDK實現代理只需要使用newProxyInstance方法,但是該方法需要接收三個引數,完整寫法為:static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) 動態代理應用舉例

    用動態代理實現事務:

    UserService:

    UserServiceImpl:

    UserServiceInvocationHandler:

    測試類:

    結果為:

    下面分析,為什麼java動態代理中,最終都轉換為呼叫invok方法?

    我們先檢視上面生成的proxy物件,

    下面我們看看生成的 $proxy0程式碼:

    很清楚,動態代理類實現了UserService介面,繼承了Proxy類。

    介面方法:

    invoke方法傳入3個引數,這個invoke方法也就是4.1.2中我們提到的InvocationHandler介面的 invoke方法,那理解3個引數的意義也就很簡單了。

    引數1傳入的為this——即$Proxy0本身,所以是記憶體中的動態代理物件

    引數2傳入的為m3——也就是proxy.test.UserService中名為saveUser的方法,即介面中的方法。

    引數3傳入的為null——因為saveUser方法沒有引數,所以為空。

    完整程式碼如下
  • 中秋節和大豐收的關聯?
  • 安卓手機郵箱無法設定啊,總是說無法與伺服器連線,安卓4.0的?