JDK动态代理源码分析

Posted bigfly277

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK动态代理源码分析相关的知识,希望对你有一定的参考价值。

JDK动态代理源码分析

本文我们思路主要分三点:

  1. 简单分析一下静态代理
  2. 按照JDK动态代理源码的思路我们手写一个低配版的动态代理
  3. 阅读JDK动态代理源码

1、静态代理

本环节的知识比较基础,如果对代理比较了解的朋友可以跳过

不管是静态代理还是动态代理目的都是为了给方法增强,静态代理主要实现方式有继承和聚合两种,在了解这两种之前我们先来了解一下代理中的几个比较重要的名词

  1. 目标类:我们需要增强的类
  2. 代理类:增强后的类

1.1、继承

只要代理类实现目标类,重写目标方法就可以了

/**
 * 目标类
 */
public class Target {

    public void targetMethod(){
        System.out.println("targetMethod...");
    }
}
/**
 *  静态代理 继承 代理类
 */
public class ExtendsTargetProxy extends Target {

    @Override
    public void targetMethod() {
        System.out.println("before ExtendsTargetProxy...");
        super.targetMethod();
        System.out.println("end ExtendsTargetProxy...");
    }
}
/**
 * 测试
 */
public class Client {

    public static void main(String[] args) {

        ExtendsTargetProxy proxy = new ExtendsTargetProxy();
        proxy.targetMethod();

    }
}

运行结果:

技术图片

1.2、聚合

代理类和目标类要实现同一个接口

/**
 * 代理接口
        */
public interface Target {

    void targetMethod();
}
/**
 * 目标类
 */
public class TargetImpl implements Target {
    @Override
    public void targetMethod() {
        System.out.println("TargetImpl...");
    }
}
/**
 * 代理类
 */
public class TargetImplProxy implements Target {
    private Target target;

    public TargetImplProxy (Target target){
        this.target = target;
    }

    @Override
    public void targetMethod() {
        System.out.println("before");
        target.targetMethod();
        System.out.println("end");
    }
}
/**
 * 测试类
 */
public class Client {
    public static void main(String[] args) {

        TargetImpl target = new TargetImpl();

        Target proxy = new TargetImplProxy(target);

        proxy.targetMethod();
    }
}

技术图片

1.3、总结

因为现实项目中,我们同一个目标类,在不同的情况下我们需要增强不同的功能,所以不管是使用继承还是聚合都会使我们项目中产生类爆炸。

2、手写JDK动态代理

2.1、抽取增强逻辑

/**
 * 代理接口
        */
public interface Target {

    String targetMethod(String s,int i);
}
/**
 * 目标类
 */
public class TargetImpl implements Target {
    @Override
    public String targetMethod(String a,int i) {
        System.out.println("TargetImpl...");
        return "OK";
    }
}
/**
 *  类似于 InvocationHandler
 */
public interface MyInvocationHandler {
    
    Object invoke(Object obj,Method method,Object[] args) throws Throwable;
}
import java.lang.reflect.Method;

public class TargetInvocationHandler implements MyInvocationHandler{
    private Object obj;

    /**
     * 接受一个代理类
     * @param obj
     */
    public TargetInvocationHandler(Object obj){
        this.obj = obj;
    }

    /**
     *  代理增强
     * @param o 代理类
     * @param method 目标方法
     * @param args 目标方法参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object o,Method method, Object[] args) throws Throwable {
        System.out.println("before");
        Object res = method.invoke(obj,args);
        System.out.println("end");
        return res;
    }
}
import java.lang.reflect.Method;

/**
 * 代理类
 */
public class TargetImplProxy implements Target {
    private Target target;

    private MyInvocationHandler h;

    public TargetImplProxy (Target target,MyInvocationHandler h){
        this.target = target;
        this.h = h;
    }

