JDK動態代理與CGlib動態代理小結

JDK動態代理與CGlib動態代理

應用場景

比如進行日誌記錄、監控某個方法的運行時間、權限控制、事務管理 (調用方法前開啓事務, 調用方法後提交關閉事務 )、緩存優化 (第一次調用查詢數據庫,將查詢結果放入內存對象, 第二次調用, 直接從內存對象返回,不需要查詢數據庫 )等等,總的來說是執行目標方法前後都可以幹一些其他的事情,在不改動目標方法的前提下將目標方法與其他操作實現解耦。

區別

如果目標類有實現接口則用JDK動態代理,如果目標類沒有實現接口則用CGlib動態代理。

JDK動態代理

接口:

public interface PrepareWork {
    //打開電腦
    public void openCompare();

    //輸入語言,開始擼代碼
    public void LuCode(String language);
}

目標類:

public class RealWork implements PrepareWork {
    @Override
    public void openCompare() {
        System.out.println("open computer......!");
    }

    @Override
    public void LuCode(String language) {
        System.out.println("今天用" + language +"擼代碼");
    }
}

代理工廠:

public class ProxyFactory {
    private Object object; // 目標對象

    public ProxyFactory(Object object) {
        this.object = object;
    }

    public Object getProxyInstance() {
        return Proxy.newProxyInstance(
                object.getClass().getClassLoader(),
                object.getClass().getInterfaces(), new InvocationHandler() {
                    // proxy:表示我們代理的真實對象
                    // method:表示調用真實對象中的某個方法的metode對象
                    // args:調用真實對象方法裏所傳的參數
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // TODO Auto-generated method stub
                        //在代理真實對象前我們可以添加一些自己的操作
                        System.out.println("調用方法前執行!");
                        //目標方法調用
                        Object obj = method.invoke(object, args);
                        System.out.println("方法執行完畢!");
                        return obj;
                    }
                });
    }
}

測試:

public class Test {
    public static void main(String[] args) {
        // 1.要代理的真實對象
        RealWork prepareWork = new RealWork();//
        PrepareWork proxy = (PrepareWork) new ProxyFactory(prepareWork).getProxyInstance();
        proxy.openCompare();
        System.out.println("-----------------------------分隔符-----------------------------");
        proxy.LuCode("PAYTHON");
    }
}

結果:
在這裏插入圖片描述

CGlib動態代理

目標類:

public class RealWork {
    //新增
    public void insertInf() {
        System.out.println("增加...");
    }
    //刪除
    public void deleteInf() {
        System.out.println("刪除...");
    }
    //修改
    public void updateInf() {
        System.out.println("修改...");
    }
    //查詢
    public void selectInf() {
        System.out.println("查詢...");
    }
}

代理工廠:

public class ProxyFactory {
    // 被代理對象
    private Object object;

    public ProxyFactory(Object object) {
        this.object = object;
    }

    public Enhancer getProxyInstance(){
        //創建cglib核心對象
        Enhancer enhancer = new Enhancer();
        //設置父類
        enhancer.setSuperclass(object.getClass());
        //設置回調
        enhancer.setCallback(new org.springframework.cglib.proxy.MethodInterceptor() {
        /**
         * 當你調用目標方法時,實質上是調用該方法
         * intercept四個參數:
         * proxy:代理對象
         * method:目標方法
         * args:目標方法的形參
         * methodProxy:代理方法
         */
        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            // TODO Auto-generated method stub
            //在代理真實對象前我們可以添加一些自己的操作
            System.out.println("調用方法前執行!");
            //目標方法調用
            Object result = methodProxy.invokeSuper(proxy, args);
            System.out.println("方法執行完畢!");
            return result;
        }
        });
        return enhancer;
    }
}

測試:

public class Test {
    public static void main(String[] args) {
        RealWork realWork = new RealWork();
        //創建代理對象
        RealWork proxyObj = (RealWork) new ProxyFactory(realWork).getProxyInstance().create();
        proxyObj.insertInf();
        proxyObj.deleteInf();
        proxyObj.updateInf();
        proxyObj.deleteInf();
    }
}

結果:
在這裏插入圖片描述

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