Java-代理-設計模式(七)
阿新 • • 發佈:2021-01-19
說明
代理模式,顧名思義,使用代理類對原類進行擴充套件。
程式碼
以NetWork為上網介面為例,預設為CommonNet,實現NetWork介面,然後可以通過ProxyNet代理類來對原CommonNet進行擴充套件,程式碼如下。
通用介面
/**
* @author ctl
* @date 2021/1/18
* 通用介面
*/
public interface NetWork {
void online();
}
預設實現類
/**
* @author ctl
* @date 2021/1/18
* 預設實現類
*/
public class CommonNet implements NetWork {
@Override
public void online() {
System.out.println("上網");
}
}
代理類,實現通用介面,並對原CommonNet進行擴充套件
/**
* @author ctl
* @date 2021/1/18
* 代理類
*/
public class ProxyNet implements NetWork {
private NetWork commonNet;
public ProxyNet (NetWork commonNet) {
this.commonNet = commonNet;
}
@Override
public void online() {
before();
commonNet.online();
after();
}
private void after() {
System.out.println("關閉代理伺服器");
}
private void before() {
System. out.println("開啟代理伺服器");
}
}
測試類
/**
* @author ctl
* @date 2021/1/18
*/
public class ProxyMain {
public static void main(String[] args) {
// 代理前
NetWork commonNet = new CommonNet();
commonNet.online();
System.out.println("---------分割線---------");
// 代理後
NetWork netWork = new ProxyNet(commonNet);
netWork.online();
}
}
結果
可以看出使用代理後,對原online方法進行了前後的擴充套件。
總結
代理模式其實分為靜態代理和動態代理,上述是靜態代理的實現方式,被代理的類是固定的。動態代理則不是固定的。
眾多常用的開源框架中都使用了動態代理,比如mybatis的mapper實現類,spring的aop等等。
動態代理通常使用jdk的動態代理和cglib動態代理,區別是使用jdk代理的類要實現介面,而cglib代理的類不能被final修飾,因為cglib是通過繼承關係來實現的代理,在子類中採用方法攔截的技術攔截所有父類方法的呼叫並順勢織入橫切邏輯。
關於這兩種動態代理的實現方式,之前我在手寫簡版“Spring”,基於自定義註解實現IOC和AOP這篇文章中實現過,就不再重複寫了。