日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用djcproxy创建代理对象

發布時間:2023/12/3 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用djcproxy创建代理对象 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在過去的幾周中,我展示了如何使用Java Reflection API和cglib創建代理對象。 在本文中,我將向您展示如何使用djcproxy做到這一點。

哦,不是,另一個代理實現!

除了我創建此代理的自私事實之外,還要寫些什么呢? 關鍵是這是一個用Java編寫的代理,它創建了可以檢查的Java代碼。 它還可以即時編譯和加載創建的Java類,因此它也可以使用,但主要優點是您可以輕松了解動態代理的工作原理。 至少比深入研究cglib的代碼要容易得多,后者直接創建字節碼。

如何使用它

您可以從github獲取源代碼,也可以將依賴項添加到項目maven pom中。

<dependency><groupId>com.javax0</groupId><artifactId>djcproxy</artifactId><version>2.0.3</version> </dependency>

之后,您可以使用以下代碼:

class A {public int method() {return 1;} } class Interceptor implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args,MethodProxy mproxy) throws Exception {if (method.getName().equals("toString")) {return "interceptedToString";}return 0;} }...A a = new A();ProxyFactory<A> factory = new ProxyFactory<>();A s = factory.create(a, new Interceptor());

可以在GitHub中的項目測試中找到此代碼。 這是一個易于編輯的易于編輯的縮寫版本。

類“ A”是原始類,當我們要創建新的代理對象時,我們將創建一個已存在對象的代理。 這不同于反射或屈服。 如果使用cgilib,您將創建一個代理對象,它“包含”原始對象。 從OO術語來看,它并不是真正的包含,因為代理類擴展了原始類。 但是,由于此擴展,代理對象也是原始類的實例。 Cgilib并不真正在乎您要攔截哪個類實例(對象)。 如果需要,可以將對任何對象實例的引用注入到攔截器中。 Djcproxy使用了一種不同的方法,它可以為您做到這一點,在攔截器中,您將獲得此對象作為參數傳遞。 這就是為什么您必須在第20行實例化該對象的原因。

Interceptor實現了庫中也提供的接口MethodInterceptor 。 它只有一種方法: intercept ,在調用代理對象方法時調用。 參數是

  • obj –原始對象
  • method –在代理對象中調用的方法
  • args –傳遞給代理對象上的方法調用的參數。 注意原始參數將被裝箱。
  • mproxy –方法代理,可用于在原始對象上或僅在相同類型的任何其他對象上調用方法

這就是關于如何使用該庫的全部內容。 接下來的事情是查看生成的內容,以便您可以更好地了解代理的工作方式。 即使您使用其他代理,洞察力也不會傷害您。 當您了解所使用的庫的原理時,很多時候調試或僅生成更好的代碼會更容易。

盡管cglib為您提供了一個靜態工廠方法來創建新對象,但djcproxy要求您創建一個代理工廠。 這是在21上方的行上顯示的。如果要像使用cglib一樣使用它,則可以在要使用其工廠的類中聲明一個靜態ProxyFactory字段。 另一方面,可能在代碼的不同部分具有不同的工廠。 盡管它的優點很少,但是我仍然相信它比提供靜態工廠方法更干凈。

代理如何工作?

此程序包中的另一件事是,它使您可以訪問生成的源。 您可以插入行

String generatedSource = factory.getGeneratedSource();System.out.println(generatedSource);

打印出生成的代理類,這是經過某種格式設置的:

package com.javax0.djcproxy;class PROXY$CLASS$A extends com.javax0.djcproxy.ProxyFactoryTest.A implements com.javax0.djcproxy.ProxySetter {com.javax0.djcproxy.ProxyFactoryTest.A PROXY$OBJECT = null;com.javax0.djcproxy.MethodInterceptor PROXY$INTERCEPTOR = null;public void setPROXY$OBJECT(java.lang.Object PROXY$OBJECT) {this.PROXY$OBJECT = (com.javax0.djcproxy.ProxyFactoryTest.A) PROXY$OBJECT;}public void setPROXY$INTERCEPTOR(com.javax0.djcproxy.MethodInterceptor PROXY$INTERCEPTOR) {this.PROXY$INTERCEPTOR = PROXY$INTERCEPTOR;}PROXY$CLASS$A() {super();}private com.javax0.djcproxy.MethodProxy method_MethodProxyInstance = null;@Overridepublic int method() {try {if (null == method_MethodProxyInstance) {method_MethodProxyInstance = new com.javax0.djcproxy.MethodProxy() {public java.lang.Object invoke(java.lang.Object obj, java.lang.Object[] args) throws Throwable {return ((com.javax0.djcproxy.ProxyFactoryTest.A) obj).method();}};}return (int) PROXY$INTERCEPTOR.intercept(PROXY$OBJECT, PROXY$OBJECT.getClass().getMethod("method", new Class[]{}),new Object[]{}, method_MethodProxyInstance);} catch (Throwable e) {throw new RuntimeException(e);}}... other overridden methods deleted ...}

請注意,對于此生成的代碼,類A是ProxyFactoryTest的靜態嵌套類。

有趣的代碼是方法method()的重載。 (對不起這個名字。對于一個什么都不做的方法,我有一個更好的名字。我不MethodProxy 。)讓我們跳過該部分,檢查該方法是否已經存在MethodProxy實例,如果缺少則創建一個。 方法method()實際上會調用我們定義的攔截器對象,并傳遞代理對象,反射方法對象,參數以及方法代理。

什么是方法代理

該名稱可能首先引起混淆,因為我們已經有一個“對象”代理。 原始類的每個方法都有一個單獨的方法代理。 這些可用于調用原始方法,而無需進行反射調用。 這加快了代理的使用。 您還可以在cglib中找到此調用和類似的機制。

筆記

該實現有一些流程,例如,后方法代理實例化實際上沒有優勢,但同時在代理的多線程執行情況下可能會受到損害。 還可以創建一個不僅擴展類而且實現任意接口的代理對象(也許某些擴展類甚至沒有實現)。 該實現在github上也有一些其他業余愛好開源項目中使用,我將來可能會寫有關該項目的信息。 它們比生產代碼更具說明性,教育性和概念證明性項目。 如果您對實施,想法或任何意見有任何意見,請給我您的意見。

翻譯自: https://www.javacodegeeks.com/2016/02/creating-proxy-object-using-djcproxy.html

總結

以上是生活随笔為你收集整理的使用djcproxy创建代理对象的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。