博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java JDK 动态代理分析
阅读量:4605 次
发布时间:2019-06-09

本文共 6182 字,大约阅读时间需要 20 分钟。

JDK动态代理使用(代码来自TIJ)

import sun.misc.ProxyGenerator;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.Arrays;/** * Created by aiyi on 2017/3/17. */public class SimpleProxyDemo {    public static void consumer(Interface iface) {        iface.doSomething();        iface.somethingElse("bonobo");    }    public static void main(String[] args) {        RealObject realObject = new RealObject();        Interface instance = (Interface) Proxy.newProxyInstance(Interface.class.getClassLoader(),                new Class[]{Interface.class},                new DynamicProxyHandler(realObject));        consumer(instance);        System.out.println(instance.getClass().getName());        createProxyFile();    }    private static void createProxyFile() {        byte[] bytes = ProxyGenerator.generateProxyClass("ProxySubject", new Class[]{Interface.class});        FileOutputStream out = null;        try {            out = new FileOutputStream("ProxySubject" + ".class");            out.write(bytes);        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }}interface Interface {    void doSomething();    void somethingElse(String arg);}class RealObject implements Interface {    @Override    public void doSomething() {        System.out.println("doSomething");    }    @Override    public void somethingElse(String arg) {        System.out.println("somethingElse: " + arg);    }}class DynamicProxyHandler implements InvocationHandler {    private Object proxied;    public DynamicProxyHandler(Object proxied) {        this.proxied = proxied;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("===== proxy: " + proxy.getClass() + " method: " + method + " args: " + Arrays.toString(args));        if (args != null) {            for (Object arg : args) {                System.out.println(arg + " ");            }        }        return method.invoke(proxied, args);    }}

声明一个代理类实现 InvocationHandler接口,实际对Interfere接口方法的调用关联到对handler的invoke方法的调用。实现类似AOP的效果

 

  通过调用Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler)方法获取通过反射生成的代理类。loader定义了获取代理类所用的类加载器,interfaces是代理类需要实现的一组接口,handler就是处理器了。

  具体实现。Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler)

      ->Proxy.getProxyClass0(ClassLoader loader, Class<?>... interfaces)

      ->proxyClassCache.get(loader, interfaces)   //proxyClassCacahess是一个WeakCache的实例

      ->supplier.get()   //suppiler是一个接口,其WeakCache的内部类Factory实现了这个接口

      ->valueFactory.apply(K t, P u)  //valueFactory是WeakCache的属性,回到Proxy.java 会发现valueFactory就是ProxyClassFactory的实例

      ---->ProxyClassFactory.apply(K t, P u)

      ->ProxyGenertor.generateProxyClass

  最后生成了字节码

代码生成的字节码如下

import com.aiyi.chapter14.Interface;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.lang.reflect.UndeclaredThrowableException;public final class ProxySubject extends Proxy implements Interface {    private static Method m1;    private static Method m3;    private static Method m2;    private static Method m4;    private static Method m0;    public ProxySubject(InvocationHandler var1) throws  {        super(var1);    }    public final boolean equals(Object var1) throws  {        try {            return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue();        } catch (RuntimeException | Error var3) {            throw var3;        } catch (Throwable var4) {            throw new UndeclaredThrowableException(var4);        }    }    public final void doSomething() throws  {        try {            super.h.invoke(this, m3, (Object[])null);        } catch (RuntimeException | Error var2) {            throw var2;        } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);        }    }    public final String toString() throws  {        try {            return (String)super.h.invoke(this, m2, (Object[])null);        } catch (RuntimeException | Error var2) {            throw var2;        } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);        }    }    public final void somethingElse(String var1) throws  {        try {            super.h.invoke(this, m4, new Object[]{var1});        } catch (RuntimeException | Error var3) {            throw var3;        } catch (Throwable var4) {            throw new UndeclaredThrowableException(var4);        }    }    public final int hashCode() throws  {        try {            return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue();        } catch (RuntimeException | Error var2) {            throw var2;        } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);        }    }    static {        try {            m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});            m3 = Class.forName("com.aiyi.chapter14.Interface").getMethod("doSomething", new Class[0]);            m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);            m4 = Class.forName("com.aiyi.chapter14.Interface").getMethod("somethingElse", new Class[]{Class.forName("java.lang.String")});            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);        } catch (NoSuchMethodException var2) {            throw new NoSuchMethodError(var2.getMessage());        } catch (ClassNotFoundException var3) {            throw new NoClassDefFoundError(var3.getMessage());        }    }}

可以看到方法的调用都关联到了h\*就是InvocationHandler*\.invoke()方法.那么生成的类又是怎么获得InvocationHandler的

在Proxy.newProxyInstance中有如下代码

Class
cl = getProxyClass0(loader, intfs);final Constructor
cons = cl.getConstructor(constructorParams);//这个h就是我们的代理类return cons.newInstance(new Object[]{h});

  

 

 

 

转载于:https://www.cnblogs.com/blogforleetcode/p/6622689.html

你可能感兴趣的文章
windows 下配置Eclipse che
查看>>
SearchSploit
查看>>
2017.3.2
查看>>
关于C语言中的转义字符
查看>>
9-条件测试
查看>>
移植3.4.2内核之韦东山笔记
查看>>
Cocos2d-x学习笔记(20)(TestCpp源代码分析-4)
查看>>
maven pom.xml报错
查看>>
钱多,人傻,快来快来
查看>>
python之haproxy配置文件操作(第三天)
查看>>
【css初始化】统一规范样式 base.css 样式应该怎样写?
查看>>
DB2数据库BACKUP PENDING状态(修改日志模式导致)(转)
查看>>
bzoj 1061 单纯形法,或转化网络流(待补)
查看>>
PHP实现 bitmap 位图排序 求交集
查看>>
2015.05.04,外语,读书笔记-《Word Power Made Easy》 14 “如何谈论日常现象” SESSION 41...
查看>>
UA Curry 4 Low Performance Reviews
查看>>
placeholder属性
查看>>
用正则表达式从网页里面提取视频地址
查看>>
开源搜索引擎Iveely 0.7.0发布,不一样,那就让他不一样!
查看>>
Java中的拆箱和装箱
查看>>