网站建设资讯

NEWS

网站建设资讯

java动态代理ProxyGenerator-创新互联

jdk自带实现动态代理核心逻辑即是在调用 java.lang.reflect.Proxy#newProxyInstance 时,根据用户指定实现的接口动态创建一个Proxy类定义的byte[],然后调用native 的defineClass返回该代理类的实例;java动态代理ProxyGen
erator

核心逻辑实例:

创新互联是一家专业提供临潭企业网站建设,专注与网站建设、网站制作html5、小程序制作等业务。10年已为临潭众多企业、政府机构等服务。创新互联专业网站设计公司优惠进行中。
 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(), 而且将方法调用委派给用户指定的 InvocationHandler。

所以本质上来说“动态代理”仍旧是“静态代理”,“动态”表现在不用修改代码的情况下运行时通过“魔改”,然后“偷梁换柱”的方式返回给用户代理对象;

对用户来说,调用返回的代理对象本身就实现了用户接口 (implements Executor)。

从用户的角度语义上讲即为:“塞给java.lang.reflect.Proxy任意接口和目标对象,Poxy都能给出用户指定增强目标对象接口方法逻辑的代理对象”;

如果不制定具体是哪个接口java.lang.reflect.Proxy 无法得知在从何处抽取出接口方法生成class byte数组。

无接口AOP增强类方法就要依靠cglib之类工具了。


分享标题:java动态代理ProxyGenerator-创新互联
网页URL:http://cdweb.net/article/doeepe.html