美文网首页
JDK动态代理

JDK动态代理

作者: Audience0 | 来源:发表于2019-11-27 10:05 被阅读0次

    开发:
    1.目标接口:

    package com.bj.zl.learn.mybatis.proxy.dynamic;
    
    /**
     * 代理目标类
     */
    public interface TargetClass {
    
        void say();
    }
    

    2.目标实现类

    package com.bj.zl.learn.mybatis.proxy.dynamic;
    
    public class TargetClassImpl implements TargetClass {
        @Override
        public void say() {
            System.out.println("say~!");
        }
    }
    

    3.代理类

    /**
    * create by Administrator
    * 2019-11-25
    */
    package com.bj.zl.learn.mybatis.proxy.dynamic;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    /**
    * 动态代理类,但不是真正的代理类,真正的代理类是JDK自动生成的
    *
    * InvocationHandler 需要实现这个接口
    */
    public class PoxyClass implements InvocationHandler {
       //持有一个目标类的引用
       Object target;
    
       public PoxyClass(Object target) {
           this.target = target;
       }
    
       /**
        * 对目标方法的增强
        * @param proxy   表示的是JDK自动生成的代理类
        * @param method
        * @param args 参数
        * @return
        * @throws Throwable
        */
       @Override
       public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
           System.out.println("增强前............");
    
           Object object = method.invoke(target,args);
           System.out.println("增强后............");
           return object;
       }
    }
    

    4.测试类

    /**
     * create by Administrator
     * 2019-11-25
     */
    package com.bj.zl.learn.mybatis.proxy.dynamic;
    
    import java.lang.reflect.Proxy;
    
    public class Client {
    
        public static void main(String[] args) {
            //是否对JDK生成的代理类进行保存
            String name = "sun.misc.ProxyGenerator.saveGeneratedFiles";
            System.setProperty(name,"true");
    
    
            TargetClass targetClass = new TargetClassImpl();
            //代理类
            TargetClass poxyTarget = (TargetClass)Proxy.newProxyInstance(Client.class.getClassLoader(),
                    new Class<?>[]{TargetClass.class},
                    new PoxyClass(targetClass));
    
            poxyTarget.say();
        }
    }
    
    

    5.自动生成的代理类

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package com.sun.proxy;
    
    import com.bj.zl.learn.mybatis.proxy.dynamic.TargetClass;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.lang.reflect.UndeclaredThrowableException;
    //自动生成的代理类,会实现目标接口,并且继承JDK的Proxy类
    //重写目标接口方法,Object类的方法
    public final class $Proxy0 extends Proxy implements TargetClass {
        private static Method m1;
        private static Method m2;
        private static Method m3;
        private static Method m0;
       //InvocationHandler  即我们写的动态代理类
        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})).booleanValue();
            } 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 void say() throws  {
            try {
                super.h.invoke(this, m3, (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)).intValue();
            } 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");
                m3 = Class.forName("com.bj.zl.learn.mybatis.proxy.dynamic.TargetClass").getMethod("say");
                m0 = Class.forName("java.lang.Object").getMethod("hashCode");
            } catch (NoSuchMethodException var2) {
                throw new NoSuchMethodError(var2.getMessage());
            } catch (ClassNotFoundException var3) {
                throw new NoClassDefFoundError(var3.getMessage());
            }
        }
    }
    
    

    Proxy.newProxyInstance 的解析

             /*
             * 1.获取JDK自动生成的代理类Class
             */
            Class<?> cl = getProxyClass0(loader, intfs);
              //  2.获取自动生成的代理类的构造器
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            //3.生成代理类对象
            cons.newInstance(new Object[]{h});
    

    Class<?> cl = getProxyClass0(loader, intfs);说明

     /*
                 * Generate the specified proxy class.生成JDK代理类的Class文件,二进制Class
                 */
                byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                    proxyName, interfaces, accessFlags);
    

    相关文章

      网友评论

          本文标题:JDK动态代理

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