一.先說明一下設計模式中代理模式是什么?
代理類與委托類有同樣的接口,代理類主要負責為委托類預處理消息、過濾消息、把消息轉發給委托類,以及事后處理消息等。代理類與委托類之間通常會存在關聯關系,一個代理類的對象與一個委托類的對象關聯,代理類的對象本身并不真正實現服務,而是通過調用委托類的對象的相關方法,來提供特定的服務。簡單的說就是,我們在訪問實際對象時,是通過代理對象來訪問的,代理模式就是在訪問實際對象時引入一定程度的間接性
首先我模擬一個場景,公司領導發獎金給員工的行為,我希望作為公司領導只關注發多少獎金,具體發給誰,是因為什么原因發,這些領導可以不用管,在這種情況下,就可用代理類去代理領導發獎金,他去過濾員工,具體每個發多少獎金;首先領導的這種行為可抽象為
interface person{
void giveBonus(int value)
}
二.java的代理分為兩類,根據創建代理類的時間點,又可以分為靜態代理和動態代理。
1.靜態代理:指的是在compile時已經將接口,被代理類,代理類等確定下來。在程序runtime之前,代理類的.class文件就已經生成。AOP 編程就是基于動態代理實現的
//被代理類
class Leader implements person{
void giveBonus(int value){
sysout("銀行轉賬"+value+“元”)
}
}
代理類
class LeaderProxy implements person{
private Leader leader;
LeaderProxy(Leader leader){
this.leader = leader
}
void giveBonus(int value){
leader.giveBonus(value)
}
}
main(){
LeaderProxy delegate = new LeaderProxy(new Leader())
delegate.giveBonus(100)
}
2.動態代理:代理類在程序runtime創建的代理方式被成為動態代理
public class MyInvocationHandler<T> implements InvocationHandler {
//invocationHandler持有的被代理對象
T target;
public MyInvocationHandler(T target) {
this.target = target;
}
/**
* proxy:代表動態代理對象
* method:代表正在執行的方法
* args:代表調用目標方法時傳入的實參
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理執行" +method.getName() + "方法之前"+currenttime);
Object result = method.invoke(target, args);
System.out.println("代理執行" +method.getName() + "方法之后"+currenttime);
return result;
}
}
main(){
//創建一個與代理對象相關聯的InvocationHandler
InvocationHandler leaderHandler = new MyInvocationHandler<person>(leader);
//創建一個代理對象stuProxy,代理對象的每個執行方法都會替換執行Invocation中的invoke方法
person leaderProxy= (person) Proxy.newProxyInstance(person.class.getClassLoader(), new Class<?>[]{person.class}, leaderHandler);
}
三.cglib
JDK的動態代理 代理的是接口,也就是你的 業務類必須要實現接口,通過 Proxy 里的 newProxyInstance 得到代理對象。cglib是一個功能強大,高性能的代碼生成包。它為沒有實現接口的類提供代理,為JDK的動態代理提供了很好的補充。通??梢允褂肑ava的動態代理創建代理,但當要代理的類沒有實現接口或者為了更好的性能,cglib是一個好的選擇。
cglib的缺點是:cglib底層采用ASM字節碼生成框架,使用字節碼技術生成代理類,也就是生成的.class文件,而我們在android中加載的是優化后的.dex文件,也就是說我們需要可以動態生成.dex文件代理類,cglib在android中是不能使用的。但后面我們會根據dexmaker框架來仿照動態生成.dex文件,實現cglib的動態代理功能。