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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

sap-erp实施心得_实施动态代理-比较

發(fā)布時間:2023/12/3 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sap-erp实施心得_实施动态代理-比较 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

sap-erp實施心得

有時需要攔截某些方法調(diào)用,以便每次調(diào)用被攔截方法時都執(zhí)行自己的邏輯。 如果您不屬于Java EE的CDI領(lǐng)域,并且不想使用諸如Aspectj之類的AOP框架,那么您將有一個簡單而有效的替代方法。

從1.5版開始,JDK附帶了類java.lang.reflect.Proxy,該類允許您為給定的接口創(chuàng)建動態(tài)代理。 每當應(yīng)用程序調(diào)用代理上的方法時,都會調(diào)用位于動態(tài)創(chuàng)建的類后面的InvocationHandler。 因此,您可以在調(diào)用某個框架或庫的代碼之前動態(tài)控制執(zhí)行什么代碼。

在JDK的Proxy實現(xiàn)旁邊,像javassist或cglib這樣的字節(jié)碼框架提供了類似的功能。 在這里,您甚至可以對現(xiàn)有的類進行子類化,并確定要轉(zhuǎn)發(fā)給超類的實現(xiàn)的方法以及要攔截的方法。 當然,這會帶來項目依賴的另一個庫的負擔(dān),并且可能需要不時更新,而運行時環(huán)境中已經(jīng)包含了JDK的Proxy實現(xiàn)。

因此,讓我們仔細看看并嘗試這三種選擇。 為了將javassist和cglib的代理與JDK實現(xiàn)進行比較,我們需要一個由簡單類實現(xiàn)的接口,因為JDK機制僅支持接口,而沒有子類:

public interface IExample {void setName(String name); }public class Example implements IExample {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;} }

為了將代理上的方法調(diào)用委托給某個實際對象,我們創(chuàng)建了上面的Example類的實例,并通過最終聲明的變量在InvocationHandler中調(diào)用它:

final Example example = new Example(); InvocationHandler invocationHandler = new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {return method.invoke(example, args);} }; return (IExample) Proxy.newProxyInstance(JavaProxy.class.getClassLoader(), new Class[]{IExample.class}, invocationHandler);

從代碼示例中可以看到,代理的創(chuàng)建非常簡單:調(diào)用靜態(tài)方法newProxyInstance()并提供ClassLoader,應(yīng)由代理實現(xiàn)的接口數(shù)組以及InvocationHandler接口的實例。 為了演示起見,我們的實現(xiàn)僅轉(zhuǎn)發(fā)我們之前創(chuàng)建的Example實例。 但是,在現(xiàn)實生活中,您當然可以執(zhí)行更高級的操作,以評估例如方法名稱或其參數(shù)。

現(xiàn)在我們來看一下使用javassist完成相同操作的方式:

ProxyFactory factory = new ProxyFactory(); factory.setSuperclass(Example.class); Class aClass = factory.createClass(); final IExample newInstance = (IExample) aClass.newInstance(); MethodHandler methodHandler = new MethodHandler() {@Overridepublic Object invoke(Object self, Method overridden, Method proceed, Object[] args) throws Throwable {return proceed.invoke(newInstance, args);} }; ((ProxyObject)newInstance).setHandler(methodHandler); return newInstance;

在這里,我們有一個ProxyFactory,它想知道應(yīng)該為哪個類創(chuàng)建子類。 然后,我們讓ProxyFactory創(chuàng)建一個整個類,該類可以根據(jù)需要多次重用。 這里的MethodHandler與InvocationHandler類似,后者是為實例的每次方法調(diào)用而調(diào)用的。 在這里,我們再次將調(diào)用轉(zhuǎn)發(fā)到之前創(chuàng)建的Example實例。

最后但并非最不重要的一點,讓我們看一下cglib的代理:

final Example example = new Example(); IExample exampleProxy = (IExample) Enhancer.create(IExample.class, new MethodInterceptor() {@Overridepublic Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {return method.invoke(example, args);} }); return exampleProxy;

在cglib世界中,我們有一個Enhancer類,可用于通過MethodInterceptor實例實現(xiàn)給定的接口。 回調(diào)方法的實現(xiàn)看起來與javassist示例中的實現(xiàn)非常相似。 我們只是通過反射API將方法調(diào)用轉(zhuǎn)發(fā)到Example的現(xiàn)有實例。

現(xiàn)在,我們已經(jīng)看到了三種不同的實現(xiàn),我們還希望評估它們的運行時行為。 因此,我們編寫了一個簡單的單元測試,它測量了每個實現(xiàn)的執(zhí)行時間:

@Test public void testPerformance() {final IExample example = JavaProxy.createExample();long measure = TimeMeasurement.measure(new TimeMeasurement.Execution() {@Overridepublic void execute() {for (long i = 0; i < JavassistProxyTest.NUMBER_OF_ITERATIONS; i++) {example.setName("name");}}});System.out.println("Proxy: "+measure+" ms"); }

我們選擇大量的迭代,以強調(diào)JVM并讓HotSpot編譯器為經(jīng)常執(zhí)行的段落創(chuàng)建本機代碼。 下表顯示了三種實現(xiàn)的平均運行時間:

為了完全顯示代理實現(xiàn)的影響,該圖表還顯示了對Example對象(“無代理”)進行標準方法調(diào)用的執(zhí)行時間。 首先,我們可以記錄到代理實現(xiàn)比方法本身的普通調(diào)用慢大約10倍。 但是我們也注意到三種代理解決方案之間的差異。 令人驚訝的是,JDK的Proxy類幾乎與cglib實現(xiàn)一樣快。 只有javassist的退出時間是cglib的兩倍左右。

結(jié)論:運行時代理易于使用,您有不同的處理方式。 JDK的代理僅支持接口代理,而javassist和cglib允許您對現(xiàn)有類進行子類化。 代理的運行時行為比標準方法調(diào)用慢大約10倍。 三種解決方案在運行時間方面也有所不同。

參考: 實現(xiàn)動態(tài)代理–來自我們的JCG合作伙伴 Martin Mois在Martin's Developer World博客上的比較。

翻譯自: https://www.javacodegeeks.com/2014/01/implementing-dynamic-proxies-a-comparison.html

sap-erp實施心得

總結(jié)

以上是生活随笔為你收集整理的sap-erp实施心得_实施动态代理-比较的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。