// 创建jdk动态代理 UserService jdkProxy = (UserService) Proxy.newProxyInstance(UserService.class.getClassLoader(), new Class[]{UserService.class}, handler); 复制代码
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException // 删除了影响阅读的异常捕获部分,并加上了响应注释。 // 拦截处理器不能为空 为空抛出异常 Objects.requireNonNull(h); // 防御性拷贝 避免修改 interfaces数组对象的属性 final Class<?>[] intfs = interfaces.clone(); // 获取java安全管理器 final SecurityManager sm = System.getSecurityManager(); // 安全管理器不为空 if (sm != null) { // 校验代理参数访问权限 checkProxyAccess(Reflection.getCallerClass(), loader, intfs); } // 1. 寻找或生成代理类信息 即 Class对象 Class<?> cl = getProxyClass0(loader, intfs); try { if (sm != null) { checkNewProxyPermission(Reflection.getCallerClass(), cl); } // 2. 根据类信息对象c1生成构造器 final Constructor<?> cons = cl.getConstructor(constructorParams); final InvocationHandler ih = h; // 设置构造起访问权限 if (!Modifier.isPublic(cl.getModifiers())) { AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run() { cons.setAccessible(true); return null; } }); } // 3. 用构造器生成代理对象 将h拦截处理器设置到代理对象中 return cons.newInstance(new Object[]{h}); } 复制代码
我们看到关键代码注释1、2、3。得知生成代理类逻辑:生成代理类的class对象c1--> 根据class对象c1生成类构造器对象cons--> 根据构造器cons生成代理。
private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) { // 接口数组超过65535抛出异常 if (interfaces.length > 65535) { throw new IllegalArgumentException("interface limit exceeded"); } // 如果通过给定类加载器定义并实现指定接口的代理类的class对象存在,则直接返回。 // 否则通过ProxyClassFactory创建代理类的class对象 return proxyClassCache.get(loader, interfaces); } 复制代码
我们看到proxyClassCache.get方法是生成代理类class对象的关键。
public V get(K key, P parameter) { // 忽略其他代码我们只看 创建代理Class的代码 // 创建subkey Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter)); // 根据subkey 找回可能的被存储的supplier Supplier<V> supplier = valuesMap.get(subKey); V value = supplier.get(); // 返回代理类Class对象 return value; } 复制代码
这里用到了缓存机制获取代理类Class对象,我们在第三节进行详细讲述。
因为JDK动态代理类继承了Proxy类,Java又是单继承的,所以被代理对象只能通过实现接口,让代理对象生成相应接口的实现。
那么,问题来了。为什么JDK动态代理要继承Proxy类呢?留给大家思考!
第一节生成的动态代理类
public final class $Proxy0 extends Proxy implements UserService { private static Method m1; private static Method m2; private static Method m0; private static Method m3; public $Proxy0(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 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); } } public final void addUser() throws { try { super.h.invoke(this, m3, (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"); m0 = Class.forName("java.lang.Object").getMethod("hashCode"); m3 = Class.forName("com.java24k.example.service.UserService").getMethod("addUser"); } catch (NoSuchMethodException var2) { throw new NoSuchMethodError(var2.getMessage()); } catch (ClassNotFoundException var3) { throw new NoClassDefFoundError(var3.getMessage()); } } } 复制代码