1. 程式人生 > 實用技巧 >JAVA 動態代理

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();
    }
}

那麼以上是不是就通過靜態代理,實現了微商類的代理類,因為我們在裡面寫了另外的兩個方法goagaingo,通過這種靜態代理模式,給了原本只有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到底是怎麼實現的,它為什麼可以幫助我們實現自己想要實現的代理方法、語句等?

跟進去繼續看