JDK动态代理原理
来源:互联网 发布:印象笔记 for mac 编辑:程序博客网 时间:2024/05/21 19:48
public class ProxySubject implements InvocationHandler { private Object target; /** * @param obj * 真实对象 * @return 代理对象 */ public Object bind(Object obj) { this.target = obj; return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this); } /* * 返回调用实例方法的返回值 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(target); }}
动态代理实现原理
//动态代理类的参数类型private static final Class<?>[] constructorParams ={ InvocationHandler.class };protected InvocationHandler h;//构造方法私有化,不允许外部实例化对象,单例设计private Proxy() { }//有参的也被被封装起来,用protecct貌似是为了方便吧子类调用protected Proxy(InvocationHandler h) { Objects.requireNonNull(h); this.h = h; } //提供统一的获取代理类的实例方法(摘要主要的方法,其他省略) public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException {//类似有getClass,Class.forName()的一个获取Class对象的方法Class<?> cl = getProxyClass0(loader, intfs);//反射获得构造final Constructor<?> cons = cl.getConstructor(constructorParams); final InvocationHandler ih = h;//代理类返回实例化对象return cons.newInstance(new Object[]{h});}
private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) { if (interfaces.length > 65535) { throw new IllegalArgumentException("interface limit exceeded"); } //它将通过proxyclassfactory创建代理类 // 给定的接口存在,从缓存中获取 return proxyClassCache.get(loader, interfaces); }
private static final WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
KeyFactory获得类加载器和接口
ProxyClassFactory 获得真正的代理类
//这是代理类工厂类 private static final class ProxyClassFactory implements BiFunction<ClassLoader, Class<?>[], Class<?>> { //定义的名字前缀 private static final String proxyClassNamePrefix = "$Proxy"; // 生成的数,跟在$Proxy这个名字之后,JDK动态代理类的名字都是 $ProxyN (N=0,1,2,3,4,5,6,7,8) 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"); } //判断Class对象是否代表的是一个接口 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; // package to define proxy class in int accessFlags = Modifier.PUBLIC | Modifier.FINAL; 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)); if (proxyPkg == null) { proxyPkg = pkg; } else if (!pkg.equals(proxyPkg)) { throw new IllegalArgumentException( "non-public interfaces from different packages"); } } } if (proxyPkg == null) { // if no non-public proxy interfaces, use com.sun.proxy package proxyPkg = ReflectUtil.PROXY_PACKAGE + "."; } long num = nextUniqueNumber.getAndIncrement(); String proxyName = proxyPkg + proxyClassNamePrefix + num; //产生本地字节文件 byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces, accessFlags); try { //按照产生的字节码文件来产生动态代理类 return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length); } catch (ClassFormatError e) { throw new IllegalArgumentException(e.toString()); } } }
public static byte[] generateProxyClass(final String name, Class[] interfaces) { ProxyGenerator gen = new ProxyGenerator(name, interfaces); // 这里动态生成代理类的字节码,比较复杂 final byte[] classFile = gen.generateClassFile(); // 把所生成的代理类的字节码保存到硬盘上 if (saveGeneratedFiles) { java.security.AccessController.doPrivileged( new java.security.PrivilegedAction<Void>() { public Void run() { try { FileOutputStream file = new FileOutputStream(dotToSlash(name) + ".class"); file.write(classFile); file.close(); return null; } catch (IOException e) { throw new InternalError( "I/O exception saving generated file: " + e); } } }); } // 返回代理类的字节码 return classFile; }
JNI调用原生态方法
private static native Class<?> defineClass0(ClassLoader loader, String name,byte[] b, int off, int len);
1 0
- jdk动态代理原理
- JDK动态代理原理
- JDK动态代理原理
- jdk动态代理原理
- JDK动态代理原理
- JDK的动态代理原理
- JDK动态代理实现原理
- JDK动态代理实现原理
- JDK动态代理实现原理
- JDK动态代理实现原理
- jdk动态代理实现原理
- JDK动态代理实现原理
- JDK动态代理实现原理
- JDK动态代理实现原理
- JDK动态代理实现原理
- JDK动态代理实现原理
- JDK动态代理实现原理
- JDK动态代理实现原理
- 小白题解 Codeforces 798B Mike and strings
- android 动画实现之 Tween Animation(补间动画)
- 2017华东师范大学网赛-七巧板
- 搭建Ngrok实现树莓派内网穿透
- 编译Servlet时跳出下载文件对话框的问题
- JDK动态代理原理
- W2.3 Hadoop2.6安装
- ES6.0 类定义之私有变量与私有函数
- Android Gradle上传Maven仓库
- CSDN日报20170514 ——《聪明的老板才不招工资低的程序员》
- 用gradle构建java项目
- 蛇形输出
- 水题hdu Identity Card
- ReactNative调研报告