美文网首页
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