核心邏輯實例:
創(chuàng)新互聯(lián)是一家專業(yè)提供臨潭企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站建設(shè)、網(wǎng)站制作、html5、小程序制作等業(yè)務(wù)。10年已為臨潭眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計公司優(yōu)惠進行中。 1 String className = "com.sun.$Proxy";
2 int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
3
4 Class<?>[] cls = new Class<?>[]{Executor.class};
5
6 byte[] bytes = ProxyGenerator.generateProxyClass(className, cls, accessFlags);
7
8 System.out.println("byteLen: " + bytes.length);
9 Path path = Paths.get("D:\misc\Proxy.class");
10
11 try {
12 Files.createFile(path);
13 OutputStream outputStream = Files.newOutputStream(path, StandardOpenOption.WRITE);
14 outputStream.write(bytes);
15 outputStream.close();
16 } catch (IOException e) {
17 e.printStackTrace();
18 }
這里將byte[] 寫入文件,二進制文件Proxy.class 反編譯后類似:
1 // 2 // Source code recreated from a .class file by IntelliJ IDEA
3 // (powered by Fernflower decompiler)
4 //
5
6 package com.sun;
7
8 import indi.joynic.actscase.gen.aopalliance.Executor;
9 import java.lang.reflect.InvocationHandler;
10 import java.lang.reflect.Method;
11 import java.lang.reflect.Proxy;
12 import java.lang.reflect.UndeclaredThrowableException;
13
14 public final class $Proxy extends Proxy implements Executor {
15 private static Method m1;
16 private static Method m2;
17 private static Method m3;
18 private static Method m0;
19
20 public $Proxy(InvocationHandler var1) throws {
21 super(var1);
22 }
23
24 public final boolean equals(Object var1) throws {
25 try {
26 return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
27 } catch (RuntimeException | Error var3) {
28 throw var3;
29 } catch (Throwable var4) {
30 throw new UndeclaredThrowableException(var4);
31 }
32 }
33
34 public final String toString() throws {
35 try {
36 return (String)super.h.invoke(this, m2, (Object[])null);
37 } catch (RuntimeException | Error var2) {
38 throw var2;
39 } catch (Throwable var3) {
40 throw new UndeclaredThrowableException(var3);
41 }
42 }
43
44 public final char execute() throws {
45 try {
46 return (Character)super.h.invoke(this, m3, (Object[])null);
47 } catch (RuntimeException | Error var2) {
48 throw var2;
49 } catch (Throwable var3) {
50 throw new UndeclaredThrowableException(var3);
51 }
52 }
53
54 public final int hashCode() throws {
55 try {
56 return (Integer)super.h.invoke(this, m0, (Object[])null);
57 } catch (RuntimeException | Error var2) {
58 throw var2;
59 } catch (Throwable var3) {
60 throw new UndeclaredThrowableException(var3);
61 }
62 }
63
64 static {
65 try {
66 m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
67 m2 = Class.forName("java.lang.Object").getMethod("toString");
68 m3 = Class.forName("indi.joynic.actscase.gen.aopalliance.Executor").getMethod("execute");
69 m0 = Class.forName("java.lang.Object").getMethod("hashCode");
70 } catch (NoSuchMethodException var2) {
71 throw new NoSuchMethodError(var2.getMessage());
72 } catch (ClassNotFoundException var3) {
73 throw new NoClassDefFoundError(var3.getMessage());
74 }
75 }
76 }
生成了一個新的Proxy代理子類,可以看到實際返回的類定義寫入了 hashCode() 、toString()、equals()和 用戶接口方法 execute(), 而且將方法調(diào)用委派給用戶指定的 InvocationHandler。
所以本質(zhì)上來說“動態(tài)代理”仍舊是“靜態(tài)代理”,“動態(tài)”表現(xiàn)在不用修改代碼的情況下運行時通過“魔改”,然后“偷梁換柱”的方式返回給用戶代理對象;
對用戶來說,調(diào)用返回的代理對象本身就實現(xiàn)了用戶接口 (implements Executor)。
從用戶的角度語義上講即為:“塞給java.lang.reflect.Proxy任意接口和目標(biāo)對象,Poxy都能給出用戶指定增強目標(biāo)對象接口方法邏輯的代理對象”;
如果不制定具體是哪個接口,java.lang.reflect.Proxy 無法得知在從何處抽取出接口方法生成class byte數(shù)組。
無接口AOP增強類方法就要依靠cglib之類工具了。
名稱欄目:java動態(tài)代理ProxyGenerator-創(chuàng)新互聯(lián)
鏈接地址:http://www.rwnh.cn/article34/doeepe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營銷型網(wǎng)站建設(shè)、手機網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、品牌網(wǎng)站設(shè)計、標(biāo)簽優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容