設計模式之代理模式(結構型)
第一章
1.1 模式定義
代理模式:代理模式就是引入一個代理物件,通過代理物件實現對原物件的引用。代理模式是一種物件結構型。
1.2 代理模式包含如下角色
- Subject:抽象主題角色
- Proxy:代理主題角色
- RealSubject:真實主題角色
[圖片上傳失敗...(image-d1d75e-1547891819525)]
1.3 模式例子
public class Proxy implements Subject
{
private RealSubject realSubject = new RealSubject();
public void preRequest()
{…...}
public void request()
{
preRequest();
realSubject.request();
postRequest();
}
public void postRequest()
{……}
}
1.4 模式型別
來自:《設計模式》一書歸納分類
- 遠端(Remote)代理:為一個位於不同的地址空間的物件提供一個本地的代理物件,這個不同的地址空間可以是在同一臺主機中,也可是在另一臺主機中,遠端代理又叫做大使(Ambassador)。
- 虛擬(Virtual)代理:如果需要建立一個資源消耗較大的物件,先建立一個消耗相對較小的物件來表示,真實物件只在需要時才會被真正建立。
- Copy-on-Write代理:它是虛擬代理的一種,把複製(克隆)操作延遲到只有在客戶端真正需要時才執行。一般來說,物件的深克隆是一個開銷較大的操作,Copy-on-Write代理可以讓這個操作延遲,只有物件被用到的時候才被克隆。
- 保護(Protect or Access)代理:控制對一個物件的訪問,可以給不同的使用者提供不同級別的使用許可權。
- 緩衝(Cache)代理:為某一個目標操作的結果提供臨時的儲存空間,以便多個客戶端可以共享這些結果。
- 防火牆(Firewall)代理:保護目標不讓惡意使用者接近。
- 同步化(Synchronization)代理:使幾個使用者能夠同時使用一個物件而沒有衝突。
- 智慧引用(Smart Reference)代理:當一個物件被引用時,提供一些額外的操作,如將此物件被呼叫的次數記錄下來等。
下面介紹一下靜態代理和動態代理
代理模式分為靜態代理和動態代理 • 靜態代理:靜態代理就是編譯階段就生成代理類來完成對代理物件的一系列操作。
• 動態代理:動態代理是指在執行時動態生成代理類。即,代理類的位元組碼將在執行時生成並載入當前代理的 ClassLoader。
第二章 靜態代理
靜態代理:靜態代理就是編譯階段就生成代理類來完成對代理物件的一系列操作。
主題介面:
public interface Subject {
abstract public void request();
}
目標物件:
public class RealSubject implements Subject {
public void request() {
System.out.println( " From real subject. " );
}
}
代理物件:
public class StaticProxySubject implements Subject {
private RealSubject realSubject; // 以真實角色作為代理角色的屬性
public ProxySubject() { }
public void request() { // 該方法封裝了真實物件的request方法
//懶載入,用的時候才載入
if ( realSubject == null ) {
realSubject = new RealSubject();
}
realSubject.request(); // 此處執行真實物件的request方法
}
}
編寫客戶端類:
public class Client{
StaticProxySubject sps = new StaticProxySubject();
sps.request();
}
第三章 動態代理
動態代理:動態代理是指在執行時動態生成代理類。即,代理類的位元組碼將在執行時生成並載入當前代理的 ClassLoader。
生成動態代理的方法有很多: JDK中自帶動態代理,CGlib, javassist等。
3.1 JDK動態代理
Proxy類。該類即為動態代理類,該類最常用的方法為:public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
。
newProxyInstance()方法用於根據傳入的介面型別interfaces返回一個動態建立的代理類的例項,方法中第一個引數loader表示代理類的類載入器,第二個引數interfaces表示被代理類實現的介面列表,第三個引數h表示所指派的呼叫處理程式類。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyInvocationHandler implements InvocationHandler {
private Class<?> target;//委託類
public MyInvocationHandler(Class<?> target){
this.target=target;
}
//實際執行類bind
public Object bind(Class<?> target){
//利用JDK提供的Proxy實現動態代理
return Proxy.newProxyInstance(target.getClassLoader(),
new Class[]{target},this);
}
@Override
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
/**代理環繞**/
//執行實際的方法
Object invoke = method.invoke(target, args);
return invoke;
}
}
3.2 CGLIB動態代理
CGLIB動態代理實現相關類需要在專案中匯入 cglib-nodep-2.1_3.jar ,主要涉及兩個類:
MethodInterceptor介面。它是代理例項的呼叫處理程式實現的介面,該介面中定義瞭如下方法:public Object intercept(Object proxy, Method method, Object[] arg2, MethodProxy mp);
intercept()方法中第一個引數proxy表示代理類,第二個引數method表示需要代理的方法,第三個引數args表示代理方法的引數陣列,第四個引數mp用 來去呼叫被代理物件方法
package com.demo;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class MyInterceptor implements MethodInterceptor{
private Object target; ;//代理的目標物件
public MyInterceptor(Object target) {
this.target = target;
}
//proxy 在其上呼叫方法的代理例項 method攔截的方法 args 攔截的引數
//invocation 用來去呼叫被代理物件方法
@Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy invocation) throws Throwable {
//1.記錄日誌 2.時間統計開始 3.安全檢查
Object retVal = invocation.invoke(target, args);
//4.時間統計結束
return retVal;
}
//建立代理物件的方法
public Object proxy(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();//該類用於生成代理類
enhancer.setSuperclass(this.target.getClass());//設定父類
enhancer.setCallback(this);//設定回撥用物件為本身
return enhancer.create();
}
}
相關文章
- 設計模式(十六)----結構型模式之代理享元模式設計模式
- 結構型-代理模式模式
- JAVA設計模式 5【結構型】代理模式的理解與使用Java設計模式
- 結構型設計模式設計模式
- 設計模式之代理模式設計模式
- 《設計模式》之代理模式設計模式
- 無廢話設計模式(11)結構型模式--代理模式設計模式
- (Java)設計模式:結構型Java設計模式
- Javascript設計模式之代理模式JavaScript設計模式
- Java設計模式之代理模式Java設計模式
- 聊一聊設計模式(三)-- 結構型設計模式設計模式
- 設計模式之代理設計模式
- 設計模式詳解之結構型設計模式——介面卡、裝飾器設計模式
- 設計模式之代理模式(proxy pattern)設計模式
- 設計模式漫談之代理模式設計模式
- C++設計模式之代理模式C++設計模式
- Java設計模式之(五)——代理模式Java設計模式
- 23天設計模式之代理模式設計模式
- 設計模式(十三)----結構型模式之橋接模式設計模式橋接
- C++設計模式之Proxy模式(代理模式)C++設計模式
- 初探Java設計模式2:結構型模式(代理模式,介面卡模式等)Java設計模式
- 23種設計模式之代理模式(靜態代理)設計模式
- 結構型模式:代理模式模式
- 設計模式(十一)----結構型模式之裝飾者模式設計模式
- 設計模式(十四、十五)----結構型模式之組合模式設計模式
- 設計模式(十)----結構型模式之介面卡模式設計模式
- 12.java設計模式之代理模式Java設計模式
- JavaScript設計模式經典之代理模式JavaScript設計模式
- JavaScript設計模式之建立型設計模式JavaScript設計模式
- 大話 PHP 設計模式--結構型PHP設計模式
- 物件導向-設計模式-結構型物件設計模式
- 設計模式-代理模式設計模式
- 設計模式----代理模式設計模式
- 設計模式~代理模式設計模式
- 【設計模式】代理模式設計模式
- 設計模式——代理模式設計模式
- 【設計模式自習室】結構型:組合模式 Composite設計模式
- Java設計模式之七 —– 享元模式和代理模式Java設計模式