設計模式(3) 代理模式 動態代理

根據上一個文章可輕鬆實現代理功能,但是這樣做的代價是會生成許多的XxxProxy類,怎樣才能消除掉這些類呢?這時我們可以使用JDK的動態代理。

  • 使用JDK提供的動態代理方案
    編寫一個事務CarTimeHandler類 實現計時功能 、實現InvocationHandler接口
package cn.niriqiang.proxy;

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

/**
 * Created by fengyuwusong on 2017/8/19 15:37.
 */
public class CarTimeHandler implements InvocationHandler {
    //被代理的目標對象
    private Object target;
    long start,end;
    public CarTimeHandler(Object target) {
        this.target = target;
    }


    private void before() {
        start=System.currentTimeMillis();
        System.out.println("開車前時間:"+start);
    }

    private void after(){
        end=System.currentTimeMillis();
        System.out.println("開車後時間:"+end+".\n總耗時:"+(end-start)+"毫秒");
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        method.invoke(target);
        after();
        return null;
    }
}

再編寫一個事務CarLogHandler類實現日誌功能

package cn.niriqiang.proxy;

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

/**
 * Created by fengyuwusong on 2017/8/19 23:58.
 */
public class CarLogHandler implements InvocationHandler {
    ICar car;

    public CarLogHandler(ICar car) {
        this.car = car;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        method.invoke(car);
        System.out.println("記錄日誌");
        return null;
    }
}

則在main方法如此調用則可實現代理

package cn.niriqiang.proxy;

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

/**
 * Created by fengyuwusong on 2017/8/19 14:55.
 */
public class main {

    public static void main(String[] args) {
//        靜態代理
        //        ICar car=new CarImpl();
//        Carproxy carproxy=new Carproxy(car);
//        CarLogProxy carLogProxy=new CarLogProxy(carproxy);
//        carLogProxy.run();
//        動態代理
        ICar car=new CarImpl();
        Class cls=car.getClass();
//        實現計時功能
        InvocationHandler carTimeHandler=new CarTimeHandler(car);
        car= (ICar) Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),carTimeHandler);
//        實現日誌功能
        InvocationHandler carLogHandler=new CarLogHandler(car);
        car=(ICar)Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),carLogHandler);
        car.run();
    }
}

結果

開車前時間:1503158582409
正在開車~~~
開車後時間:1503158583225.
總耗時:816毫秒
記錄日誌

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