動態代理

概述 : Spring 框架有一個技術, 叫做 AOP 技術. (面向切面編程)

效果 : 攔截被調用對象的所有方法.
動態代理1

動態代理2

動態代理3

實現類完成
接口定義 :

public interface SuperStar {

    void sing(int money);
    void liveShow(int money);
    void sleep();
}

實現類定義 :

public class LiuYan implements SuperStar {

    @Override
    public void sing(int money) {
        System.out.println("柳巖爲了唱了一首 <真的真的很愛你!> 歌曲. 掙了 = " + money);
    }

    @Override
    public void liveShow(int money) {
        System.out.println("柳巖參加了 <屌絲男士!> 節目. 掙了 = " + money);
    }

    @Override
    public void sleep() {
        System.out.println("柳巖真的很累了, 休息休息...");
    }
}

測試類定義 :

@Test
public void test1() {

    SuperStar star = new LiuYan();

    star.sing(-10);
    star.liveShow(-20);
    star.sleep();
}

@Test
public void test2() {

SuperStar star = new LiuYan();

/************ 動態代理對象 start **************/
// 1. 使用 Proxy 類調用 newProxyInstance 方法
// 1.1 類加載器 (與被代理對象保持一致)
ClassLoader loader = star.getClass().getClassLoader();
// 1.2 interfaces 接口行爲規範 (與被代理對象保持一致)
Class<?>[] interfaces = star.getClass().getInterfaces();
// 1.3 InvocationHandler 調用處理器 (實現類)
// 注意點 : 返回的 Object 類型對象必須要轉成接口實現.
SuperStar proxy = (SuperStar) Proxy.newProxyInstance(loader, interfaces, new MyInvocationHandler(star));
/************ 動態代理對象 end **************/
// System.out.println(proxy.getClass());
proxy.sing(10000);
proxy.liveShow(200000);
proxy.sleep();

}

MyInvocationHandler 實現類代碼編寫 :
簡化版本 :

public class MyInvocationHandler implements InvocationHandler {
    // 屬性
    private SuperStar star;

    // 構造方法
    public MyInvocationHandler(SuperStar star) {
        this.star = star;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable  {
        // 直接放行 
        return method.invoke(star, args);   
    }
}

判斷版本 :

public class MyInvocationHandler implements InvocationHandler {
    // 屬性
    private SuperStar star;

    // 構造方法
    public MyInvocationHandler(SuperStar star) {
        this.star = star;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable  {

        // 1. 判斷方法
        if (method.getName().equals("sing")) {
            // 2. 取出參數
            int money = (int) args[0];
            // 3. 判斷參數
            if (money < 10000) {
                System.out.println("滾, 你這個窮屌絲, 趕緊回家擼代碼去...");
                return null;
            }
            // 4. 參數合法
            // 抽提成
            System.out.println("代理抽取了 " + (money * 0.3) + " 回扣.");
            // 5. 調用真實的方法
            return method.invoke(star, (int)(money * 0.7));
        } else if ("liveShow".equals(method.getName())) {
            // 2. 取出參數
            int money = (int) args[0];
            // 3. 判斷參數
            if (money < 100000) {
                System.out.println("滾, How old are you. 繼續回家擼代碼去...");
                return null;
            }
            // 4. 參數合法
            // 抽提成
            System.out.println("代理抽取了 " + (money * 0.3) + " 回扣.");
            // 5. 調用真實的方法
            return method.invoke(star, (int)(money * 0.7));
        }

        return method.invoke(star, args);   // 其它方法直接放行   (close  池)
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章