动态代理原理名词解释(动态代理原理)
简介
java.lang.reflect.Proxy是整个jdk中实现动态代理的核心 类 ,本文主要介绍Proxy类的实现 ,关于Proxy类的使用请自行查阅其他资料 。
Field
constructorParams:构造函数的参数,用于代理类的核心的逻辑实现 ,关于InvocationHandler这个接口的介绍不是本文的重点 ,此处不做介绍 。
private static final Class<?>[] constructorParams = { InvocationHandler.class };proxyClassCache: 代理类的缓存 ,此类是一个二级缓存的实现 ,利用WeakReference的特性 ,当内存占用过高的时候会JVM自动进行回收缓存中的数据。
private static final WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());h: InvocationHandler接口 ,用于此代理实例的调用处理程序 。
Inner Class
KeyFactory:顾名思义 ,缓存代理的key的工厂实现 ,此类仅一个方法 ,实现了BiFunction接口,具体代码如下
private static final class KeyFactory implements BiFunction<ClassLoader, Class<?>[], Object>{ @Override public Object apply(ClassLoader classLoader, Class<?>[] interfaces) { switch (interfaces.length) { case 1: return new Key1(interfaces[0]); // the most frequent case 2: return new Key2(interfaces[0], interfaces[1]); case 0: return key0; default: return new KeyX(interfaces); } }}由以上代码可见 ,该类的实现分为委托给了Key0,Key1,Key2,KeyX这四个类实现 ,其中key0是一个Object,其他的类Key1,Key2,KeyX则是分别用不同的实现对hashcode和equals方法进行了不同的实现 ,大同小异 。这里则分别简单的做一下解释 。
private static final class Key1 extends WeakReference<Class<?>> { private final int hash; Key1(Class<?> intf) { super(intf); this.hash = intf.hashCode(); } @Override public int hashCode() { return hash; } @Override public boolean equals(Object obj) { Class<?> intf; return this == obj || obj != null && obj.getClass() == Key1.class && (intf = get()) != null && intf == ((Key1) obj).get(); }} private static final class Key2 extends WeakReference<Class<?>> { private final int hash; private final WeakReference<Class<?>> ref2; Key2(Class<?> intf1, Class<?> intf2) { super(intf1); hash = 31 * intf1.hashCode() + intf2.hashCode(); ref2 = new WeakReference<Class<?>>(intf2); } @Override public int hashCode() { return hash; } @Override public boolean equals(Object obj) { Class<?> intf1, intf2; return this == obj || obj != null && obj.getClass() == Key2.class && (intf1 = get()) != null && intf1 == ((Key2) obj).get() && (intf2 = ref2.get()) != null && intf2 == ((Key2) obj).ref2.get(); }} private static final class KeyX { private final int hash; private final WeakReference<Class<?>>[] refs; @SuppressWarnings("unchecked") KeyX(Class<?>[] interfaces) { hash = Arrays.hashCode(interfaces); refs = (WeakReference<Class<?>>[])new WeakReference<?>[interfaces.length]; for (int i = 0; i < interfaces.length; i++) { refs[i] = new WeakReference<>(interfaces[i]); } } @Override public int hashCode() { return hash; } @Override public boolean equals(Object obj) { return this == obj || obj != null && obj.getClass() == KeyX.class && equals(refs, ((KeyX) obj).refs); } private static boolean equals(WeakReference<Class<?>>[] refs1, WeakReference<Class<?>>[] refs2) { if (refs1.length != refs2.length) { return false; } for (int i = 0; i < refs1.length; i++) { Class<?> intf = refs1[i].get(); if (intf == null || intf != refs2[i].get()) { return false; } } return true; }}ProxyClassFactory: 顾名思义 , 代理类的生产工厂类,用于生成代理类 ,此类也是实现了BiFunction,技能一个apply方法 ,最终根据ClassLoader,Interface,proxyName参数调用java.lang.reflect.Proxy#defineClass0这个本地方法生成代理类 。
private static final class ProxyClassFactory implements BiFunction<ClassLoader, Class<?>[], Class<?>>{ // 代理类名称的前缀 ,我们看到的代理类的名称都有这个前缀就是这个原因 private static final String proxyClassNamePrefix = "$Proxy"; // 用于生成代理类名称的唯一的序号 private static final AtomicLong nextUniqueNumber = new AtomicLong(); @Override public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) { Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length); for (Class<?> intf : interfaces) { /* * 验证类加载器是否将此接口的名称解析为同一类对象 */ Class<?> interfaceClass = null; try { interfaceClass = Class.forName(intf.getName(), false, loader); } catch (ClassNotFoundException e) { } if (interfaceClass != intf) { throw new IllegalArgumentException( intf + " is not visible from class loader"); } /* * 验证此类实际是否是一个接口 */ if (!interfaceClass.isInterface()) { throw new IllegalArgumentException( interfaceClass.getName() + " is not an interface"); } /* * 校验接口是不重复的 */ if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) { throw new IllegalArgumentException( "repeated interface: " + interfaceClass.getName()); } } // 代理类包名 String proxyPkg = null; //代理类的访问修饰符 int accessFlags = Modifier.PUBLIC | Modifier.FINAL; /* * 记录非public的代理接口的包 ,以至于代理类的定义是相同的包 ,验证所有的非public的代理接口在相同的包中 。 */ for (Class<?> intf : interfaces) { int flags = intf.getModifiers(); if (!Modifier.isPublic(flags)) { accessFlags = Modifier.FINAL; String name = intf.getName(); int n = name.lastIndexOf(.); String pkg = ((n == -1) ? "" : name.substring(0, n + 1));创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!