Java动态代理
参考文档: https://www.cnblogs.com/whirly/p/10154887.html
本文将介绍的Java动态代理与设计模式中的代理模式有关,什么是代理模式呢?
代理模式:给某一个对象提供一个代理,并由代理对象来控制对真实对象的访问。代理模式是一种结构型设计模式。
代理模式角色分为 3 种:
Subject(抽象主题角色):定义代理类和真实主题的公共对外方法,也是代理类代理真实主题的方法;
RealSubject(真实主题角色):真正实现业务逻辑的类;
Proxy(代理主题角色):用来代理和封装真实主题;
代理模式的结构比较简单,其核心是代理类,为了让客户端能够一致性地对待真实对象和代理对象,在代理模式中引入了抽象层
代理模式类图
代理模式按照职责(使用场景)来分类,至少可以分为以下几类:1、远程代理。 2、虚拟代理。 3、Copy-on-Write 代理。 4、保护(Protect or Access)代理。 5、Cache代理。 6、防火墙(Firewall)代理。 7、同步化(Synchronization)代理。 8、智能引用(Smart Reference)代理等等。
如果根据字节码的创建时机来分类,可以分为静态代理和动态代理:
所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和真实主题角色的关系在运行前就确定了。
而动态代理的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以在运行前并不存在代理类的字节码文件
接下来我们使用代码实现动态代理
被代理类接口
1 2 3 4
| public interface Client { void getUp(); void sleep(); }
|
被代理类实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class ClientImpl implements Client{ private String name; public ClientImpl(String name) { this.name = name; }
@Override public void sleep() { System.out.println(name+"睡觉了"); }
public void getUp(){ System.out.println(name+"起床了"); } }
|
逻辑控制器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
import java.lang.reflect.*;
public class ClientProxy implements InvocationHandler {
private Object target; private Object proxy; private String name;
public Object getProxy() { return proxy; }
public ClientProxy(Object _target) throws NoSuchFieldException, IllegalAccessException { target=_target; Class<?> c = _target.getClass(); ClassLoader classLoader = c.getClassLoader(); Class<?>[] interfaces = c.getInterfaces(); this.proxy = Proxy.newProxyInstance(classLoader, interfaces, this); Field _name = c.getDeclaredField("name"); _name.setAccessible(true); this.name = (String)_name.get(target); }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { xl(); Object invoke = method.invoke(target, args); xz(); return invoke; }
public void xl() throws NoSuchFieldException, IllegalAccessException { System.out.println(name+"洗脸刷牙"); } public void xz(){ System.out.println(name+"洗脸刷牙洗澡"); } }
|
main方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class Test {
public static void main(String[] args) { ClientImpl target=new ClientImpl("李四"); ClientProxy clientProxy= null; try { clientProxy = new ClientProxy(target); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } Client proxy=(Client) clientProxy.getProxy(); proxy.getUp();
ProxyUtils.generateClassFile(clientProxy.getClass(), "ClientImplProxy"); } }
|
ProxyUtils
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class ProxyUtils {
public static void generateClassFile(Class clazz, String proxyName) { byte[] classFile = ProxyGenerator.generateProxyClass(proxyName, clazz.getInterfaces()); String paths = clazz.getResource(".").getPath(); System.out.println(paths); FileOutputStream out = null; try { out = new FileOutputStream(paths + proxyName + ".class"); out.write(classFile); out.flush(); } catch (Exception e) { e.printStackTrace(); } finally { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } }
|
反编译后的代理类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException;
public final class ClientImplProxy extends Proxy implements InvocationHandler { private static Method m1; private static Method m2; private static Method m3; private static Method m0; public ClientImplProxy(InvocationHandler var1) throws { super(var1); }
public final boolean equals(Object var1) throws { try { return (Boolean)super.h.invoke(this, m1, new Object[]{var1}); } 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 Object invoke(Object var1, Method var2, Object[] var3) throws Throwable { return (Object)super.h.invoke(this, m3, new Object[]{var1, var2, var3}); }
public final int hashCode() throws { try { return (Integer)super.h.invoke(this, m0, (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")); m2 = Class.forName("java.lang.Object").getMethod("toString"); m3 = Class.forName("java.lang.reflect.InvocationHandler").getMethod("invoke", Class.forName("java.lang.Object"), Class.forName("java.lang.reflect.Method"), Class.forName("[Ljava.lang.Object;")); m0 = Class.forName("java.lang.Object").getMethod("hashCode"); } catch (NoSuchMethodException var2) { throw new NoSuchMethodError(var2.getMessage()); } catch (ClassNotFoundException var3) { throw new NoClassDefFoundError(var3.getMessage()); } } }
|
动态代理逻辑图