Java动态代理你会了吗?

来源:互联网 发布:电脑vpn软件 编辑:程序博客网 时间:2024/04/28 12:13

java中动态代理有两种:一是jdk动态代理,二是Cglib动态代理Cglib jar包下载地址 https://mvnrepository.com/artifact/cglib/cglib/3.1 

一、jdk动态代理

package learn;import java.io.FileOutputStream;import java.io.IOException;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import sun.misc.ProxyGenerator;public class DynamicProxy {    public static void main(String[] args) throws IOException {       UserImpl user = new UserImpl("feng",22);        InvocationHandler handler = new MyHandler(user);              IUser proxy = (IUser)Proxy.newProxyInstance(UserImpl.class.getClassLoader(), user.getClass().getInterfaces(), handler);      System.out.println(proxy.getClass().getName());      proxy.say();      System.out.println(proxy.getAge());      //将内存中的代理类proxy 写入文件并用反编译查看 动态代理的执行过程。      byte[] data = ProxyGenerator.generateProxyClass("proxy", new Class[]{UserImpl.class});      FileOutputStream os = new FileOutputStream("user.class");      os.write(data);      os.close();              }}class MyHandler implements InvocationHandler{   IUser user;   public MyHandler(IUser user){      this.user = user;   }   @Override   public Object invoke(Object proxy, Method method, Object[] args)         throws Throwable {      System.out.println("before");      Object result = method.invoke(user, args);      System.out.println("after");      return result;   }}interface IUser{   public void say();   public int getAge();}class UserImpl implements IUser{      public UserImpl(String name, int age) {      super();      this.name = name;      this.age = age;   }   String name;   int age;   public void say() {      System.out.println("hello "+ this.name);   }   public int getAge() {      System.out.println("getAge()");      return age;   }   }

运行结果


生成的代理类proxy将它写入文件并反编译,得到

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.lang.reflect.UndeclaredThrowableException;import learn.UserImpl;public final class proxy extends Proxy implements UserImpl {    private static Method m1;    private static Method m9;    private static Method m2;    private static Method m7;    private static Method m6;    private static Method m8;    private static Method m3;    private static Method m4;    private static Method m10;    private static Method m0;    private static Method m5;    public proxy(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 void notify() throws  {        try {            super.h.invoke(this, m9, (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 wait(long var1) throws InterruptedException {        try {            super.h.invoke(this, m7, 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, m6, 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, m8, (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 getAge() throws  {        try {            return ((Integer)super.h.invoke(this, m4, (Object[])null)).intValue();        } catch (RuntimeException | Error var2) {            throw var2;        } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);        }    }    public final void notifyAll() throws  {        try {            super.h.invoke(this, m10, (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);        }    }    public final void wait() throws InterruptedException {        try {            super.h.invoke(this, m5, (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"));            m9 = Class.forName("learn.UserImpl").getMethod("notify");            m2 = Class.forName("java.lang.Object").getMethod("toString");            m7 = Class.forName("learn.UserImpl").getMethod("wait", Long.TYPE);            m6 = Class.forName("learn.UserImpl").getMethod("wait", Long.TYPE, Integer.TYPE);            m8 = Class.forName("learn.UserImpl").getMethod("getClass");            m3 = Class.forName("learn.UserImpl").getMethod("say");            m4 = Class.forName("learn.UserImpl").getMethod("getAge");            m10 = Class.forName("learn.UserImpl").getMethod("notifyAll");            m0 = Class.forName("java.lang.Object").getMethod("hashCode");            m5 = Class.forName("learn.UserImpl").getMethod("wait");        } catch (NoSuchMethodException var2) {            throw new NoSuchMethodError(var2.getMessage());        } catch (ClassNotFoundException var3) {            throw new NoClassDefFoundError(var3.getMessage());        }    }}
注意看看绿色地方,内存中生成的代理proxy,内部调用的是被代理对象中方法。

二、Cglib代理

package learn;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;import java.io.IOException;import java.lang.reflect.Method;public class CglibProxyTest {    public static void main(String[] args) throws IOException {        CglibProxy proxy = new CglibProxy();        //通过生成子类的方式创建代理类        SayHello proxyImp = (SayHello) proxy.getProxy(SayHello.class);        //查看代理类名称  结果是        System.out.println(proxyImp.getClass().getName());        proxyImp.say();        proxyImp.printName();    }}class CglibProxy implements MethodInterceptor {    private Enhancer enhancer = new Enhancer();    public Object getProxy(Class clazz) {        //设置需要创建子类的类        enhancer.setSuperclass(clazz);        enhancer.setCallback(this);        //通过字节码技术动态创建子类实例        return enhancer.create();    }    //实现MethodInterceptor接口方法    public Object intercept(Object obj, Method method, Object[] args,                            MethodProxy proxy) throws Throwable {        System.out.println("前置代理");        //通过代理类调用父类中的方法        Object result = proxy.invokeSuper(obj, args);        System.out.println("后置代理");        return result;    }}class SayHello {    public void say() {        System.out.println("hello everyone");    }    public void printName() {        System.out.println("feng");    }}

运行结果