java靜態署理詳解。本站提示廣大學習愛好者:(java靜態署理詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是java靜態署理詳解正文
署理都曉得吧,你去買器械就有許多的署理商,他們就是賣原廠的器械。好比,你每天要買肉,豬是農人伯伯養的,但你是從屠夫手上買到肉的,這個屠夫便可以當做是署理。那為何要署理呢,署理有甚麼用呢,固然是有事給他做了,關於屠夫這個署理就好懂得了,由於你本身弗成能去宰豬吧,所以署理就是去買活豬,然後宰失落再賣給你,固然屠夫有能夠給肉注點水,症結看他壞不壞,所以屠夫的全部流程就是:
這個流程用代碼怎樣完成呢:我們應當要用三個類You、Butcher、Farmer分離指你、屠夫、農人伯伯。個中農人伯伯又供給一個買肉的辦法給屠夫挪用,這個辦法輸出是錢的數目,前往是肉的數目,都用int型,代碼以下:
class Farmer {
public int buyMeat(int money) {
int meat = 0;
// ... meat = ***;
return meat;
}
}
而屠夫則供給一個買肉的辦法給你挪用,異樣是輸出錢,前往肉,然則會把肉加工一下(殺豬和刮豬毛在代碼中就省了,要否則還得為豬寫個類),代碼以下:
class Butcher {
public int buyMeat(int money) {
Farmer farmer = new Farmer(); // 1.find a farmer.
int meat = farmer.buyMeat(money); // 2.buy meat from the farmer.
meat += 5; // 3.inject 5 pound water into the meat, so weight will increase.
return meat; // 4.return to you.
}
}
然你從屠夫手上買肉的代碼就釀成如許:
class You {
public void work() {
int youMoney = 10;
Butcher butcher = new Butcher(); // find a butcher.
int meat = butcher.buyMeat(youMoney);
System.out.println("Cook the meat, weight: " + meat); // you cooked it.
}
}
這個法式我們還可以優化一下,我們發明屠夫有農人有一個雷同的買肉辦法,我們可以提取一個接口,叫為商販(pedlar)吧,今後你買肉就不消管他是屠夫照樣農人伯伯了,只需他有肉賣便可以了,我們提取一個接口後,代碼就釀成如許:
class You {
public void work() {
int youMoney = 10;
Peldar peldar= new Butcher(); // find a peldar.
int meat = peldar.buyMeat(youMoney);
System.out.println("Cook the meat, weight: " + meat); // you cooked it.
}
}
interface Peldar {
int buyMeat(int money);
}
class Butcher implements Peldar {
@Override
public int buyMeat(int money) {
Farmer farmer = new Farmer(); // 1.find a farmer.
int meat = farmer.buyMeat(money); // 2.buy meat from the farmer.
meat += 5; // 3.inject 5 pound water into the meat, so weight will increase.
return meat; // 4.return to you.
}
}
class Farmer implements Peldar {
@Override
public int buyMeat(int money) {
int meat = 0;
// ... meat = ***;
return meat;
}
}
這就是署理,值得留意的是普通署理類和終究類會完成統一接口,如許的利益是,挪用者就不消關懷以後援用的究竟是署理照樣終究類。
不外這叫靜態署理,由於署理類(屠夫類)是你親手寫,靜態署理就是Java在運轉的時刻,靜態生成一個等價的署理類。固然類是靜態生成的,然則殺豬和灌水的代碼照樣要寫的,只是不要寫一個類了。寫到哪裡呢,寫到上面這個接口外面:
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}
參數是甚麼意思呢,我寫成如許,能夠你就明確了:
public interface InvocationHandler {
public Object invoke(Object butcher, Method buyMeat, Object[] money) throws Throwable;
}
第一個參數是主動生成的署理類的一個對象(主動生成的屠夫類的對象),第二個參數是正前正在被挪用的辦法的對象(辦法怎樣還有對象呢,拜見Java反射機制),我們這裡只要一個辦法叫buyMeat,所以這個參數代表的確定就是它了,第三個參數是傳給後面誰人辦法的參數數組,buyMeat只要一個參數,所以這個數組只會有一個元素。因而殺豬灌水的代碼寫出去就釀成如許了:
InvocationHandler mInvocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object butcher, Method buyMeat, Object[] args) throws Throwable {
Farmer farmer = new Farmer(); // 1.find a farmer.
int meat = (Integer) buyMeat.invoke(farmer, args); // 2.buy meat from the farmer.
meat += 5; // 3.inject 5 pound water into the meat, so weight will increase.
return meat; // 4.return to you.
}
};
這個裡挪用農人伯伯的買肉辦法有點不符慣例,這裡是反射機制挪用法,意思是如許的,以farmer對象為接收者來挪用buyMeat辦法,跟直接挪用farmer的辦法是一樣的,你能夠會問那為何不直接挪用呢,你能夠沒留意,invoke的第一個參數類型是Object,所以你可以向任何對象宣布挪用敕令(但紛歧定會勝利,甚麼時刻會勝利等下說),假如你有許多farmer對象,乃至不是farmer對象,只需某接口的實例便可以(哪一個接口等下解釋,我們先定名為A接口),便可以當做參數傳出去,然後對其停止辦法挪用。如今我們來看看若何生成署理類吧,很簡略,可以挪用Proxy的工場辦法,以下:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
throws IllegalArgumentException
說明參數,第一個ClassLoader是用來加載署理類的(關於ClassLoader,本文暫不講授),你暫不懂得也沒緊要,第二個是一個數組,每一個元數都是一個接口,重生成的署理都邑完成一切這些接口,傳給InvocationHandler.invoke第二個參數的辦法,一定屬於一切這些接口中的辦法,上一段落說的誰人A接口必需是數組中的一個元素,上一段落說的誰人挪用成掉敗成績也清楚明了了。第三個參數InvocationHandler更好懂得了,就是只需署理類中的任何辦法被挪用,就會告訴這個InvocationHandler。上面寫出完全代碼:
class You {
public void work() {
int youMoney = 10;
Peldar peldarProxy = (Peldar) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Peldar.class}, mInvocationHandler);
int meat = peldarProxy.buyMeat(youMoney);
System.out.println("Cook the meat, weight: " + meat);
}
InvocationHandler mInvocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object butcher, Method buyMeat, Object[] args)
throws Throwable {
Farmer farmer = new Farmer(); // 1.find a farmer.
int meat = (Integer) buyMeat.invoke(farmer, args); // 2.buy meat from the farmer.
meat += 5; // 3.inject 5 pound water into the meat, so weight will increase.
return meat; // 4.return to you.
}
};
}
interface Peldar {
int buyMeat(int money);
}
class Farmer implements Peldar {
@Override
public int buyMeat(int money) {
int meat = 0;
// ... meat = ***;
return meat;
}
}
這裡You類裡生成一個署理類,在署理類的buyMeat被挪用時,代碼就跟之前的靜態署理一樣的了。