一起研究源码系列:一步一步分析 Java JDK 动态代理源码

JDK 动态代理

参考

这篇文章主要参考了以下两篇写的不错的文章,综合了一下,整理成自己的学习笔记。
https://www.jianshu.com/p/269afd0a52e6
https://www.cnblogs.com/puyangsky/p/6218925.html

动态代理

静态代理的缺点:

  1. 代理类和被代理类实现了相同的接口。导致代码的重复,如过接口新增加一方法,代理类和被代理类都要实现这个方法,增加代码维护的难度
  2. 代理对象只服务于一种类型的对象,如果要服务多种类型的对象就要为每个对象都进行代理。

静态代理只能指定针对某个类,那么如果想在这个类的任意方法上都加上同样的逻辑(实现同样的代理)该如何做,可以通过JDK的动态代理,JDK动态代理可以通过反射机制来获取class和Method

JDK自带方法

步骤

①创建被代理的接口和类;
②创建InvocationHandler接口的实现类,在invoke方法中实现代理逻辑;
③通过Proxy的静态方法newProxyInstance( ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理对象
④使用代理对象

首先介绍一下最核心的一个接口和一个方法:

首先是java.lang.reflect包里的InvocationHandler接口:

public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
}

我们对于被代理的类的操作都会由该接口中的invoke方法实现,其中的参数的含义分别是:

  • proxy:被代理的类的实例
  • method:调用被代理的类的方法 (通过反射机制获得)
  • args:该方法需要的参数

使用方法首先是需要实现该接口,并且我们可以在invoke方法中调用被代理类的方法并获得返回值,自然也可以在调用该方法的前后去做一些额外的事情,从而实现动态代理,下面的例子会详细写到。

另外一个很重要的静态方法是 java.lang.reflect 包中的 Proxy 类的 newProxyInstance 方法:

public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
    throws IllegalArgumentException

其中的参数含义如下:

  • loader:指定代理类的类加载器
  • interfaces:被代理类实现的接口数组,当传入代理类实现的接口,这样生成的代理类和被代理类实现了相同的接口)
  • invocationHandler:就是刚刚介绍的调用处理器类的对象实例

该方法会返回一个被修改过的类的实例,从而可以自由的调用该实例的方法。

Demo 演示

Fruit接口:

public interface Fruit {
    public void show();
}

Apple实现Fruit接口:

public class Apple implements Fruit{
    @Override
    public void show() {
        System.out.println("<<<<show method is invoked");
    }
}

代理类Agent.java:

public class DynamicAgent {

    //实现InvocationHandler接口,并且可以初始化被代理类的对象
    static class MyHandler implements InvocationHandler {
        private Object proxy;
        public MyHandler(Object proxy) {
            this.proxy = proxy;
        }
            
        //自定义invoke方法
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println(">>>>before invoking");
            //真正调用方法的地方
            Object ret = method.invoke(this.proxy, args);
            System.out.println(">>>>after invoking");
            return ret;
        }
    }

    //返回一个被修改过的对象
    public static Object agent(Class interfaceClazz, Object proxy) {
        return Proxy.newProxyInstance(interfaceClazz.getClassLoader(), new Class[]{interfaceClazz},
                new MyHandler(proxy));
    }    
}

测试类:

public class ReflectTest {
    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
        //注意一定要返回接口,不能返回实现类否则会报错
        Fruit fruit = (Fruit) DynamicAgent.agent(Fruit.class, new Apple());
        // 如果光将代理的内部类拿出来,那么当前类就为代理类,直接在main方法内返回代理对象
        // Friut fruit = Proxy.newProxyInstance(Reflect.class.getClassLoader(), new class[] {Friut}, new MyHandler(new Apple()))
        fruit.show();
    }
}

JDK 动态代理源码解析

1. Proxy.newProxyInstance 方法

