【趣味設計模式系列】之【代理模式2--JDK動態代理原始碼解析】
阿新 • • 發佈:2020-08-13
## 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