AMD 已向歐盟委員會提交 350 億美元收購賽靈思計劃,以接受審查
代理模式:為其他物件提供一種代理以控制對這個代理物件的訪問
代理分為兩種模式:靜態代理、和動態代理模式
代理模式中有三個角色:
抽象角色:宣告真實物件和代理物件的共同介面。
代理角色:代理物件與真實物件實現同樣的介面,所以它可以在不論什麼時刻都可以代理真實物件。代理角色內部包括有對真實物件的引用。所以她可以操作真實物件,同一時候也可以附加其它的操作,相當於對真實物件進行封裝。
真實角色:它代表著真實物件。是我們終於要引用的物件
靜態代理
模擬場景:
生活中我們在大城市租房,很多都是中介給介紹的或者二房東,從中介手裡可以租到房東的房子,從房東手裡也可以租到房子,中介、二房東只是代理房東租房,他們都有一個共同的租房介面。
租房介面:
public interface IRent {
void Rent();//出租
}
房東出租房子(真實角色):
public class Host implements IRent{
@Override
public void Rent() {
System.out.println("房東出租房");
}
}
增加一個代理類(代理角色),實現租房的介面
public class Proxy implements IRent{ private Host host; public Proxy(Host host) { this.host=host; } @Override public void Rent() { host.Rent(); } }
public static void main(String[] args) {
Host host=new Host();
Proxy proxy=new Proxy(host);
proxy.Rent();
}
現在還是從房東那租房子,只是中間多了一層關係。代理類裡面還可以加其他功能,配客戶看房吃飯等。
就是在不改變原有程式碼的基礎上,對原有的程式碼進行增強,所以才有代理類。
優點:
- 一定程度上降低了系統的耦合度,擴充套件性好。
- 公共角色交給代理,實現業務的分工
- 對目標物件的功能增強
缺點:
如果要實現多個代理的話,一個真實角色就會產生一個代理角色,開發程式碼量翻倍
動態代理
動態代理和靜態代理原理一樣,不過動態代理的代理類是自動生成的,不是是手動編寫的
動態代理分為兩大類:介面動態代理JDK、類的動態代理cglib、java位元組碼
實現JDK動態代理的步驟:
JDK動態代理中包含一個類和一個介面:
Proxy類
Object Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler)
- loader:代理類的入口(當前類的類載入器)
- interfaces:被代理的介面
- handler:InvocationHandler介面
InvocationHandler介面
public interface InvocationHandler {
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}
-
proxy - 呼叫該方法的代理例項
-
method - 對應於在代理例項上呼叫的介面方法的方法例項。
-
args - 包含代理例項上方法呼叫中傳遞的引數值的物件陣列。
步驟一:新建一個類,實現代理呼叫的介面InvocationHandler
,並重寫裡面的invoke
方法執行動作
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的介面
private Object object;
//傳入被代理的介面
public ProxyInvocationHandler(Object object)
{
this.object = object;
}
//處理代理例項 並返回結果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result =method.invoke(object,args);//執行介面 args:介面上的方法
return result;
}
}
步驟二:生成代理類Proxy
//建立代理物件
IRent obj=(IRent) Proxy.newProxyInstance(IRent.class.getClassLoader(), new Class<?>[]{IRent.class}, pih);
步驟三:測試
public static void main(String[] args) {
//真實物件
Host host=new Host();
//代理物件的呼叫處理程式 並設定要代理的物件
ProxyInvocationHandler pih=new ProxyInvocationHandler(host);
//動態生成代理類
IRent obj=(IRent) Proxy.newProxyInstance(IRent.class.getClassLoader(), new Class<?>[]{IRent.class}, pih);
obj.Rent();
}
動態代理的好處
靜態代理有的它都有,靜態代理沒有的,它也有!
- 可以使得我們的真實角色更加純粹 . 不再去關注一些公共的事情
- 公共的業務由代理來完成 . 實現了業務的分工
- 公共業務發生擴充套件時變得更加集中和方便
- 一個動態代理 , 一般代理某一類業務
- 一個動態代理可以代理多個類,代理的是介面