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"); } }
运行结果