    @Override
    public String targetMethod(String s,int i) {
        try {
            Method method = Class.forName(target.getClass().getName()).getMethod("targetMethod",String.class,int.class);
            return (String) h.invoke(this,method,new Object[]{s,i});
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return null;
    }
}
/**
 * 测试类
 */
public class Client {
    public static void main(String[] args) throws Exception {

        TargetImpl target = new TargetImpl();

        Target proxy = new TargetImplProxy(target,new TargetInvocationHandler(target));

        proxy.targetMethod("",1);

    }
}

技术图片

2.2、动态生成TargetImplProxy

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import java.lang.reflect.Modifier;
import java.net.URL;
import java.net.URLClassLoader;

public class ProxyUtil {

    private static final String tab = "	";
    private static final String line = "
";



    public static Object newProxyInstance(Object target,MyInvocationHandler myInvocationHandler) throws Exception {
    //拼接class内容
        // 包名
        String packageName = "package com.proxy.myproxy;" + line;
        // 导入的包
        String importContent = "import com.proxy.learn.dynamicproxy.MyInvocationHandler;
"
                + "import java.lang.reflect.Method;"
                + "import "+target.getClass().getInterfaces()[0].getName()+";"
                + line;
        // 类开头
        Class<?>[] interfaces = target.getClass().getInterfaces();
        String interfaceName = interfaces[0].getSimpleName();

        String classContent = "public class $Proxy implements "+interfaceName+" {" + line;
        // 属性
        String attributeContent = tab + "private Target target;" + line
                + tab + "private MyInvocationHandler h;" + line;
        // 构造方法
        String constructContent = tab + "public $Proxy ("+interfaceName+" target,MyInvocationHandler h){
" +
                "        this.target = target;
" +
                "        this.h = h;
" +
                "}" +line;
        // 方法
        String methodContent = "";
        Method[] methods = target.getClass().getMethods();
        // 循环所有方法
        for(int i = 0 ; i < methods.length; i++){
            if(Modifier.isFinal(methods[i].getModifiers())){
                continue;
            }
            Class<?>[] parameterTypes = methods[i].getParameterTypes();
            // 参数
            // String p1,Integer p2
            String parameterTypeNames = "";
            // p1,p2
            String parameterNames = "new Object[]{";
            // String.class  int.class
            String parameterClassNames = "";
            for(int j = 0 ; j < parameterTypes.length ; j++){
                parameterTypeNames += parameterTypes[j].getSimpleName() + " " + "p" + j + ",";
                parameterClassNames += "," + parameterTypes[j].getSimpleName() + ".class";
                parameterNames += "p" + j + ",";
            }
            if (parameterTypes.length > 0){
                parameterTypeNames = parameterTypeNames.substring(0,parameterTypeNames.lastIndexOf(","));
                parameterNames = parameterNames.substring(0,parameterNames.lastIndexOf(","));
            }
            parameterNames += "}";
            if (parameterTypes.length <= 0){
                parameterNames = "null";
            }
            String returnType = methods[i].getReturnType().getSimpleName();
            String re = "";
            String re1 = "";
            String re2 = "";

            if(!"void".equals(returnType)){
                re = "return ";
                re1 = "return null; ";
                re2 = "("+returnType+")";

                switch (returnType){
                    case "int":
                        re1 = "return 0; ";
                        break;
                    case "boolean":
                        re1 = "return false; ";
                        break;
                    default:
                }
            }
            methodContent += tab + "public "+returnType+" "+methods[i].getName()+"("+parameterTypeNames+") {
" +
                    "        try {
" +
                    "            Method method = Class.forName(target.getClass().getName()).getMethod(""+methods[i].getName()+"" "+parameterClassNames+");
" +
                    "            "+re+""+re2+"h.invoke(this,method,"+parameterNames+");
" +
                    "        } catch (NoSuchMethodException e) {
" +
                    "            e.printStackTrace();
" +
                    "        } catch (ClassNotFoundException e) {
" +
                    "            e.printStackTrace();
" +
                    "        } catch (Throwable throwable) {
" +
                    "            throwable.printStackTrace();
" +
                    "        }
" +
                    "        "+re1+"" +
                    "    }"+line;

        }

        String content = packageName + importContent + classContent + attributeContent + constructContent + methodContent + "}";

        // 生成.java文件
        File filpath = new File("");
        //这里不判断文件夹了
        File file = new File(filpath.getAbsoluteFile()+"/src/com/proxy/myproxy/$Proxy.java");
        if(!file.exists()){
            file.createNewFile();
        }
        FileWriter fw = new FileWriter(file);
        fw.write(content);
        fw.flush();

        // 生成 .class 文件
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null,null,null);
        Iterable units = fileManager.getJavaFileObjects(file);
        JavaCompiler.CompilationTask task = compiler.getTask(null,fileManager,null,null,null,units);
        task.call();
        fileManager.close();

