JDK Proxy

作者: lixwcqs | 来源:发表于2020-01-04 17:37 被阅读0次

动态代理

public class JdkProxyDemo {


    static class ProxyHandler implements InvocationHandler {

        private Object target;

        public ProxyHandler(Object target) {
            this.target = target;
        }


        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            return method.invoke(target, args);
        }
    }

    public static void main(String[] args) throws IntrospectionException, InterruptedException {
        // 1.被代理的对象
        Predicate<Integer> predicate = integer -> integer > 100;
        //2.handler实现类
        ProxyHandler handler = new ProxyHandler(predicate);
        //3.新建Proxy对象
        Predicate<Integer> pre = (Predicate) Proxy.newProxyInstance(Predicate.class.getClassLoader(), new Class[]{Predicate.class}, handler);
        System.out.println(pre.getClass());//class com.sun.proxy.$Proxy0
    }
}

pre对象为com.sun.proxy.Proxy0类型Proxy0字节码通过文件的方式打印出来

//找到进程
jps -l | grep JdkProxyDemo 
//启动HSDB
 java -cp $JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.HSDB

点击找到com.sun.proxy.Proxy0类, Create .class for this class ![image.png](https://img.haomeiwen.com/i6156941/e737fe10a3016562.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 通过idea查看字节码Proxy0的字节码

image.png

105~113行是$Proxy对接口Predicate的方法test的实现:通过传递进来的invocationHandler实现的.

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.sun.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.function.Predicate;

public final class $Proxy0 extends Proxy implements Predicate {
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m6;
    private static Method m4;
    private static Method m5;
    private static Method m7;
    private static Method m0;

    public final Predicate negate() {
        try {
            return (Predicate)super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final Predicate isEqual(Object var1) {
        try {
            return (Predicate)super.h.invoke(this, m4, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public $Proxy0(InvocationHandler var1) {
        super(var1);
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m3 = Class.forName("java.util.function.Predicate").getMethod("negate");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m6 = Class.forName("java.util.function.Predicate").getMethod("and", Class.forName("java.util.function.Predicate"));
            m4 = Class.forName("java.util.function.Predicate").getMethod("isEqual", Class.forName("java.lang.Object"));
            m5 = Class.forName("java.util.function.Predicate").getMethod("test", Class.forName("java.lang.Object"));
            m7 = Class.forName("java.util.function.Predicate").getMethod("or", Class.forName("java.util.function.Predicate"));
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }

    public final boolean equals(Object var1) {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() {
        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 int hashCode() {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final boolean test(Object var1) {
        try {
            return (Boolean)super.h.invoke(this, m5, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final Predicate and(Predicate var1) {
        try {
            return (Predicate)super.h.invoke(this, m6, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final Predicate or(Predicate var1) {
        try {
            return (Predicate)super.h.invoke(this, m7, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }
}

我们发现$Proxy0

  1. 继承了Proxy类 : Java 是单继承的,所以Java 动态代理不能代理类,只能代理接口
  2. 实现了接口
  3. 所有的实现方法是通过InvocationHandler对象实现的

相关文章

  • JDK Proxy

    动态代理 pre对象为com.sun.proxy.Proxy0字节码通过文件的方式打印出来 点击找到com.sun...

  • JDK Proxy

  • 使用 Cglib 实现多重代理

    前言 由于 Cglib 本身的设计,无法实现在 Proxy 外面再包装一层 Proxy(JDK Proxy 可以...

  • Cglib 如何实现多重代理?

    由于 Cglib 本身的设计,无法实现在 Proxy 外面再包装一层 Proxy(JDK Proxy 可以),通...

  • Cglib 如何实现多重代理?

    由于 Cglib 本身的设计,无法实现在 Proxy 外面再包装一层 Proxy(JDK Proxy 可以),通...

  • GCLIB动态代理

    1,简介 1)对比JDK动态代理,由于JDK动态代理生成的proxy对象,都是继承了Proxy类,并实现了所代理的...

  • Spring系列之AOP(1)—— JDK动态代理和CigLib

    1、JDK动态代理 JDK动态代理通过JDK的Proxy类实现,JDK提供的动态代理需要实现InvocationH...

  • 代理之JDK动态代理(2018-07-26)

    jdk动态代理使用: 核心方法: 使用java.lang.reflect.Proxy中的方法Proxy.newPr...

  • JDK Proxy 小试

    demo 在本 demo 中我们将创建一个 door 接口,实现对接口中所有方法的代理。door.java Hom...

  • JDK Proxy 源码

    说到动态代理的受限于的接口的,这包括两个方面 非接口不能使用JDK动态代理 若一个类实现了接口(implement...

网友评论

      本文标题:JDK Proxy

      本文链接:https://www.haomeiwen.com/subject/aihfactx.html