1、模式介紹:
代理模式(Proxy Pattern)是一種結構型設計模式,它允許你在不改變客戶端代碼的情況下,向某個對象提供一個代理,以控制對該對象的訪問。代理對象通常會在實際對象的方法調用前后添加一些附加邏輯,如權限控制、懶加載、日志記錄等。
代理模式涉及以下幾個角色:
接口(Subject):定義了代理類和真實類共同的接口。
真實類(RealSubject):實現了接口的具體類,它是真正執行操作的對象。
代理類(Proxy):也實現了接口,持有真實類的引用,并在調用真實類的方法前后進行一些額外的處理。
2、應用場景:
遠程代理(Remote Proxy):為一個對象在不同地址空間提供局部代表。典型應用是 RMI(遠程方法調用)。
虛擬代理(Virtual Proxy):根據需要創建開銷大的對象。它在真正需要時才創建對象。
保護代理(Protection Proxy):控制對原始對象的訪問。通常用于對象應該有不同的訪問權限。
智能引用(Smart Reference):在訪問對象時提供額外的功能,例如引用計數、緩存等。
3、優點:
控制對真實對象的訪問,增加系統的靈活性。
可以對真實對象進行擴展,而不修改其代碼。
提供了對目標對象額外的操作,如權限控制、延遲加載、日志記錄等。
4、缺點:
增加了系統的復雜度,尤其是在使用保護代理時。
可能會影響請求的處理速度,因為增加了間接層。
5、代碼實現:
/*** 代理接口** @author FM_南風* @date 2024/6/25 13:28*/
public interface Subject {void request();
}/*** 實體類** @author FM_南風* @date 2024/6/25 13:28*/
public class RealSubject implements Subject{@Overridepublic void request() {System.out.println("實體類的請求");}
}/*** 代理類** @author FM_南風* @date 2024/6/25 13:30*/
public class Proxy implements Subject {private RealSubject realSubject;@Overridepublic void request() {if (realSubject == null) {realSubject = new RealSubject();}preRequest();realSubject.request();postRequest();}private void preRequest() {System.out.println("代理類: 前置處理");}private void postRequest() {System.out.println("代理類: 后置處理");}
}/*** 應用** @author FM_南風* @date 2024/6/25 13:31*/
public class ProxyClient {public static void main(String[] args) {Subject proxy = new Proxy();proxy.request();}
}
6、結果展示:

7、拓展動態代理:
還可以使用動態代理來實現代理模式,它使用 java.lang.reflect.Proxy
類和 InvocationHandler
接口來動態地創建代理對象。動態代理可以在運行時動態地將代理邏輯添加到真實對象中,而不需要在編譯時顯式地創建代理類。
/*** 動態代理** @author FM_南風* @date 2024/6/25 13:37*/
public class ProxyInvocationHandler implements InvocationHandler {private Object realSubject;public ProxyInvocationHandler(Object realSubject) {this.realSubject = realSubject;}@Overridepublic Object invoke(Object o, Method method, Object[] objects) throws Throwable {System.out.println("動態代理類: 前置處理");Object result = method.invoke(realSubject, objects);System.out.println("動態代理類: 后置處理");return result;}
}/*** 動態代理應用** @author FM_南風* @date 2024/6/25 13:39*/
public class ProxyInvocationClient {public static void main(String[] args) {RealSubject realSubject = new RealSubject();Subject proxy = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),realSubject.getClass().getInterfaces(),new ProxyInvocationHandler(realSubject));proxy.request();}
}