思想: 通過代理對象來創建目標對象, 間接的可對目標對象進行前置或後置處理(即擴展了目標對象);
代理對象調用目標對象的接口實現對目標對象的調用
- 角色
- 靜態代理
- 定義抽象類, 代理類和目標類均實現此抽象類的方法, 客戶端調用代理類中的實現方法能調用到目標類相同實現方法;
- 優點: 不修改目標類對象的情況下進行擴展;
- 缺點: 代理類和目標類都要實現抽象類, 當目標類數量大時, 對抽象類加了方法後需要對其子類更新;
- JKD動態代理(目標對象要實現接口時適用)
- 只有目標類一方需要實現接口, 代理類則利用JDK提供的方法在內存中進行構建;
- cglib代理(屬於動態代理, 目標對象沒實現接口時適用)
- 代理類和目標類均不用實現接口, 通過cglib.jar利用攔截器實現;
- 靜態代理案例
- JDK動態代理案例
- 在內存中構建代理對象時同樣動態的實現了目標對象實現的接口, 代理對象最終還是通過接口的method來調用到目標對象的method;
- cglib動態代理案例
- cglib實現原理: 同靜態和JDK代理一樣, cglib在內存中對目標類新增了一個接口(接口中的方法包含了目標對象方法), 代理對象和目標對象一同實現了接口, 代理對象通過調用實現方法來調用目標對象;
- 注意事項
- 代理類不能是final, 否則會報錯;
- 目標對象的方法不能是final/static, 否則不會進入攔截;
- 常見的幾種代理變體
- 防火牆代理
- 內網通過代理穿透防火牆, 從而實現對外網的訪問;
- 緩存代理
- 如Maven的私服庫, 當需要的jar沒有時通過中央庫下載到私服, 再由私服下到本地;
- 遠程調用
- 阿里的Dubbo其遠程過程調用, 把遠程對象當本地對象調用;