網(wǎng)上有很多關(guān)于 spring 動(dòng)態(tài)代理模式的解釋還有實(shí)現(xiàn)的代碼疮绷,但是對(duì)于初學(xué)者來說都不太容易理解朝巫。所以這篇文章我想采用一種比較簡潔生動(dòng)的描述來簡單的說一下動(dòng)態(tài)代理模式莫辨,如果你是初學(xué)者或者小白刃唤,這篇文章或許會(huì)對(duì)你有所幫助洪灯。
什么是動(dòng)態(tài)代理模式
官方解釋這里就不提了坎缭。
這么說吧,咱們每個(gè)人可能都會(huì)遇到租房的情況,我們作為租房的客戶唯一的目的就是租到房子掏呼,搬進(jìn)去住坏快。但是我們是直接找到房子交錢然后就齊活的嗎?恐怕大部分情況是在入住之前會(huì)有一個(gè)中介屁顛屁顛的領(lǐng)著我們先去看房哄尔,看完房之后如果滿意假消,然后再找房東簽訂合同,咱們交錢入住岭接,他們收費(fèi)閃人富拗。
有人會(huì)問了,這和動(dòng)態(tài)代理有什么關(guān)系呢鸣戴?可以這么理解啃沪,把租房看成一個(gè)方法,在我們執(zhí)行這個(gè)方法的時(shí)候窄锅,表面上我們只執(zhí)行了這一個(gè)方法创千,實(shí)際上在運(yùn)行該方法之前我們還運(yùn)行了另外一個(gè)方法,即看房入偷,然后我們才簽了合同才算租房成功追驴。只不過這個(gè)看房的方法是動(dòng)態(tài)的放在我們租房方法之前執(zhí)行的。
這就叫動(dòng)態(tài)代理疏之,不知道大家能否理解殿雪?也可以這么理解,就是說锋爪,只要我們一觸發(fā)租房的方法丙曙,必然會(huì)先運(yùn)行看房的方法,然后再運(yùn)行租房的方法其骄。
代碼實(shí)現(xiàn)
以下是我寫的實(shí)現(xiàn)上面所述動(dòng)態(tài)代理的代碼亏镰。
- 租房的方法(抽象方法):
/**
* 租房的接口
* 抽象的方法
*/
public interface IRent
{
/*
* 租房
*/
void rent();
}
- 真實(shí)角色房東:
/**
* 房東
* 真實(shí)角色
*/
public class Landlord implements IRent
{
@Override
public void rent()
{
System.out.println("=====Landlord====rent====簽合同===");
}
}
- 動(dòng)態(tài)代理類,實(shí)現(xiàn) InvocationHandler 接口
public class MyDynProxy implements InvocationHandler
{
/*
* 指明為誰做代理拯爽,target 為真實(shí)角色
* */
private Object target;//這里是房東索抓;
public void setTarget(Object target)
{
this.target=target;
}
public Object getTarget()
{
return target;
}
/**
* 專門生成代理角色(中介)
* IRent agency = new Agency(landlord);
* @return
*/
public Object newTargetProxy()
{
/**
* 參數(shù)1:代理類的類加載器
* 參數(shù)2:代理類要實(shí)現(xiàn)的接口;中介就是代理類,實(shí)現(xiàn)IRent接口毯炮,可以通過 target.getClass.getInterfaces(獲取所有的接口)
* 參數(shù)3:需要傳入一個(gè) InvocationHandler逼肯,傳入 this指的是 MyDynProxy.
*/
return Proxy.newProxyInstance(this.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this);
}
/*
* 當(dāng)代理角色的方法被執(zhí)行時(shí),會(huì)執(zhí)行這個(gè) invoke 方法否副;當(dāng) 執(zhí)行到 MyDynClient 中的 rent.rent(); 處汉矿,會(huì)調(diào)到此處執(zhí)行該方法
* */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
System.out.println("=========invoke=======");
this.seeHouse();
/*
* 會(huì)調(diào)用真實(shí)角色(比如:房東)的方法
*
* 調(diào)用對(duì)象的方法
* 參數(shù)1:對(duì)象
* 參數(shù)2:方法的參數(shù)崎坊,可以從 invoke 的參數(shù)中獲取
* */
Object object = method.invoke(this.getTarget(), args);
this.fee();
return object;
}
private void fee()
{
System.out.println("=====收費(fèi)====");
}
private void seeHouse()
{
System.out.println("======看房=====");
}
}
- 客戶备禀,也就是我們自己:
/**
* 客戶
*/
public class MyDynClient
{
public static void main(String[] args)
{
Landlord landLord=new Landlord();//創(chuàng)建真正的房東;
/*創(chuàng)建一個(gè)對(duì)象,該對(duì)象能生成動(dòng)態(tài)代理角色(也就是中介)*/
MyDynProxy dynProxy=new MyDynProxy();
/*設(shè)置真實(shí)角色*/
dynProxy.setTarget(landLord);
/*
* 利用上面生成的對(duì)象創(chuàng)建代理類
* 返回抽象角色曲尸,也就相當(dāng)于中介
* */
IRent rent=(IRent)dynProxy.newTargetProxy();
/*調(diào)用抽象接口中的方法赋续,也就是租房方法*/
rent.rent();
}
}
首先,運(yùn)行 MyDynClient 中的 main 方法另患,得到結(jié)果如下:
代碼中寫了比較詳細(xì)的解釋纽乱,如果對(duì)這段代碼的運(yùn)行不是很清楚,可以自己試著打個(gè)斷點(diǎn)運(yùn)行一下昆箕。
如果對(duì)您有所幫助鸦列,實(shí)在是很開心,記得喜歡一下并關(guān)注哦鹏倘。