        String path = "file:"+filpath.getAbsoluteFile()+"\\src\\com\\proxy\\myproxy\\";
        URL newurl=new URL(path);
        URLClassLoader classLoader=new URLClassLoader(new URL[]{newurl});
        Class<?> methtClass = classLoader.loadClass("com.proxy.myproxy.$Proxy");
        Constructor constructor = methtClass.getConstructor(Target.class, MyInvocationHandler.class);
        return constructor.newInstance(target,myInvocationHandler);
    }

}
/**
 * 测试类
 */
public class Client {
    public static void main(String[] args) throws Exception {

        TargetImpl target = new TargetImpl();

//        Target proxy = new TargetImplProxy(target,new TargetInvocationHandler(target));
        Target proxy = (Target) ProxyUtil.newProxyInstance(target,new TargetInvocationHandler(target));

        proxy.targetMethod("",1);

    }
}

技术图片

这样我们就自己实现了一个简单版本的动态代理。

3、源码分析

3.1、Proxy.newProxyInstance

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {   
            // 校验
        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 详见 3.1.1
        Class<?> cl = getProxyClass0(loader, intfs);

        /*
         * Invoke its constructor with the designated invocation handler.
         */
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }

            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);
        }
    }

3.1.1、 Class<?> cl = getProxyClass0(loader, intfs);

/**
     * Generate a proxy class.  Must call the checkProxyAccess method
     * to perform permission checks before calling this.
     */
    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
        // 如果通过类加载器和接口去缓存里面拿,缓存没有就用·ProxyClassFactory·创建代理类
        // proxyClassCache 详见3.1.1.1
        // proxyClassCache.get(loader, interfaces) 详见 3.1.1.2
        return proxyClassCache.get(loader, interfaces);
    }

3.1.1.1、proxyClassCache

    /**
     * a cache of proxy classes
     */
        // 调用 WeakCache 构造方法
        // new KeyFactory() 详见 3.1.1.1.1
        // new ProxyClassFactory() 详见 3.1.1.2.2
        // new WeakCache<>(new KeyFactory(), new ProxyClassFactory()); 详见3.1.1.1.2
        // 
    private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
3.1.1.1.1、new KeyFactory()
/**
     * A function that maps an array of interfaces to an optimal key where
     * Class objects representing interfaces are weakly referenced.
     */
        // 我们只需要知道这个是根据classloader和接口生成subKey,subKey见3.1.1.1.2 WeakCache
    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);
            }
        }
    }
3.1.1.1.2、new WeakCache<>(new KeyFactory(), new ProxyClassFactory())
final class WeakCache<K, P, V> {

    private final ReferenceQueue<K> refQueue
        = new ReferenceQueue<>();
    // the key type is Object for supporting null key
  
    //这个map 就是缓存,结构是 (key,subKey)->value 格式
    // key:传进来的classloader包装对象
    // subKey: 上面 new KeyFactory() 生成的
    // value:   生成的代理类对象
    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);
    }
  
    ...
      
}

3.1.1.2、proxyClassCache.get(loader, interfaces);

