• 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());
            }
        }
    }
    
    
  • 相关阅读:
    struct中的字段顺序的大小
    go web之CSRF库的使用方式和实现原理
    Go进阶23:Go指针返回值的劣势(译)
    16 Transformer 的编码器(Encodes)——我在做更优秀的词向量
    13 MultiHead SelfAttention(从空间角度解释为什么做多头)
    07 预训练语言模型的下游任务改造简介(如何使用词向量)
    11 SelfAttention相比较 RNN和LSTM的优缺点
    1401 位置编码公式详细理解补充
    08 ELMo模型(双向LSTM模型解决词向量多义问题)
    09 什么是注意力机制(Attention )
  • 原文地址:https://www.cnblogs.com/bigfly277/p/11990856.html
Copyright © 2020-2023  润新知