JAVA 動態代理
參考文章:https://y4er.com/post/java-proxy/
一共講兩個,一個是靜態代理,一個是動態代理!
靜態代理
實現靜態代理的前提:
1、代理類和被代理類實現了同一介面
2、被代理類需要實現具體繼承介面中的方法
3、代理類呼叫的是具體類中的方法(也就是說代理類中需要接受一個被代理類的物件)
這裡舉的例子就是,供應商 - 微商 - 客戶 之間的代理
供應商/微商的介面:
public interface Seller {
public void toSell();
}
供應商的實現類:
public class NormalSeller implements Seller{ @Override public void toSell() { System.out.println("我是賣鞋的!!!"); } }
微商類的實現(這裡體現的就是代理類):
public class MicroSeller implements Seller { Seller normal = new NormalSeller(); @Override public void toSell() { this.go(); this.normal.toSell(); this.againgo(); } public void go(){ System.out.println("瞧一瞧,看一看"); } public void againgo(){ System.out.println("要不繼續看看?"); } }
這裡Main如下:
public class Mymain {
public static void main(String[] args){
Seller testSeller = new MicroSeller();
testSeller.toSell();
}
}
那麼以上是不是就通過靜態代理,實現了微商類的代理類,因為我們在裡面寫了另外的兩個方法go
和againgo
,通過這種靜態代理模式,給了原本只有toSell方法就添加了兩種方法,並且沒有改變原來的類!
但是也有缺點:
1、要為每一個介面實現代理類,一旦介面增加方法,目標物件與代理物件都要維護。
這個缺點怎麼理解?
比如現在又是一個,如果供應商需要回購不需要的鞋子的話,在介面中就需要新增一個buy
的方法,那麼被代理需要去實現,然後代理類也需要進行呼叫,導致了兩個類都需要進行維護!
動態代理
動態代理的話,就可以幫助我們解決上面的問題!
動態代理和靜態代理的唯一區別就在於:動態代理是動態生成的,省去為介面實現代理類的操作。
要使用動態代理的話,只需要將被代理類繼承InvocationHandler介面,然後實現其中的方法invoke即可!
那麼靜態代理中的被代理類實現動態代理:
這裡寫的時候有個變動,就是 之前說的代理類中需要接受一個被代理類的物件,現在這個被代理類的物件就作為代理類的建構函式的引數傳入!
供應商/微商的介面:
public class NormalSeller implements Seller{
@Override
public void toSell() {
System.out.println("我是賣鞋的!!!");
}
}
供應商的實現類:
public class NormalSeller implements Seller{
@Override
public void toSell() {
System.out.println("我是賣鞋的!!!");
}
}
微商實現的類:
public class MicroSeller implements InvocationHandler {
Object normal;
public MicroSeller(Object normal){
this.normal = normal;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("瞧一瞧,看一看");
System.out.println("要不繼續看看?");
return null;
}
}
public class MyMain {
public static void main(String[] args){
Seller normal = new NormalSeller();
InvocationHandler invocationHandler = new MicroSeller(normal);
Seller microSeller = (Seller)Proxy.newProxyInstance(
Seller.class.getClassLoader(),
new Class[]{Seller.class},
invocationHandler);
microSeller.toSell();
}
}
結果圖如下:
繼續講,通過動態代理就可以方便的進行代理,就是將被代理類繼續介面InvocationHandler,然後去實現InvocationHandler介面中的invoke方法,在invoke方法中進行我們要想代理的東西即可!
那麼繼續思考,Proxy.newProxyInstance到底是怎麼實現的,它為什麼可以幫助我們實現自己想要實現的代理方法、語句等?
跟進去繼續看