JDK动态代理原理

接口

public interface Task {
    void doSomething(String things);
    String makeSomething(String seed);
}

实现类

public class TaskImpl implements Task {

    @Override
    public void doSomething(String things) {
        System.out.println("I'm doing it : " + things);
    }

    @Override
    public String makeSomething(String seed) {
        return seed + "--" + seed;
    }
}

InvocationHandler

public class TaskInvocationHandler implements InvocationHandler {

    /**
     * 代理对象
     */
    private Object obj;

    public TaskInvocationHandler(Object obj) {
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result;
        try{
            System.out.println("You are calling : " + method.getName());
            result = method.invoke(obj, args);
        } catch (InvocationTargetException e) {
            throw e;
        } catch (Exception e) {
            throw e;
        }
        return result;
    }
}

动态代理工厂

public class TaskInvocationHandlerFactory {
    public static Object newInstance(Object obj, Class clazz, InvocationHandler invocationHandler) {
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                new Class[]{clazz}, invocationHandler);
    }
}

测试代码

public class App {

    public static void main(String[] args) {
        //查看生成的代理类
        //项目目录:E:\workspace\idea\snDemo\com\sun\proxy\$Proxy0.class
        //System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
        //$Proxy0.class ---->  $Proxy0.txt
        TaskImpl task = new TaskImpl();
        Task taskProxy = (Task) TaskInvocationHandlerFactory.newInstance(task, Task.class, new TaskInvocationHandler(task));
        taskProxy.doSomething("WTF");
        String result = taskProxy.makeSomething("test");
        System.out.println(result);
    }
}

查看生成的代理类

项目目录:E:\workspace\idea\snDemo\com\sun\proxy\$Proxy0.class
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");

代理类代码

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 implements Task {

    private static Method m1;
    private static Method m4;
    private static Method m3;
    private static Method m0;
    private static Method m2;

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

    //实际调用的是InvocationHandler的invoke方法
    public final String makeSomething(String var1) throws  {
        try {
            return (String)super.h.invoke(this, m4, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    //实际调用的是InvocationHandler的invoke方法
    public final void doSomething(String var1) throws  {
        try {
            super.h.invoke(this, m3, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

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

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

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));

            //反射获取方法
            m4 = Class.forName("cn.suning.invocation.Task").getMethod("makeSomething", Class.forName("java.lang.String"));
            m3 = Class.forName("cn.suning.invocation.Task").getMethod("doSomething", Class.forName("java.lang.String"));

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

原理

taskProxy的类型是 $Proxy0,taskProxy.doSomething 方法相当于调用 $Proxy0 类中的 doSomething  方法

//实际调用的是InvocationHandler的invoke方法
public final void doSomething(String var1) throws  {
        try {
            super.h.invoke(this, m3, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
}

而 super.h.invoke 相当于调用TaskInvocationHandler类中的invoke的方法

@Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result;
        try{
            System.out.println("You are calling : " + method.getName());
            //被代理方法调用
            result = method.invoke(obj, args);
        } catch (InvocationTargetException e) {
            throw e;
        } catch (Exception e) {
            throw e;
        }
        return result;
    }

TaskInvocationHandler 怎么传递给 $Proxy0 的呢

$Proxy0 继承 Proxy ,Proxy 中有变量 InvocationHandler h

public class Proxy implements java.io.Serializable {

    private static final long serialVersionUID = -2222568056686623797L;

     ...............此处省略部分代码..................

     * the invocation handler for this proxy instance.
     * @serial
     */
    protected InvocationHandler h;
}

然后通过 TaskInvocationHandlerFactory 的 newInstance 方法传递

public class TaskInvocationHandlerFactory {
    public static Object newInstance(Object obj, Class clazz, InvocationHandler invocationHandler) {
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                new Class[]{clazz}, invocationHandler);
    }
}

 

你可能感兴趣的:(Java,jdk动态代理)