Java中的動態代理和靜態代理

本文面向初接觸動態代理的學者,代碼貼在最後

靜態代理

其實現思路:

從前有A,B商家註冊到了C平臺上,A提供一些初級的服務,B對A的服務進行了一些封裝從而能實現更厲害的服務。

(寫到這裏我突然發現和SpringCloud咋這麼像。。。。。)

其映射在Java中就是:

C是一個接口,A,B都實現了該接口,B中持有A的引用,B調用方法都是通過A來實現,只不過在實現前後增加了一些操作。

(和裝飾者模式咋這麼像。。。。。)

其實雖然實現方式是差不多的,但是其終究目的卻不同:裝飾着模式是增強方法而靜態代理是保護和隱藏被代理對象

動態代理

實現思路:

同樣有C平臺和A,B商家。同樣是A提供一些初級的服務,B對A的服務進行了一些封裝從而能實現更厲害的服務。差別就在B對A提供的散裝服務不用一個一個處理了,而是一起處理

其體現在Java代碼中是這樣的:

對於B類,不用去實現C接口了,而是持有一個實現C接口的A類引用(在B中要用Object,不然要轉換十分麻煩,但是在調用的時候卻要傳入一個A類的引用),自己實現InvocationHandler接口,其就是jdk爲我們提供的動態生成代碼的方式:

在以下代碼中:C ==Dormitory,B == DormitoryProxy(靜態),DynamicDormitory(動態),A==MyDormitory

package sjms.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @Author Yan1less
 * @Date 2019/5/1 15:22
 * @Description TODO
 **/
public class DynamicProxy implements InvocationHandler {

    // 這個就是我們要代理的真實對象
    private Object subject;

    //    構造方法,給我們要代理的真實對象賦初值
    public DynamicProxy(Object subject)
    {
        this.subject = subject;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //  在代理真實對象前我們可以添加一些自己的操作
        System.out.println("使用方法之前");

        System.out.println("Method:" + method);

        //    當代理對象調用真實對象的方法時,其會自動的跳轉到代理對象關聯的handler對象的invoke方法來進行調用
        Object invoke = method.invoke(subject, args);

        //  在代理真實對象後我們也可以添加一些自己的操作
        System.out.println("使用方法之後");

        return invoke;
    }
}

 

package sjms.proxy;

/**
 * @Author Yan1less
 * @Date 2019/5/1 14:53
 * @Description 被代理類,靜態代理其實和裝飾這模式有點像,這其實可以類比成被裝飾者
 **/
public class MyDormitory implements Dormitory{
    @Override
    public void OneFloor() {
        System.out.println("這裏是一層");
    }

    @Override
    public void TwoFloor() {
        System.out.println("這裏是二層");
    }

    @Override
    public void ThreeFloor() {
        System.out.println("這裏是三層");
    }

    @Override
    public int FourFloor() {
        System.out.println("這裏是四層");
        return 8888;
    }
}

 

package sjms.proxy;

/**
 * @Author Yan1less
 * @Date 2019/5/1 14:53
 * @Description 可以類比成裝置這模式中的裝飾者,不過其較動態代理麻煩的地方在於:
 *                  1.方法都要重寫一遍,有點麻煩
 *                  2.構造方法傳參需要類型轉化
 *           最大的區別還是在與:裝飾者模式主要目的是增強方法,靜態代理目的是保護與隱藏被代理對象
 **/
public class DormitoryProxy implements Dormitory{

    private MyDormitory myDormitory;


    public DormitoryProxy(Dormitory dormitory) {
        if(dormitory.getClass() == MyDormitory.class){
            myDormitory = (MyDormitory)dormitory;
        }
    }

    @Override
    public void OneFloor() {
        System.out.println("抵達XX公寓");
        myDormitory.OneFloor();
    }

    @Override
    public void TwoFloor() {
        System.out.println("抵達XX公寓");
        myDormitory.TwoFloor();
    }

    @Override
    public void ThreeFloor() {
        System.out.println("抵達XX公寓");
        myDormitory.ThreeFloor();
    }

    @Override
    public int FourFloor() {
        System.out.println("抵達XX公寓");
        myDormitory.FourFloor();
        return 8888;
    }
}
package sjms.proxy;

/**
 * @Author Yan1less
 * @Date 2019/5/1 14:52
 * @Description 這是一個接口,被代理類和代理類都要實現它
 **/
public interface Dormitory {

    void OneFloor();
    void TwoFloor();
    void ThreeFloor();
    int FourFloor();

}
package sjms.proxy;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Author Yan1less
 * @Date 2019/5/1 14:50
 * @Description TODO
 **/
public class Main {
    public static void main(String[] args) {
        Dormitory dormitory = new MyDormitory();
        Dormitory proxy = new DormitoryProxy(dormitory);
        proxy.OneFloor();

        System.out.println("--------------------------------");

        DynamicProxy dynamicProxy = new DynamicProxy(dormitory);

        Dormitory a = (Dormitory)Proxy.newProxyInstance(dynamicProxy.getClass().getClassLoader(),
                dormitory.getClass().getInterfaces(),dynamicProxy
               );
        int i = a.FourFloor();
        System.out.println(i);

    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章