代理代理,就是找個(gè)人代替你做你該做的事,分為靜態(tài)代理和動(dòng)態(tài)代理,一個(gè)一個(gè)說(shuō)
準(zhǔn)備工作
我們先假設(shè)一種場(chǎng)景,打游戲,我們創(chuàng)建一個(gè)游戲人物去打游戲,讓一個(gè)代理幫我們打游戲
1,建立一個(gè)游戲人物的抽象類
public interface GamePlayer {
void login(String user,String password);
void killBoss();
void upgrade();
}
2,游戲人物的實(shí)體類
public class GamePlayerA implements GamePlayer{
private String name;
public GamePlayerA(String name){
this.name = name;
}
@Override
public void login(String user, String password) {
System.out.println(name + " 登錄成功" + " 登錄名為" + user);
}
@Override
public void killBoss() {
System.out.println(this.name + "在打怪");
}
@Override
public void upgrade() {
System.out.println(this.name + "恭喜你 升級(jí)了");
}
}
下面開(kāi)始實(shí)現(xiàn)代理
靜態(tài)代理
靜態(tài)代理是在編譯時(shí)期就把代理實(shí)現(xiàn)了
1,將被代理對(duì)象構(gòu)造注入,代碼如下
public class GamePlayerProxy implements GamePlayer{
private GamePlayer gamePlayer;
public GamePlayerProxy(GamePlayer gamePlayer){
this.gamePlayer = gamePlayer;
}
@Override
public void login(String user, String password) {
this.gamePlayer.login(user,password);
}
@Override
public void killBoss() {
this.gamePlayer.killBoss();
}
@Override
public void upgrade() {
this.gamePlayer.upgrade();
}
}
2,調(diào)用
public class Main {
public static void main(String[] args){
GamePlayer gamePlayer = new GamePlayerA("張三");
GamePlayerProxy gamePlayerProxy = new GamePlayerProxy(gamePlayer);
gamePlayerProxy.login("zhangsan","password");
gamePlayerProxy.killBoss();
gamePlayerProxy.upgrade();
}
}
還是挺簡(jiǎn)單的,就是把被代理對(duì)象構(gòu)造注入,然后在內(nèi)部調(diào)用被代理對(duì)象,這里我們可以做的更極致一點(diǎn)就是把被代理對(duì)象都隱藏起來(lái)讓高層組件只能接觸到代理對(duì)象
動(dòng)態(tài)代理
在運(yùn)行時(shí)創(chuàng)建代理類,這里要注意我們使用java中的動(dòng)態(tài)代理實(shí)際上就是創(chuàng)建了在運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建了一個(gè)
public class Main {
public static void main(String[] args){
GamePlayer gamePlayer = new GamePlayerA("張三");
GamePlayer gamePlayerProxy = (GamePlayer) Proxy.newProxyInstance(gamePlayer.getClass().getClassLoader(),
gamePlayer.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(gamePlayer,args);
}
});
gamePlayerProxy.login("zhangsan","password");
gamePlayerProxy.killBoss();
gamePlayerProxy.upgrade();
}
}
我們?cè)谑褂玫臅r(shí)候大部分都是使用的動(dòng)態(tài)代理,通過(guò)反射調(diào)用目標(biāo)方法,在代理中增加非業(yè)務(wù)性代碼,比如打點(diǎn)啊,數(shù)據(jù)統(tǒng)計(jì)之類的