上述Demo代码中可以看到是由 Proxy 方法内的 newProxyInstance 方法产生代理类并返回

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
{
    // 检验 InvocationHandler 是否为空
    Objects.requireNonNull(h);
	// 接口的类对象拷贝
    final Class<?>[] intfs = interfaces.clone();
    // 安全解析
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
    }

    /*
      * Look up or generate the designated proxy class.
      * 查询(在缓存中已经有)或生成指定代理类的class对象
      */
    Class<?> cl = getProxyClass0(loader, intfs);

    /*
      * Invoke its constructor with the designated invocation handler.
      */
    try {
        if (sm != null) {
            checkNewProxyPermission(Reflection.getCallerClass(), cl);
        }
		
        // 得到代理类对象的构造函数,这个构造函数的参数由 constructorParams 指定
        // constructorParams 常量值
        // private static final Class<?>[] constructorParams = { InvocationHandler.class };
        final Constructor<?> cons = cl.getConstructor(constructorParams);
        final InvocationHandler ih = h;
        if (!Modifier.isPublic(cl.getModifiers())) {
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {
                    cons.setAccessible(true);
                    return null;
                }
            });
        }
        // 生成代理类对象
        return cons.newInstance(new Object[]{h});
        
    } catch (IllegalAccessException|InstantiationException e) {
        throw new InternalError(e.toString(), e);
    } catch (InvocationTargetException e) {
        Throwable t = e.getCause();
        if (t instanceof RuntimeException) {
            throw (RuntimeException) t;
        } else {
            throw new InternalError(t.toString(), t);
        }
    } catch (NoSuchMethodException e) {
        throw new InternalError(e.toString(), e);
    }
}

上述代码去掉一些校验规则之后,其核心代码就是

  1. Class<?> cl = getProxyClass0(loader, intfs);
    

    通过代理对象的类加载器和接口数组ClassLoaderClass<?>[] interfaces 查看缓存里是否存在或生成指定代理类的class对象

  2. private static final Class<?>[] constructorParams = { InvocationHandler.class };
    final Constructor<?> cons = cl.getConstructor(constructorParams);
    

    得到代理类对象的构造函数,构造函数的参数由 constructorParams 参数指定,

  3. return cons.newInstance(new Object[]{h});
    

    根据这个构造函数生成一个对象

接下来主要对以下代码进行分析

2. getProxyClass0(loader, intfs) 方法

//此方法也是Proxy类下的方法
private static Class<?> getProxyClass0(ClassLoader loader,
                                       Class<?>... interfaces) {
    if (interfaces.length > 65535) {
        throw new IllegalArgumentException("interface limit exceeded");
    }

    // If the proxy class defined by the given loader implementing
    // the given interfaces exists, this will simply return the cached copy;
    // otherwise, it will create the proxy class via the ProxyClassFactory
    //意思是:如果代理类被指定的类加载器loader定义了,并实现了给定的接口interfaces,
    //那么就返回缓存的代理类对象,否则使用ProxyClassFactory创建代理类。
    return proxyClassCache.get(loader, interfaces);
}

这段代码的注释:如果代理类被指定的类加载器loader定义了,并实现了给定的接口interfaces,那么就返回缓存的代理类对象,否则使用ProxyClassFactory创建代理类。

接下来看一下 ProxyClassFactory 是什么

3. proxyClassCache

/**
 * a cache of proxy classes
 */
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

proxyClassCache 其实是个 WeakCache 对象,proxyClassCache 对象的 get 方法其实是 WeakCache 类的 get 方法。

注意对象内的泛型 <ClassLoader, Class[?], Class<?>

  • ClassLoader : 代理对象的类加载器
  • Class[]<?> : 代理对象实现的参数数组
  • Class<?>:需要的代理类对象

构造方法的参数 new KeyFactory(), new ProxyClassFactory()

到这里可以看出代理对象的实例化与 WeakCache 对象密切相关

4 .WeakCache 对象的参数与构造参数

这里先看 这个对象的核心参数和构造参数

