文章目錄
- 1.概念
- 1.1 什么是代理模式
- 1.2 優點與缺點
- 2.實現方式
- 2.1 靜態代理
- 2.2 動態代理
- 3. Java 哪些地方用到了代理模式
- 4. Spring 哪些地方用到了代理模式
1.概念
1.1 什么是代理模式
代理模式
(Proxy Pattern)是一種結構型設計模式,它允許通過一個代理對象來控制對另一個對象的訪問。
1.2 優點與缺點
優點:
1.可以控制對真實對象的訪問。
2.可以延遲真實對象的創建,減少系統開銷。
3.可以提供額外的服務,如緩存、權限檢查等。
缺點:
1.增加了系統的復雜性,因為引入了額外的代理類。
2.可能會降低系統的性能,因為代理會增加一層間接調用。
2.實現方式
2.1 靜態代理
// Image接口
public interface Image {void display();
}// RealImage類,實現了Image接口
public class RealImage implements Image {private String fileName;// 構造函數,加載圖像public RealImage(String fileName) {this.fileName = fileName;loadImageFromDisk();}// 加載圖像的模擬方法private void loadImageFromDisk() {System.out.println("Loading " + fileName);}// 顯示圖像@Overridepublic void display() {System.out.println("Displaying " + fileName);}
}// Image代理類
public class ImageProxy implements Image {private String fileName;private Image realImage;// 構造函數public ImageProxy(String fileName) {this.fileName = fileName;}// 顯示圖像,如果真實圖像尚未加載,則先加載@Overridepublic void display() {if (realImage == null) {realImage = new RealImage(fileName);}realImage.display();}
}// 測試類
public class ProxyPatternDemo {public static void main(String[] args) {Image image = new ImageProxy("test_10mb.jpg");// 圖像將從磁盤加載image.display();System.out.println("");// 圖像不需要從磁盤加載image.display();}
}
2.2 動態代理
動態代理通常使用java.lang.reflect.Proxy類和java.lang.reflect.InvocationHandler接口來實現。
// Image接口
public interface Image {void display();
}// RealImage類,實現了Image接口
public class RealImage implements Image {private String fileName;// 構造函數,加載圖像public RealImage(String fileName) {this.fileName = fileName;loadImageFromDisk();}// 加載圖像的模擬方法private void loadImageFromDisk() {System.out.println("Loading " + fileName);}// 顯示圖像@Overridepublic void display() {System.out.println("Displaying " + fileName);}
}// 動態代理類
public class DynamicImageProxy {public static Image newInstance(String fileName) {return (Image) java.lang.reflect.Proxy.newProxyInstance(Image.class.getClassLoader(),new Class[]{Image.class},new java.lang.reflect.InvocationHandler() {private Image realImage = null;@Overridepublic Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws Throwable {if (realImage == null) {realImage = new RealImage(fileName);}return method.invoke(realImage, args);}});}
}// 測試類
public class ProxyPatternDemo {public static void main(String[] args) {Image image = DynamicImageProxy.newInstance("test_10mb.jpg");// 圖像將從磁盤加載image.display();System.out.println("");// 圖像不需要從磁盤加載image.display();}
}
3. Java 哪些地方用到了代理模式
RMI
(Remote Method Invocation): Java的RMI機制使用代理模式來實現遠程對象的透明訪問。RMI系統提供的代理類將遠程方法調用轉換為對遠程對象的調用。
JDBC
(Java Database Connectivity): JDBC驅動程序管理器使用代理模式來加載和實例化JDBC驅動程序。當應用程序請求連接到數據庫時,代理會加載適當的驅動程序并建立連接。
動態代理
: Java的動態代理機制允許在運行時創建代理類和代理實例。這通常用于AOP(面向切面編程)框架,如Spring AOP,其中代理用于在目標對象的方法調用前后執行增強代碼。
事件監聽器
: 在Swing或其他GUI框架中,事件監聽器使用代理模式來處理事件。事件源將事件委托給事件監聽器,后者作為事件處理的代理。
延遲加載
: 在Hibernate或其他ORM框架中,代理模式用于實現延遲加載。代理對象代表真實對象,并在真正需要訪問對象數據時才加載數據。
保護代理
: 在需要控制對資源的訪問時,可以使用保護代理來檢查調用者的權限,并根據權限決定是否允許訪問資源。
智能引用
: 在需要跟蹤對象的使用情況時,可以使用智能代理來記錄對象的使用次數、最后使用時間等信息。
4. Spring 哪些地方用到了代理模式
AOP
(面向切面編程): Spring AOP使用代理模式來實現方法攔截。Spring的AopProxy類充當代理,它根據配置創建代理對象,并在目標對象的方法調用前后執行增強代碼。
事務管理
: Spring的事務管理器使用代理模式來管理事務。TransactionInterceptor類充當代理,它在目標方法執行前后管理事務的開啟、提交或回滾。
事件發布
: Spring的事件驅動模型使用代理模式來解耦事件的生產者和消費者。ApplicationEventMulticaster類充當代理,它將事件發布給所有注冊的監聽器。
Web集成
: Spring的Web模塊使用代理模式來集成不同的Web框架。例如,DispatcherServlet充當代理,它將HTTP請求轉換為Spring MVC框架的調用。
資源訪問
: Spring的ResourceLoader和Resource接口使用代理模式來抽象不同類型的資源訪問。ResourceLoader的實現類充當代理,它們將資源訪問的調用轉換為具體文件系統、類路徑或URL的訪問。
消息服務
: Spring的JMS(Java消息服務)集成使用代理模式來適配不同的消息中間件。JmsTemplate和JmsListenerContainerFactory類充當代理,它們將Spring的消息抽象轉換為具體的消息中間件操作。