1. 程式人生 > >【趣味設計模式系列】之【代理模式2--JDK動態代理原始碼解析】

【趣味設計模式系列】之【代理模式2--JDK動態代理原始碼解析】

## 1. 圖解 ![](https://img2020.cnblogs.com/blog/1765702/202008/1765702-20200813090502793-1476832292.png) 上圖主要描述了JDK動態代理的執行過程,下面做詳細分析。 ## 2. Proxy原始碼分析 上一篇,在使用JDK動態代理的時候,藉助於`Proxy`類,使用`newProxyInstance`靜態方法,建立了動態代理物件,這個方法接收三個引數,分別是目標類的類載入器、目標類實現的介面陣列、自定義的`InvocationHandler`類,下面從該方法開始,詳細分析該類如何生成的。本文所用`JDK`版本為`1.8.0_161`,為了保留原始碼英文註釋的原汁原味,未對英文註釋做刪減,並在程式碼後面加註中文註釋。 ``` public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) throws IllegalArgumentException { Objects.requireNonNull(h);// 驗證InvocationHandler不為空 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); //獲取引數型別是InvocationHandler.class的代理類構造器 final InvocationHandler ih = h; if (!Modifier.isPublic(cl.getModifiers())) { //如果代理類是不可訪問的, 就使用特權將它的構造器設定為可訪問 AccessController.doPrivileged(new Privileg