//K代表key的类型,P代表参数的类型,V代表value的类型。
// WeakCache<ClassLoader, Class<?>[], Class<?>>  proxyClassCache  说明proxyClassCache存的值是Class<?>对象,正是我们需要的代理类对象。
final class WeakCache<K, P, V> {

    private final ReferenceQueue<K> refQueue
        = new ReferenceQueue<>();
    // the key type is Object for supporting null key
    private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
        = new ConcurrentHashMap<>();
    private final ConcurrentMap<Supplier<V>, Boolean> reverseMap
        = new ConcurrentHashMap<>();
    
    private final BiFunction<K, P, ?> subKeyFactory;
    private final BiFunction<K, P, V> valueFactory;
	
     /**
     * Construct an instance of {@code WeakCache}
     *
     * @param subKeyFactory a function mapping a pair of
     *                      {@code (key, parameter) -> sub-key}
     * @param valueFactory  a function mapping a pair of
     *                      {@code (key, parameter) -> value}
     * @throws NullPointerException if {@code subKeyFactory} or
     *                              {@code valueFactory} is null.
     */
  
    public WeakCache(BiFunction<K, P, ?> subKeyFactory,
                     BiFunction<K, P, V> valueFactory) {
        this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
        this.valueFactory = Objects.requireNonNull(valueFactory);
    }

再回顾一下 proxyClassCache 是如何利用 WeakCache 创建的

private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

通过指定的两个参数来构建 一个指定分别指定 K P V 泛型的 WeakCache 类,这个指定类型 K P V 和两个构造参数贯穿了整个代理对像的创建流程。这两个参数一定要对应好:

两个参数

  • BiFunction<K, P, ?> subKeyFactory - > new KeyFactory()
  • BiFunction<K, P, V> valueFactory -> new ProxyClassFactory()

K P V

  • K key 值 ->ClassLoader : 代理对象的类加载器
  • P 参数值 ->Class[]<?> : 代理对象实现的接口数组
  • V value值 -> Class<?>:需要的代理类对象

构造函数

创建 ProcyClassCache 变量对应的 WeakCache 构造函数的参数有两个,结合注释可以知道这两个参数的作用:

  • new KeyFactory():通过 key 和 p 生成 subKey
  • new ProxyClassFactory() :通过 key 和 p 生成 value

key 传进来的是ClassLoader进行包装后的对象,p 是代理对象实现的参数数组,最终生成的 value 就是我们需要的代理类对象

private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
        = new ConcurrentHashMap<>();

结合这个二级缓存可以推测:

  • 通过构造函数传进来的 keyFactory 根据代理对象的类加载器和接口数据生成 subKey
  • 根据 subKey 查找 Suppler 类,即代理对象,如果有则返回;否则根据 代理对象的ClassLoader 和 interfaces 生成代理类

前面说了,proxyClassCache 对象的 get 方法其实是 WeakCache 类的 get 方法,接下来看一下 WeakCache 对象的 get 方法。

5.WeakCache 对象的get方法

Proxy 类 下getProxyClass0 的方法最后 return proxyClassCache.get(loader, interfaces);

由前面的分析可以得到 其实这个 get 方法就是 WeakCache 的 get 方法

