Proxy代理模式

定義:代理一個(gè)對象,去執(zhí)行對象的方法。

使用場景:根據(jù)開閉原則,很多時(shí)候我們不能去直接修改被代理的實(shí)現(xiàn)類,而又要增加業(yè)務(wù)邏輯,這時(shí)可以使用代理模式。

舉例:比如我們調(diào)用一個(gè)第三方接口的方法,現(xiàn)在有個(gè)新需求,在執(zhí)行某個(gè)方法前,需要記錄日志,我們無法修改第三方接口,這時(shí)可以使用代理模式。

優(yōu)點(diǎn):程序擴(kuò)展性、可維護(hù)性增強(qiáng),無需更改以前的實(shí)現(xiàn)。

1.? 靜態(tài)代理

對每一個(gè)需要被代理的類,新增一個(gè)代理類;

1.1 支付接口

public interface PayService {

????void pay();

}

1.2 被代理對象,實(shí)現(xiàn)支付接口

public class PayServiceImpl implements PayService{

? ? @Override

? ? public void pay() {

? ? ? ? System.out.println("支付完成");

? ? }

}

1.3 代理類,實(shí)現(xiàn)支付接口

public class StaticProxy implements PayService{

? ? private PayService payService;

? ? public StaticProxy(PayService payService) {

? ? ? ? this.payService = payService;

? ? }

? ? @Override

? ? public void pay() {

? ? ? ? System.out.println("支付日志記錄...");

? ? ????payService.pay();

? ? }

}

1.4 調(diào)用示例:

public class StaticProxyMain {

? ? public static void main(String[] args) {

? ? ? ? PayService payService = new PayServiceImpl();

? ? ? ? StaticProxy proxy = new StaticProxy(payService);

? ? ? ? proxy.pay();

? ? }

}

打印結(jié)果如下:

支付日志記錄...

支付完成

2.動(dòng)態(tài)代理

采用InvocationHandler實(shí)現(xiàn),InvocationHandler是一個(gè)JDK提供的標(biāo)準(zhǔn)接口。在動(dòng)態(tài)代理實(shí)現(xiàn)時(shí),無需指定被代理的類,在具體調(diào)用時(shí)再指定。

2.1 重寫代理類

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

public class DynamicProxy implements InvocationHandler{

? ? private Object obj;

? ? public DynamicProxy(Object obj) {

? ? ? ? this.obj = obj;

? ? }

? ? @Override

? ? public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

? ? ? ? Object result = method.invoke(this.obj, args);

? ? ? ? return result;

? ? }

}

2.2 調(diào)用示例

import java.lang.reflect.Proxy;

public class DynamicProxyMain {

? ? public static void main(String[] args) {

? ? ? ? PayService payService = new PayServiceImpl();

? ? ? ? DynamicProxy proxy = new DynamicProxy(new PayServiceImpl());

? ? ? ? PayService payServiceProxy = (PayService) Proxy.newProxyInstance(payService.getClass().getClassLoader(),? ? ? ? ????????????payService.getClass().getInterfaces(), proxy);

? ? ? ? System.out.println("支付日志記錄...");

? ? ? ? payServiceProxy.pay();

? ? }

}

打印結(jié)果和上面是一致的. 下面這段代碼返回PayService,但并不是PayServiceImpl的實(shí)例,而是JVM給我們加過工的,包含了我們在invoke方法里的實(shí)現(xiàn)。debug,payServiceProxy類型為$Proxy0

PayService payServiceProxy = (PayService) Proxy.newProxyInstance(payService.getClass().getClassLoader(), payService.getClass().getInterfaces(), proxy);

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

友情鏈接更多精彩內(nèi)容