JavaSE進階
14.7 反射的應用:動態(tài)代理
14.7.1 Java動態(tài)代理
- 之前為大家講解過代理機制的操作,屬于靜態(tài)代理,特征是代理類和目標對象的類都是在編譯期間確定下來,不利于程序的擴展。同時,每一個代理類只能為一個接口服務,這樣一來程序開發(fā)中必然產生過多的代理。
- 最好可以通過一個代理類完成全部的代理功能
- 動態(tài)代理是指客戶通過代理類來調用其它對象的方法,并且是在程序運行時根據需要動態(tài)創(chuàng)建目標類的代理對象。
- 動態(tài)代理使用場合:
- 調試
- 遠程方法調用
- 代理設計模式的原理:
???? 使用一個代理將對象包裝起來, 然后用該代理對象取代原始對象. 任何對原始對象的調用都要通過代理. 代理對象決定是否以及何時將方法調用轉到原始對象上.
- Proxy :專門完成代理的操作類,是所有動態(tài)代理類的父類。通過此類為一個或多個接口動態(tài)地生成實現(xiàn)類。
- 提供用于創(chuàng)建動態(tài)代理類和動態(tài)代理對象的靜態(tài)方法
- static?Class<?> getProxyClass(ClassLoader?loader, Class<?>...?interfaces)? 創(chuàng)建一個動態(tài)代理類所對應的Class對象
- static?Object newProxyInstance(ClassLoader?loader, Class<?>[]?interfaces, InvocationHandler?h)? 直接創(chuàng)建一個動態(tài)代理對象
ClassLoader : 類加載器
Class<?>[] : 得到全部的接口
InvocationHandler : 得到InvocationHandler接口的子類實例
14.7.2 動態(tài)代理步驟
1.創(chuàng)建一個實現(xiàn)接口InvocationHandler的類,它必須實現(xiàn)invoke方法,以完成代理的具體操作。
public Object invoke(Object theProxy, Method method, Object[] params) throws Throwable{
??????? try
??????? {
???????? Object retval = method.invoke(targetObj, params);
???????? // Print out the result
?????????? System.out.println(retval);
??????????? return retval;
??????? }
????? catch (Exception exc){}
Object theProxy : 被代理對象
Method method : 要調用的方法
Object[] params : 方法調用時所需要的參數
2.創(chuàng)建被代理的類以及接口
3.通過Proxy的靜態(tài)方法
newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 創(chuàng)建一個Subject接口代理
?? RealSubject target = new RealSubject();
// Create a proxy to wrap the original implementation
?????????? ?DebugProxy proxy = new DebugProxy(target);
?// Get a reference to the proxy through the Subject interface
???????? ?Subject sub = (Subject) Proxy.newProxyInstance(
??????????? Subject.class.getClassLoader(),
??????????? new Class[] { Subject.class }, proxy);
4.通過 Subject代理調用RealSubject實現(xiàn)類的方法
?? ??String info = sub.say(“Peter", 24);
???? System.out.println(info);