 /**
  * Look-up the value through the cache. This always evaluates the
  * {@code subKeyFactory} function and optionally evaluates
  * {@code valueFactory} function if there is no entry in the cache for given pair of (key, subKey) or the entry has already been cleared.
  *
  * @param key       possibly null key
  * @param parameter parameter used together with key to create sub-key and
  *                  value (should not be null)
  * @return the cached value (never null)
  * @throws NullPointerException if {@code parameter} passed in or
  *                              {@code sub-key} calculated by
  *                              {@code subKeyFactory} or {@code value}
  *                              calculated by {@code valueFactory} is null.
  */
public V get(K key, P parameter) {
    // 检查p 不为空,这里的p 就是类接口数组
    Objects.requireNonNull(parameter);
	// 清除无效的缓存
    expungeStaleEntries();
	// cacheKey就是(key, sub-key) -> value里的一级key,
    Object cacheKey = CacheKey.valueOf(key, refQueue);

    // lazily install the 2nd level valuesMap for the particular cacheKey
    // 根据一级key得到 ConcurrentMap<Object, Supplier<V>>对象。如果之前不存在,则新建一个ConcurrentMap<Object, Supplier<V>>和cacheKey(一级key)一起放到map中。

    ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
    if (valuesMap == null) {
        ConcurrentMap<Object, Supplier<V>> oldValuesMap
            = map.putIfAbsent(cacheKey,
                              valuesMap = new ConcurrentHashMap<>());
        if (oldValuesMap != null) {
            valuesMap = oldValuesMap;
        }
    }

    // create subKey and retrieve the possible Supplier<V> stored by that
    // subKey from valuesMap
    // subKeyFactory.apply 方法生成 sub-key
    Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
    // 根据二级索引的sub-key查到 supper ,其实就是 factory
    Supplier<V> supplier = valuesMap.get(subKey);
    Factory factory = null;

    while (true) {
        // 如果这个 二级map里面有 suppier,直接通过 get 方法获得代理对象返回
        if (supplier != null) {
            // supplier might be a Factory or a CacheValue<V> instance
            V value = supplier.get();
            if (value != null) {
                return value;
            }
        }
        // else no supplier in cache
        // or a supplier that returned null (could be a cleared CacheValue
        // or a Factory that wasn't successful in installing the CacheValue)
		
        // 若缓存中没有supplier,则创建一个Factory对象,把factory对象在多线程安全的环境下安全的赋值给supplier因为是while(true)当中,赋值成功后又get方法,返回才结束
        // lazily construct a Factory
        if (factory == null) {
            factory = new Factory(key, parameter, subKey, valuesMap);
        }

        if (supplier == null) {
            supplier = valuesMap.putIfAbsent(subKey, factory);
            if (supplier == null) {
                // successfully installed Factory
                supplier = factory;
            }
            // else retry with winning supplier
        } else {
            if (valuesMap.replace(subKey, supplier, factory)) {
                // successfully replaced
                // cleared CacheEntry / unsuccessful Factory
                // with our Factory
                supplier = factory;
            } else {
                // retry with current supplier
                supplier = valuesMap.get(subKey);
            }
        }
    }
}

看着有点乱,这段代码的核心逻辑:

此前的核心变量: 二级缓存

ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> 中的第一个 Object 就相当于一个一级 key,第二个Object 相当于 sub-key,Supplier 相当于 value

private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
        = new ConcurrentHashMap<>();
  1. 生成一级key :根据传入的key(代理对象的类加载器)和引用队列生成一级 key
 Object cacheKey = CacheKey.valueOf(key, refQueue);
  1. 根据一级key得到 ConcurrentMap<Object, Supplier<V>>对象。如果之前不存在,则新建一个ConcurrentMap<Object, Supplier<V>>cacheKey(一级key)一起放到map中
ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
  1. 生成sub -key: 通过传入的构造函数中keyFactory生成 sub-key,通过 sub-key 得到 Supplier<V>
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
Supplier<V> supplier = valuesMap.get(subKey);

生成 sub-key 的代码(了解)

private static final class KeyFactory implements BiFunction<ClassLoader, Class<?>[], Object>
{
    @Override
    public Object apply(ClassLoader classLoader, Class<?>[] interfaces){
        switch (interfaces.length) {
            case 1: return new Key1(interfaces[0]); // the most frequent
            case 2: return new Key2(interfaces[0], interfaces[1]);
            case 0: return key0;
            default: return new KeyX(interfaces);
        }
    }
}
  1. 如果Suplier 不为空,则直接调用 get 方法,得到代理对象,返回结束。否则创建一个 Factory 对象,把factory对象在多线程的环境下安全的赋给supplier
if (supplier != null) {
    // supplier might be a Factory or a CacheValue<V> instance
    V value = supplier.get();
	if (value != null) {
		return value;
	}
}

6. Factory 类的 get 方法

