首页 / 资讯中心 / 文章详情

Proxy.newProxyInstance源码探究

Proxy.newProxyInstance源码探究 ★ FEATURED ARTICLE
源码仓库Gitee·GitHubJDK动态代理案例实现实现 InvocationHandler 接口重写 invoke 方法其中包含一个对象变量和提供一个包含对象的构造方法public class MyInvocationHandler implements InvocationHandler { Object target;//目标对象 public MyInvocationHandler(Object target){ this.targettarget; } /** * param proxy 代理对象 * param method 目标对象的目标方法 * param args 目标方法的参数 */ Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(log); return method.invoke(target,args); } }public class MyInvocationHandlerTest { public static void main(String[] args) { //参数 当前类的classLoader保证MyInvocationHandlerTest当前类可用 // 接口数组通过接口反射得到接口里面的方法对接口里面的所有方法都进行代理 // 实现的InvocationHandler参数是目标对象 UserDao jdkproxy (UserDao) Proxy.newProxyInstance(MyInvocationHandlerTest.class.getClassLoader(), new Class[]{UserDao.class},new MyInvocationHandler(new UserService())); jdkproxy.query(query); //-----结果------ //log //query } }接下来查看Proxy.newProxyInstance源码探究它的实现过程public static Object newProxyInstance(ClassLoader loader, Class?[] interfaces, InvocationHandler h) throws IllegalArgumentException { //检查InvocationHandler是否为空为空抛出空指针异常 Objects.requireNonNull(h); //克隆拿到接口 final Class?[] intfs interfaces.clone(); //进行安全校验 final SecurityManager sm System.getSecurityManager(); //检查是否能被代理 if (sm ! null) { checkProxyAccess(Reflection.getCallerClass(), loader, intfs); } /* * Look up or generate the designated proxy class. * 得到代理类 */ Class? cl getProxyClass0(loader, intfs); /* * Invoke its constructor with the designated invocation handler. */ try { if (sm ! null) { checkNewProxyPermission(Reflection.getCallerClass(), cl); } //通过构造方法得到代理类的对象 final Constructor? cons cl.getConstructor(constructorParams); final InvocationHandler ih h; if (!Modifier.isPublic(cl.getModifiers())) { AccessController.doPrivileged(new PrivilegedActionVoid() { public Void run() { cons.setAccessible(true); return null; } }); } //new得到代理对象 return cons.newInstance(new Object[]{h}); } catch (IllegalAccessException|InstantiationException e) { throw new InternalError(e.toString(), e); } catch (InvocationTargetException e) { Throwable t e.getCause(); if (t instanceof RuntimeException) { throw (RuntimeException) t; } else { throw new InternalError(t.toString(), t); } } catch (NoSuchMethodException e) { throw new InternalError(e.toString(), e); } }从上面可以看出Class? cl getProxyClass0(loader, intfs);这行代码最重要它可以得到一个代理对象下面是Proxy#getProxyClass0的源码private static Class? getProxyClass0(ClassLoader loader, Class?... interfaces) { if (interfaces.length 65535) { throw new IllegalArgumentException(interface limit exceeded); } // If the proxy class defined by the given loader implementing // the given interfaces exists, this will simply return the cached copy; // otherwise, it will create the proxy class via the ProxyClassFactory //如果接口的代理类已经存在缓存中了直接从缓存中取出来返回如果不存在则通过ProxyClassFactory创建一个并放入缓存中供下次使用 return proxyClassCache.get(loader, interfaces); }proxyClassCache.get()的实现在WeakCache#get()中public V get(K key, P parameter) { Objects.requireNonNull(parameter); expungeStaleEntries(); //从缓存中取出代理类的key值因为代理类的生成需要耗时间和性能所有缓存起来方便下次直接使用 Object cacheKey CacheKey.valueOf(key, refQueue); // lazily install the 2nd level valuesMap for the particular cacheKey ConcurrentMapObject, SupplierV valuesMap map.get(cacheKey); if (valuesMap null) { ConcurrentMapObject, SupplierV oldValuesMap map.putIfAbsent(cacheKey, valuesMap new ConcurrentHashMap()); if (oldValuesMap ! null) { valuesMap oldValuesMap; } } // create subKey and retrieve the possible SupplierV stored by that // subKey from valuesMap 获取到接口信息 Object subKey Objects.requireNonNull(subKeyFactory.apply(key, parameter)); SupplierV supplier valuesMap.get(subKey); Factory factory null; //开始进来supplier是null所以执行后面的代码创建一个Factory然后赋值给supplier while (true) { if (supplier ! null) { // supplier might be a Factory or a CacheValueV instance //获取到代理类 V value supplier.get(); if (value ! null) { //返回代理类 return value; } } // else no supplier in cache // or a supplier that returned null (could be a cleared CacheValue // or a Factory that wasnt successful in installing the CacheValue) // lazily construct a Factory if (factory null) { factory new Factory(key, parameter, subKey, valuesMap);//通过接口信息和classLoader创建一个工厂 } if (supplier null) { supplier valuesMap.putIfAbsent(subKey, factory); if (supplier null) { // successfully installed Factory supplier factory; } // else retry with winning supplier } else { if (valuesMap.replace(subKey, supplier, factory)) { // successfully replaced // cleared CacheEntry / unsuccessful Factory // with our Factory supplier factory;//将工厂赋值给supplier } else { // retry with current supplier supplier valuesMap.get(subKey); } } } }下面查看supplier.get()WeakCache.Factory#get()public synchronized V get() { // serialize access // re-check SupplierV supplier valuesMap.get(subKey); if (supplier ! this) { // something changed while we were waiting: // might be that we were replaced by a CacheValue // or were removed because of failure - // return null to signal WeakCache.get() to retry // the loop return null; } // else still us (supplier this) // create new value V value null; try { //创建获取到value value Objects.requireNonNull(valueFactory.apply(key, parameter)); } finally { if (value null) { // remove us on failure valuesMap.remove(subKey, this); } } // the only path to reach here is with non-null value assert value ! null; // wrap value with CacheValue (WeakReference) CacheValueV cacheValue new CacheValue(value);//根据代理类创建一个缓存对象 // put into reverseMap reverseMap.put(cacheValue, Boolean.TRUE);//将代理放入缓存中 // try replacing us with CacheValue (this should always succeed) if (!valuesMap.replace(subKey, this, cacheValue)) { throw new AssertionError(Should not reach here); } // successfully replaced us with new CacheValue - return the value // wrapped by it return value; }接下来查看Objects.requireNonNull()中的apply方法Proxy.ProxyClassFactory#apply()public Class? apply(ClassLoader loader, Class?[] interfaces) { //获取到所有实现接口 MapClass?, Boolean interfaceSet new IdentityHashMap(interfaces.length); //遍历所有接口 for (Class? intf : interfaces) { /* * Verify that the class loader resolves the name of this * interface to the same Class object. */ Class? interfaceClass null; try { //对接口再次装载相当classLoader.loadClass interfaceClass Class.forName(intf.getName(), false, loader); } catch (ClassNotFoundException e) { } //判断两个接口是不是同一个接口同一个类加载器加载的判断对象是否是同一个 if (interfaceClass ! intf) { throw new IllegalArgumentException( intf is not visible from class loader); } /* * Verify that the Class object actually represents an * interface. */ if (!interfaceClass.isInterface()) { throw new IllegalArgumentException( interfaceClass.getName() is not an interface); } /* * Verify that this interface is not a duplicate. */ 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; /* * Record the package of a non-public proxy interface so that the * proxy class will be defined in the same package. Verify that * all non-public proxy interfaces are in the same package. */ for (Class? intf : interfaces) { int flags intf.getModifiers(); //判断接口的类型是否是public如果不是public将代理类放到目标对象同一目录下 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 //默认定义包名 //public static final String PROXY_PACKAGE com.sun.proxy; proxyPkg ReflectUtil.PROXY_PACKAGE .; } /* * Choose a name for the proxy class to generate. */ long num nextUniqueNumber.getAndIncrement(); //标识private static final String proxyClassNamePrefix $Proxy; //随机数防止多线程测试相同的类名long num nextUniqueNumber.getAndIncrement(); //代理类的名字代理包名 标识 随机数 String proxyName proxyPkg proxyClassNamePrefix num; /* * Generate the specified proxy class. * 产生指定的代理类信息是二进制信息可以使用IO流输出代理类的Java文件可查看前文有介绍 * ProxyGenerator.generateProxyClass()是一个静态方法所以可以外部直接调用 */ byte[] proxyClassFile ProxyGenerator.generateProxyClass( proxyName, interfaces, accessFlags); try { //产生代理类返回一个class将byte字节码转换成class //defineClass0是一个native方法由JVM实现的private static native Class? defineClass0(); return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length); } catch (ClassFormatError e) { /* * A ClassFormatError here means that (barring bugs in the * proxy class generation code) there was some other * invalid aspect of the arguments supplied to the proxy * class creation (such as virtual machine limitations * exceeded). */ throw new IllegalArgumentException(e.toString()); } }
阅读完成 · 觉得有帮助?
咨询建站