/**
     * 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.
     */
        // K:classloader P:interface数组
    public V get(K key, P parameter) {
        // 判断parameter是否为空
        Objects.requireNonNull(parameter);
                // 清除无效的缓存
        expungeStaleEntries();
                // 生成 (key,subKey)
        Object cacheKey = CacheKey.valueOf(key, refQueue);

        // lazily install the 2nd level valuesMap for the particular cacheKey
        // 从缓存map中获取
        ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
        // 缓存中没有
        if (valuesMap == null) {
            // 创建一个空value放进map
            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
        // 生成subKey
        Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
        // 获取 supplier
        Supplier<V> supplier = valuesMap.get(subKey);
        Factory factory = null;

        while (true) {
            // 缓存里面要是有直接返回
            if (supplier != null) {
                // supplier might be a Factory or a CacheValue<V> instance
                // 详见 3.1.1.2.1
                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)

            // lazily construct a Factory
            // 如果缓存里面没有 生成supplier 放进map 然后while(ture)从前面get出来
            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);
                }
            }
        }
    }

3.1.1.2.1、supplier.get()

                @Override
        public synchronized V get() { // serialize access
            // re-check
            Supplier<V> supplier = valuesMap.get(subKey);
            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.apply(key, parameter):生成代理类详见下
                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)
            CacheValue<V> cacheValue = new CacheValue<>(value);

            // put into 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;
        }

3.1.1.2.2、valueFactory.apply(key, parameter)

用于生成代理类

private static final class ProxyClassFactory
        implements BiFunction<ClassLoader, Class<?>[], Class<?>>
    {
        // prefix for all proxy class names
            // class名字的前缀
        private static final String proxyClassNamePrefix = "$Proxy";
            
        // next number to use for generation of unique proxy class names
            // 计数器,用于生成class名字 $Proxy1 $Proxy2
        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.
             */
            
            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();
            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());
            }
        }
    }

3.2、JDK生成的动态代理代码

我们最后来看看核心代码

byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces, accessFlags);

到底为我们生成了什么

public static void main(String[] args) throws Exception {

        byte[] proxyClass = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{UserMapper.class});
        FileOutputStream outputStream = new FileOutputStream(new File("/Users/chengpengfei/Desktop/$Proxy0.class"));
        outputStream.write(proxyClass);
        outputStream.flush();
        outputStream.close();
    }

生成的文件放进idea看一下,是不是觉得跟我们自己写的动态代理生成的文件很像

//
// 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;
import proxy.UserMapper;

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

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

    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 void notify() throws  {
        try {
            super.h.invoke(this, m8, (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 logic() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final void wait(long var1) throws InterruptedException {
        try {
            super.h.invoke(this, m5, new Object[]{var1});
        } catch (RuntimeException | InterruptedException | Error var4) {
            throw var4;
        } catch (Throwable var5) {
            throw new UndeclaredThrowableException(var5);
        }
    }

    public final void wait(long var1, int var3) throws InterruptedException {
        try {
            super.h.invoke(this, m4, new Object[]{var1, var3});
        } catch (RuntimeException | InterruptedException | Error var5) {
            throw var5;
        } catch (Throwable var6) {
            throw new UndeclaredThrowableException(var6);
        }
    }

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

    public final void notifyAll() throws  {
        try {
            super.h.invoke(this, m9, (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);
        }
    }

    public final void wait() throws InterruptedException {
        try {
            super.h.invoke(this, m6, (Object[])null);
        } catch (RuntimeException | InterruptedException | 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"));
            m8 = Class.forName("proxy.UserMapper").getMethod("notify");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("proxy.UserMapper").getMethod("logic");
            m5 = Class.forName("proxy.UserMapper").getMethod("wait", Long.TYPE);
            m4 = Class.forName("proxy.UserMapper").getMethod("wait", Long.TYPE, Integer.TYPE);
            m7 = Class.forName("proxy.UserMapper").getMethod("getClass");
            m9 = Class.forName("proxy.UserMapper").getMethod("notifyAll");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
            m6 = Class.forName("proxy.UserMapper").getMethod("wait");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

以上是关于JDK动态代理源码分析的主要内容,如果未能解决你的问题,请参考以下文章

JDK动态代理[2]----JDK动态代理的底层实现之Proxy源码分析

JDK动态代理源码分析

JDK动态代理源码分析

设计模式3.2-- JDK动态代理源码分析有多香?

源码分析:Spring是如何跟JDK动态代理结合

源码分析:Spring是如何跟JDK动态代理结合