Java动态代理你会了吗?

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

运行结果





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值