筆記14:設計模式之動態代理
阿新 • • 發佈:2018-12-18
代理模式
* 概念:
1. 真實物件:被代理的物件
2. 代理物件:
3. 代理模式:代理物件代理真實物件,達到增強真實物件功能的目的
* 實現方式:
1. 靜態代理:有一個類檔案描述代理模式
2. 動態代理:在記憶體中形成代理類
* 實現步驟:
1. 代理物件和真實物件實現相同的介面
2. 代理物件 = Proxy.newProxyInstance();
3. 使用代理物件呼叫方法。
4. 增強方法
* 增強方式:
1. 增強引數列表
2. 增強返回值型別
3. 增強方法體執行邏輯
動態代理程式碼演示 1.共同的介面
public interface SaleComputer { public String sale(double money); public void show(); }
2.真實類
/**
* 真實類
*/
public class Lenovo implements SaleComputer {
@Override
public String sale(double money) {
System.out.println("花了"+money+"錢買了一臺聯想電腦");
return "聯想電腦";
}
@Override
public void show() {
System.out.println("展示電腦...");
}
}
3.代理類
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyTest { public static void main(String[] args) { //1.建立真實物件 Lenovo lenovo = new Lenovo(); //動態代理增強lenovo方法 /*該方法的三個引數: * 1.類載入器: 真實物件.getClass().getClassLoader() * 2.介面陣列: 真實物件.getClass().getInterfaces() * 3.處理器: new InvocationHandler() {} -->編寫代理的邏輯 */ //Proxy.newProxyInstance()方法返回的是一個代理物件,可以將這個代理物件轉成介面物件 SaleComputer proxy_lenovo = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() { //代理邏輯編寫的方法,代理物件呼叫的所有方法都會觸發該方法的執行 /*該方法的三個引數: * 1.proxy : 代理物件 * 2.method : 該方法會將代理物件呼叫的方法封裝成為一個物件,method就是那個封裝後的物件 * 3.args : 代理物件呼叫方法時,實際傳遞的引數 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { /* System.out.println("該方法執行了..."); System.out.println(method.getName()); System.out.println(args[0]);*/ //判斷是否是sale方法--是sale方法才增強 if (method.getName().equals("sale")) { //增強引數 double money = (double) args[0]; money = money * 0.85; System.out.println("專車接駕...");//增強方法體的邏輯 //使用真實物件呼叫該方法--代理物件本身是無法呼叫真實物件的方法的,真實物件呼叫方法然後將結果交給代理物件 Object obj = method.invoke(lenovo, money); System.out.println("免費送貨到家...");//增強方法體的邏輯 //增強返回值 return obj + "_滑鼠墊"; } else {//不是sale方法就原樣執行(該咋執行咋執行) Object obj = method.invoke(lenovo, args); return obj; } } }); //2.使用代理物件呼叫方法 String computer = proxy_lenovo.sale(8000); System.out.println(computer); //lenovo.show(); //proxy_lenovo.show(); } }