        public synchronized V get() { // serialize access
            // re-check
            Supplier<V> supplier = valuesMap.get(subKey);
            //重新检查得到的supplier是不是当前对象
            if (supplier != this) {
                // something changed while we were waiting:
                // might be that we were replaced by a CacheValue
                // or were removed because of failure ->
                // return null to signal WeakCache.get() to retry
                // the loop
                return null;
            }
            // else still us (supplier == this)

            // create new value
            V value = null;
            try {
                 //代理类就是在这个位置调用valueFactory生成的
                 //valueFactory就是我们传入的 new ProxyClassFactory()
                
                value = Objects.requireNonNull(valueFactory.apply(key, parameter));
            } finally {
                if (value == null) { // remove us on failure
                    valuesMap.remove(subKey, this);
                }
            }
            // the only path to reach here is with non-null value
            assert value != null;

            // wrap value with CacheValue (WeakReference)
            //把value包装成弱引用
            CacheValue<V> cacheValue = new CacheValue<>(value);

            // put into reverseMap
            // reverseMap是用来实现缓存的有效性
            reverseMap.put(cacheValue, Boolean.TRUE);

            // try replacing us with CacheValue (this should always succeed)
            if (!valuesMap.replace(subKey, this, cacheValue)) {
                throw new AssertionError("Should not reach here");
            }

            // successfully replaced us with new CacheValue -> return the value
            // wrapped by it
            return value;
        }
    }

其实最终的代理对象就是这句代码生成的: valueFactory 就是我们最开始在构造参数里传入的 new ProxyClassFactory()

value = Objects.requireNonNull(valueFactory.apply(key, parameter));

7 . ProxyClassFactory 的 apply 方法

 //这里的BiFunction<T, U, R>是个函数式接口,可以理解为用T,U两种类型做参数,得到R类型的返回值
private static final class ProxyClassFactory
        implements BiFunction<ClassLoader, Class<?>[], Class<?>>
    {
        // prefix for all proxy class names
        //所有代理类名字的前缀
        private static final String proxyClassNamePrefix = "$Proxy";
        
        // next number to use for generation of unique proxy class names
        //用于生成代理类名字的计数器
        private static final AtomicLong nextUniqueNumber = new AtomicLong();

        @Override
        public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
              
            Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
            //验证代理接口,可不看
            for (Class<?> intf : interfaces) {
                /*
                 * Verify that the class loader resolves the name of this
                 * interface to the same Class object.
                 */
                Class<?> interfaceClass = null;
                try {
                    interfaceClass = Class.forName(intf.getName(), false, loader);
                } catch (ClassNotFoundException e) {
                }
                if (interfaceClass != intf) {
                    throw new IllegalArgumentException(
                        intf + " is not visible from class loader");
                }
                /*
                 * Verify that the Class object actually represents an
                 * interface.
                 */
                if (!interfaceClass.isInterface()) {
                    throw new IllegalArgumentException(
                        interfaceClass.getName() + " is not an interface");
                }
                /*
                 * Verify that this interface is not a duplicate.
                 */
                if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
                    throw new IllegalArgumentException(
                        "repeated interface: " + interfaceClass.getName());
                }
            }
            //生成的代理类的包名 
            String proxyPkg = null;     // package to define proxy class in
            //代理类访问控制符: public ,final
            int accessFlags = Modifier.PUBLIC | Modifier.FINAL;

            /*
             * Record the package of a non-public proxy interface so that the
             * proxy class will be defined in the same package.  Verify that
             * all non-public proxy interfaces are in the same package.
             */
            //验证所有非公共的接口在同一个包内;公共的就无需处理
            //生成包名和类名的逻辑,包名默认是com.sun.proxy,类名默认是$Proxy 加上一个自增的整数值
            //如果被代理类是 non-public proxy interface ,则用和被代理类接口一样的包名
            for (Class<?> intf : interfaces) {
                int flags = intf.getModifiers();
                if (!Modifier.isPublic(flags)) {
                    accessFlags = Modifier.FINAL;
                    String name = intf.getName();
                    int n = name.lastIndexOf('.');
                    String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
                    if (proxyPkg == null) {
                        proxyPkg = pkg;
                    } else if (!pkg.equals(proxyPkg)) {
                        throw new IllegalArgumentException(
                            "non-public interfaces from different packages");
                    }
                }
            }

            if (proxyPkg == null) {
                // if no non-public proxy interfaces, use com.sun.proxy package
                proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
            }

            /*
             * Choose a name for the proxy class to generate.
             */
            long num = nextUniqueNumber.getAndIncrement();
            //代理类的完全限定名,如com.sun.proxy.$Proxy0.calss
            String proxyName = proxyPkg + proxyClassNamePrefix + num;

            /*
             * Generate the specified proxy class.
             */
            //核心部分,生成代理类的字节码
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);
            try {
                //把代理类加载到JVM中,至此动态代理过程基本结束了
                return defineClass0(loader, proxyName,
                                    proxyClassFile, 0, proxyClassFile.length);
            } catch (ClassFormatError e) {
                /*
                 * A ClassFormatError here means that (barring bugs in the
                 * proxy class generation code) there was some other
                 * invalid aspect of the arguments supplied to the proxy
                 * class creation (such as virtual machine limitations
                 * exceeded).
                 */
                throw new IllegalArgumentException(e.toString());
            }
        }
    }

