代理模式

基於接口的動態代理

IProducer接口

/**
 * <p>
 * 廠家對代理商的要求規範
 */
public interface IProducer {
    /**
     * 銷售
     *
     * @param money
     */
    void saleProducer(Float money);

    /**
     * 售後
     *
     * @param money
     */
    void afterService(Float money);
}

Producer

/**
 * <p>
 * 生產者
 */
public class Producer implements IProducer{
    /**
     * 銷售
     *
     * @param money
     */
    @Override
    public void saleProducer(Float money) {
        System.out.println("銷售產品,並拿到" + money + "元");
    }

    /**
     * 售後
     *
     * @param money
     */
    @Override
    public void afterService(Float money) {
        System.out.println("提供售後服務,收取" + money + "元");
    }
}

動態代理

public class Client {
    public static void main(String[] args) {
        final Producer producer = new Producer();
        //producer.saleProducer(10000f);
        /**
         * 動態代理:
         *      特點:字節碼隨用隨創建,隨用隨加載
         *      作用:不修改源碼的基礎上對方法進行增強
         *      分類:
         *          基於接口的動態代理
         *          基於子類的動態代理
         *       基於接口的動態代理  Proxy.newProxyInstance();
         *          要求:被代理類至少實現一個接口
         *          參數:
         *              ClassLoader:用於加載代理對象字節碼,和被代理對象使用相同的類加載器 固定寫法
         *              Class<?>[]:讓代理對象和被代理對象有相同的方法                   固定寫法
         *              InvocationHandler:用於提供增強的代碼
         */
        //返回值要是一個接口而不是實現類
        IProducer proxyInstance = (IProducer) Proxy.newProxyInstance(producer.getClass().getClassLoader(),
                producer.getClass().getInterfaces(), new InvocationHandler() {
                    /**
                     *執行被代理的對象的任何接口方法都會經過該方法
                     * @param proxy     代理對象的引用
                     * @param method    當前執行的方法
                     * @param args      當前執行方法所需的參數
                     * @return 和被代理對象有相同的返回值
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        /**
                         * method.invoke()被代理對象的方法
                         * 匿名內部類訪問外部成員變量時,外部成員用final修飾
                         */
                        Object returnValue = null;
                        //1.獲取方法執行的參數
                        Float money = (Float) args[0];
                        //2.判斷當前方法是不是saleProducer
                        if ("saleProducer".equals(method.getName())) {
                            returnValue = method.invoke(producer, money * 0.8f);
                        }
                        return returnValue;
                    }
                });
        proxyInstance.saleProducer(10000f);
    }
}

基於子類的動態代理

Producer

 */
public class Producer {
    /**
     * 銷售
     *
     * @param money
     */
    public void saleProducer(Float money) {
        System.out.println("銷售產品,並拿到" + money + "元");
    }

    /**
     * 售後
     *
     * @param money
     */
    public void afterService(Float money) {
        System.out.println("提供售後服務,收取" + money + "元");
    }
}

動態代理

public class Client {
    public static void main(String[] args) {
        final Producer producer = new Producer();
        //producer.saleProducer(10000f);
        /**
         * 動態代理:
         *      特點:字節碼隨用隨創建,隨用隨加載
         *      作用:不修改源碼的基礎上對方法進行增強
         *      分類:
         *          基於接口的動態代理
         *          基於子類的動態代理
         *       基於子類的動態代理  Enhancer.create();
         *          要求:被代理類不能是最終類
         *          參數:
         *              Class:字節碼
         *                  用於指定被代理對象的字節碼
         *              Callback:用於提供增強代碼
         *                  寫的是該接口的子接口的實現類MethodInterceptor
         *
         */
        Producer cglibProducer = (Producer) Enhancer.create(producer.getClass(), new MethodInterceptor() {

            /**
             * 執行被代理的對象的任何接口方法都會經過該方法
             * @param o             代理對象的引用
             * @param method        當前執行的方法
             * @param objects       當前執行方法所需的參數
             * @param methodProxy   當前執行方法的代理對象
             * @return
             * @throws Throwable
             */
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                Object returnValue = null;
                //1.獲取方法執行的參數
                Float money = (Float) objects[0];
                //2.判斷當前方法是不是saleProducer
                if ("saleProducer".equals(method.getName())) {
                    returnValue = method.invoke(producer, money * 0.7f);
                }
                return returnValue;
            }
        });
        cglibProducer.saleProducer(10000f);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章