这里主要的代码逻辑:

  1. 验证所有非公共的接口在同一个包内;公共的就无需处理。
  2. 生成包名和类名的逻辑,包名默认是com.sun.proxy,类名默认是$Proxy 加上一个自增的整数值。如果被代理类是 non-public proxy interface ,则用和被代理类接口一样的包名
/*
	* Choose a name for the proxy class to generate.
 */
long num = nextUniqueNumber.getAndIncrement();
//代理类的完全限定名,如com.sun.proxy.$Proxy0.calss
String proxyName = proxyPkg + proxyClassNamePrefix + num;
  1. 生成类的字节码
/*
 	* Generate the specified proxy class.
*/
    //核心部分,生成代理类的字节码
    byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
        proxyName, interfaces, accessFlags);
    try {
        //把代理类加载到JVM中,至此动态代理过程基本结束了
        return defineClass0(loader, proxyName,
                            proxyClassFile, 0, proxyClassFile.length);

JDK 生成的动态代理字节码

public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
        //注意一定要返回接口,不能返回实现类否则会报错
        Fruit fruit = (Fruit) DynamicAgent.agent(Fruit.class, new Apple());
        // 如果光将代理的内部类拿出来,那么当前类就为代理类,直接在main方法内返回代理对象
        // Friut fruit = Proxy.newProxyInstance(Reflect.class.getClassLoader(), new class[] {Friut}, new MyHandler(new ProxyPattern.Apple()));
        fruit.show();
        String path = "E:/$Proxy0.class";
        // 生成的代理字节码文件
        byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy0", Fruit.class.getInterfaces());
        FileOutputStream out = null;

        try {
            out = new FileOutputStream(path);
            out.write(classFile);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

字节码文件 .Class

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

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy {
    private static Method m1;
    private static Method m2;
    private static Method m0;

    // 构造函数,参数正是 InvocationHandler
    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }
	
    // Object 的三个方法 equals, toString, hashCode
    public final boolean equals(Object var1) throws  {
        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() 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 int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

return cons.newInstance(new Object[]{h});

从前面看到最后的返回语句正是把 InvocationHandler 当做代理类的构造函数来初始化代理类,在字节码文件中也可以看到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值