成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

慕課網(wǎng)_《模式的秘密之代理模式》學(xué)習(xí)總結(jié)

wow_worktile / 640人閱讀

時(shí)間:2017年08月28日星期一
說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com
教學(xué)源碼:https://github.com/zccodere/s...
學(xué)習(xí)源碼:https://github.com/zccodere/s...

第一章:代理模式 1-1 概念介紹

學(xué)習(xí)本課程基礎(chǔ)

面向?qū)ο蟮脑O(shè)計(jì)思維
了解多態(tài)的概念
了解反射機(jī)制

課程目標(biāo)

代理模式基本概念及分類
了解代理模式開發(fā)中應(yīng)用場景
掌握代理模式實(shí)現(xiàn)方式
理解JDK動(dòng)態(tài)代理實(shí)現(xiàn)

代理模式定義

為其他對象提供一種代理以控制對這個(gè)對象的訪問
代理對象起到中介作用,可去掉功能服務(wù)或增加額外的服務(wù)

常見的幾種代理模式

遠(yuǎn)程代理:類似于客戶端服務(wù)器這種模式,列一個(gè)為不同地理對象提供局域網(wǎng)代表對象
虛擬代理:根據(jù)需要將資源消耗很大的對象進(jìn)行延遲,真正需要的時(shí)候進(jìn)行創(chuàng)建
保護(hù)代理:控制對象的訪問權(quán)限
智能代理:提供對目標(biāo)對象額外的服務(wù)

代理模式示意圖

第二章:常用代理模式 2-1 靜態(tài)代理

智能引用代理

靜態(tài)代理
動(dòng)態(tài)代理

靜態(tài)代理定義

代理和被代理對象在代理之前是確定的。他們都實(shí)現(xiàn)相同的接口或者繼承相同的抽象類

靜態(tài)代理類圖

代碼編寫

1.編寫Moveable接口

package com.myimooc.designpattern.c3proxy.car;

/**
 * @describe 可行駛的接口
 * @author zc
 * @version 1.0 2017-08-28
 */
public interface Moveable {
    
    /**
     * 行駛的方法
     */
    void move();
    
}

2.編寫Car類

package com.myimooc.designpattern.c3proxy.car;

import java.util.Random;

/**
 * @describe 一輛車實(shí)現(xiàn)可行駛的接口
 * @author zc
 * @version 1.0 2017-08-28
 */
public class Car implements Moveable {
    
    @Override
    public void move() {
        // 記錄汽車行駛的時(shí)間
//        long starttime = System.currentTimeMillis();
//        System.out.println("汽車開始行駛...");
        
        // 實(shí)現(xiàn)開車
        try {
            System.out.println("汽車行駛中...");
            Thread.sleep(new Random().nextInt(1000));
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
//        long endtime = System.currentTimeMillis();
//        System.out.println("汽車結(jié)束行駛...汽車行駛時(shí)間:"+(endtime - starttime) + "毫秒");
    }
    
}

3.編寫Car2類

package com.myimooc.designpattern.c3proxy.car;

/**
 * @describe 繼承的方式實(shí)現(xiàn)靜態(tài)代理
 * @author zc
 * @version 1.0 2017-08-28
 */
public class Car2 extends Car {

    @Override
    public void move() {
        
        long starttime = System.currentTimeMillis();
        System.out.println("汽車開始行駛...");
        
        super.move();
        
        long endtime = System.currentTimeMillis();
        System.out.println("汽車結(jié)束行駛...汽車行駛時(shí)間:"+(endtime - starttime) + "毫秒");
        
    }
}

4.編寫Car3類

package com.myimooc.designpattern.c3proxy.car;

/**
 * @describe 聚合的方式實(shí)現(xiàn)靜態(tài)代理
 * @author zc
 * @version 1.0 2017-08-28
 */
public class Car3 implements Moveable {
    
    public Car3(Car car) {
        super();
        this.car = car;
    }

    private Car car;
    
    @Override
    public void move() {
        
        long starttime = System.currentTimeMillis();
        System.out.println("汽車開始行駛...");
        
        car.move();
        
        long endtime = System.currentTimeMillis();
        System.out.println("汽車結(jié)束行駛...汽車行駛時(shí)間:"+(endtime - starttime) + "毫秒");
        
    }

}

5.編寫Client類

package com.myimooc.designpattern.c3proxy.car;


/**
 * @describe 測試類
 * @author zc
 * @version 1.0 2017-08-28
 */
public class Client {
    
    public static void main(String[] args) {
//        test1();
        test2();
        
    }
    
    // 2-2 聚合與繼承 代理功能疊加測試方法
    public static void test2(){
        Car car = new Car();
        CarLogProxy clp = new CarLogProxy(car);
        CarTimeProxy ctp = new CarTimeProxy(clp);
        ctp.move();
    }
    
    // 2-1 靜態(tài)代理測試方法
    public static void test1(){
//        Car car = new Car();
//        car.move();
        
        // 使用繼承的方式
//        Moveable m = new Car2();
//        m.move();
        
        // 使用聚合方式
        Car car = new Car();
        Moveable m = new Car3(car);
        m.move();
    }
    
}
2-2 聚合與繼承

場景分析

代理類功能疊加

1.記錄日志
2.記錄時(shí)間
3.權(quán)限功能

使用繼承方式

使用繼承方式來實(shí)現(xiàn)代理功能的疊加,代理類會(huì)無限的膨脹下去,所以這種方式不推薦使用。

使用聚合方式,通過代碼演示

代碼編寫

1.復(fù)制Car3命名為CarTimeProxy

package com.myimooc.designpattern.c3proxy.car;

/**
 * @describe 汽車行駛時(shí)間的代理
 * @author zc
 * @version 1.0 2017-08-28
 */
public class CarTimeProxy implements Moveable {
    
    // 因?yàn)榇眍惡捅淮眍惗际菍?shí)現(xiàn)相同的接口,所以構(gòu)造方法傳遞的對象也可以是Moveable對象
    public CarTimeProxy(Moveable m) {
        super();
        this.m = m;
    }

    private Moveable m;
    
    @Override
    public void move() {
        
        long starttime = System.currentTimeMillis();
        System.out.println("汽車開始行駛...");
        
        m.move();
        
        long endtime = System.currentTimeMillis();
        System.out.println("汽車結(jié)束行駛...汽車行駛時(shí)間:"+(endtime - starttime) + "毫秒");
        
    }

}

2.編寫CarLogProxy類

package com.myimooc.designpattern.c3proxy.car;

/**
 * @describe 汽車日志功能的代理
 * @author zc
 * @version 1.0 2017-08-28
 */
public class CarLogProxy implements Moveable {
    
    // 因?yàn)榇眍惡捅淮眍惗际菍?shí)現(xiàn)相同的接口,所以構(gòu)造方法傳遞的對象也可以是Moveable對象
    public CarLogProxy(Moveable m) {
        super();
        this.m = m;
    }
    private Moveable m;
    
    @Override
    public void move() {
        System.out.println("日志開始");
        m.move();
        System.out.println("日志結(jié)束");
    }
}

3.編寫Client類

package com.myimooc.designpattern.c3proxy.car;


/**
 * @describe 測試類
 * @author zc
 * @version 1.0 2017-08-28
 */
public class Client {
    
    public static void main(String[] args) {
//        test1();
        test2();
        
    }
    
    // 2-2 聚合與繼承 代理功能疊加測試方法
    public static void test2(){
        Car car = new Car();
        CarLogProxy clp = new CarLogProxy(car);
        CarTimeProxy ctp = new CarTimeProxy(clp);
        ctp.move();
    }
    
    // 2-1 靜態(tài)代理測試方法
    public static void test1(){
//        Car car = new Car();
//        car.move();
        
        // 使用繼承的方式
//        Moveable m = new Car2();
//        m.move();
        
        // 使用聚合方式
        Car car = new Car();
        Moveable m = new Car3(car);
        m.move();
    }
    
}
2-3 JDK動(dòng)態(tài)代理

場景分析

有沒有方法動(dòng)態(tài)產(chǎn)生代理,實(shí)現(xiàn)對不同類,不同方法的代理呢

JDK動(dòng)態(tài)代理類圖

Java動(dòng)態(tài)代理類位于java.lang.reflect包下,一般主要涉及到以下兩個(gè)類

Interface InvocationHandler:該接口中僅定義了一個(gè)方法
    public Object invoke(Object obj,Method method,Object[] args)
    在實(shí)際使用時(shí),第一參數(shù)obj一般是指代理類,method是被代理的方法,args為該方法的參數(shù)數(shù)組。
    這個(gè)抽象方法在代理類中動(dòng)態(tài)實(shí)現(xiàn)。
Proxy:該類即為動(dòng)態(tài)代理類
    static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)
    返回代理類的一個(gè)實(shí)例,返回后的代理類可以當(dāng)做被代理類使用
    (可使用被代理類的在接口中聲明過的方法)

所謂Dynamic Proxy是這樣一種class

它是在運(yùn)行時(shí)生成的class
該class需要實(shí)現(xiàn)一組interface
使用動(dòng)態(tài)代理類時(shí),必須實(shí)現(xiàn)InvocationHandler接口

動(dòng)態(tài)代理實(shí)現(xiàn)步驟

1.創(chuàng)建一個(gè)實(shí)現(xiàn)InvocationHandler接口的類,它必須實(shí)現(xiàn)invoke方法
2.創(chuàng)建被代理的類以及接口
3.調(diào)用Proxy的靜態(tài)方法,創(chuàng)建一個(gè)代理類
    newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)
4.通過代理調(diào)用方法

代碼編寫

1.編寫TimeHandler類

package com.myimooc.designpattern.c3proxy.jdk;

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

/**
 * @describe 對時(shí)間上的處理-使用JDK動(dòng)態(tài)代理
 * @author zc
 * @version 1.0 2017-08-28
 */
public class TimeHandler implements InvocationHandler {
    
    public TimeHandler(Object target) {
        super();
        this.target = target;
    }

    private Object target;
    
    /**
     * 參數(shù):
     * proxy 被代理對象
     * method 被代理對象方法
     * args 方法的參數(shù)
     * 返回值:
     * Object 方法的返回值
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        
        long starttime = System.currentTimeMillis();
        System.out.println("汽車開始行駛...");
        
        method.invoke(target);
        
        long endtime = System.currentTimeMillis();
        System.out.println("汽車結(jié)束行駛...汽車行駛時(shí)間:"+(endtime - starttime) + "毫秒");
        
        return null;
    }

}

2.編寫Test類

package com.myimooc.designpattern.c3proxy.jdk;

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

import com.myimooc.designpattern.c3proxy.car.Car;
import com.myimooc.designpattern.c3proxy.car.Moveable;

/**
 * @describe JDK動(dòng)態(tài)代理測試類
 * @author zc
 * @version 1.0 2017-08-28
 */
public class Test {
    
    public static void main(String[] args) {
        Car car = new Car();
        InvocationHandler h = new TimeHandler(car);
        Class cls = car.getClass();
        
        // 使用Proxy類newProxyInstance方法動(dòng)態(tài)創(chuàng)建代理類
        /**
         * loader 類加載器
         * interfaces 實(shí)現(xiàn)接口
         * h InvocationHandler
         */
        Moveable m = (Moveable)Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h);
        
        m.move();
        
    }
    
}
2-4 使用cglib

JDK動(dòng)態(tài)代理與CGLIB動(dòng)態(tài)代理區(qū)別

JDK動(dòng)態(tài)代理
1.只能代理實(shí)現(xiàn)了接口的類
2.沒有實(shí)現(xiàn)接口的類不能實(shí)現(xiàn)JDK的動(dòng)態(tài)代理
CGLIB動(dòng)態(tài)代理
1.針對類來實(shí)現(xiàn)代理的
2.對指定目標(biāo)類產(chǎn)生一個(gè)子類,通過方法攔截技術(shù)攔截所有父類方法的調(diào)用
3.因?yàn)槭鞘褂美^承的方式,所以不能對final修飾的類來進(jìn)行代理

代碼編寫

1.添加相關(guān)依賴

      
    
        cglib
        cglib-nodep
        3.2.5
    
      
    
        commons-io
        commons-io
        2.5
    

2.編寫CglibProxy類

package com.myimooc.designpattern.c3proxy.cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * @describe 代理類
 * @author zc
 * @version 1.0 2017-08-28
 */
public class CglibProxy implements MethodInterceptor {
    
    private Enhancer enhance = new Enhancer();
    
    @SuppressWarnings("rawtypes")
    public Object getProxy(Class clazz){
        // 設(shè)置創(chuàng)建子類的類
        enhance.setSuperclass(clazz);
        enhance.setCallback(this);
        return enhance.create();
    }

    /**
     * 攔截所有目標(biāo)類方法的調(diào)用
     * 參數(shù):
     * obj 目標(biāo)類的實(shí)例
     * method 目標(biāo)方法的反射對象
     * args 方法的參數(shù)
     * proxy 代理類的實(shí)例
     */
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        
        System.out.println("日志開始...");
        
        // 代理類調(diào)用父類的方法
        proxy.invokeSuper(obj, args);
        
        System.out.println("日志結(jié)束...");
        
        return null;
    }

}

3.編寫Train類

package com.myimooc.designpattern.c3proxy.cglib;

/**
 * @describe 火車
 * @author zc
 * @version 1.0 2017-08-28
 */
public class Train {
    
    public void move(){
        System.out.println("火車行駛中");
    }
    
}

4.編寫Client類

package com.myimooc.designpattern.c3proxy.cglib;


/**
 * @describe cglib代理測試類
 * @author zc
 * @version 1.0 2017-08-28
 */
public class Client {
    
    public static void main(String[] args) {
        CglibProxy proxy = new CglibProxy();
        Train t = (Train)proxy.getProxy(Train.class);
        t.move();
    }
}
第三章:模擬JDK動(dòng)態(tài)代理 3-1 實(shí)現(xiàn)動(dòng)態(tài)代理

動(dòng)態(tài)代理實(shí)現(xiàn)思路

實(shí)現(xiàn)功能:通過Proxy的newProxyInstance返回代理對象
1.聲明一段源碼(動(dòng)態(tài)產(chǎn)生代理)
2.編譯編碼(JDK Compiler API),產(chǎn)生新的類(代理類)
3.將這個(gè)類load到內(nèi)存當(dāng)中,產(chǎn)生一個(gè)新的對象(代理對象)
4.return 代理對象

代碼編寫

1.編寫InvocationHandler類

package com.myimooc.designpattern.c3proxy.simulationjdk;

import java.lang.reflect.Method;

/**
 * @describe 模擬JDK動(dòng)態(tài)代理-業(yè)務(wù)處理類
 * @author zc
 * @version 1.0 2017-08-28
 */
public interface InvocationHandler {
    
    public void invoke(Object obj,Method method);
    
}

2.編寫Proxy類

package com.myimooc.designpattern.c3proxy.simulationjdk;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

import org.apache.commons.io.FileUtils;

/**
 * @describe 模擬JDK動(dòng)態(tài)代理-代理類
 * @author zc
 * @version 1.0 2017-08-28
 */
@SuppressWarnings({"rawtypes","unchecked"})
public class Proxy {
    
    public static Object newProxyInstance( Class infce,InvocationHandler h)throws Exception{
        String rt = "
";
        String methodStr = "";
        for(Method m : infce.getMethods()){
            methodStr += "    @Override" + rt +
            "    public void "+ m.getName() +"(){" + rt +
            "     try{" + rt +
            "        Method md = " +infce.getName()+".class.getMethod(""+m.getName()+"");" + rt +
            "        h.invoke(this,md);" + rt +
            "     }catch(Exception e){e.printStackTrace();}" + rt +
            "    }" + rt;
        }
        
        String str =
        "package com.myimooc.designpattern.c3proxy.simulationjdk; " + rt +
        "import com.myimooc.designpattern.c3proxy.simulationjdk.InvocationHandler;" + rt +
        "import java.lang.reflect.Method;" + rt +
        "public class $Proxy0 implements "+ infce.getName() +" { " + rt +
        "    public $Proxy0(InvocationHandler h) {" + rt +
        "        this.h = h;" + rt +
        "    }" + rt +
        "    private InvocationHandler h;" + rt +
        methodStr + rt +
        "}";
        
        // 產(chǎn)生代理類的java文件
        String filename = System.getProperty("user.dir") + "/target/classes/com/myimooc/designpattern/c3proxy/simulationjdk/$Proxy0.java";
        File file = new File(filename);
        FileUtils.writeStringToFile(file, str,"UTF-8");
        
        // 編譯-拿到編輯器
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        // 文件管理者
        StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);
        // 獲取文件
        Iterable units = fileMgr.getJavaFileObjects(filename);
        // 編譯任務(wù)
        CompilationTask task = compiler.getTask(null, fileMgr, null, null, null, units);
        // 進(jìn)行編譯
        task.call();
        fileMgr.close();
        
        // load到內(nèi)存
        ClassLoader cl = ClassLoader.getSystemClassLoader();
        Class c = cl.loadClass("com.myimooc.designpattern.c3proxy.simulationjdk.$Proxy0");
        
        Constructor ctr = c.getConstructor(InvocationHandler.class);
        return ctr.newInstance(h);
    }
}

3.編寫TimeHandler類

package com.myimooc.designpattern.c3proxy.simulationjdk;

import java.lang.reflect.Method;

/**
 * @describe 模擬JDK動(dòng)態(tài)代理-時(shí)間業(yè)務(wù)邏輯處理
 * @author zc
 * @version 1.0 2017-08-28
 */
public class TimeHandler implements InvocationHandler{
    
    private Object target;
    
    public TimeHandler(Object target) {
        super();
        this.target = target;
    }

    @Override
    public void invoke(Object obj, Method method) {
        try {
            
            long starttime = System.currentTimeMillis();
            System.out.println("汽車開始行駛...");
            
            method.invoke(target);
            
            long endtime = System.currentTimeMillis();
            System.out.println("汽車結(jié)束行駛...汽車行駛時(shí)間:"+(endtime - starttime) + "毫秒");
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4.編寫Client類

package com.myimooc.designpattern.c3proxy.simulationjdk;

import com.myimooc.designpattern.c3proxy.car.Car;
import com.myimooc.designpattern.c3proxy.car.Moveable;

/**
 * @describe 模擬JDK動(dòng)態(tài)代理-測試類
 * @author zc
 * @version 1.0 2017-08-28
 */
public class Client {
    
    public static void main(String[] args) throws Exception {
        Car car = new Car();
        InvocationHandler h = new TimeHandler(car);
        Moveable m = (Moveable)Proxy.newProxyInstance(Moveable.class,h);
        m.move();
    }
}
第四章:總結(jié) 4-1 課程總結(jié)

總結(jié)

代理模式概念、分類及應(yīng)用場景
場景代理模式
靜態(tài)代理(繼承、聚合)
JDK動(dòng)態(tài)代理實(shí)現(xiàn)日志處理功能
模擬JDK動(dòng)態(tài)代理實(shí)現(xiàn)

代理模式-動(dòng)態(tài)代理

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/70297.html

相關(guān)文章

  • 課網(wǎng)_模式秘密責(zé)任鏈模式學(xué)習(xí)總結(jié)

    時(shí)間:2017年08月30日星期三說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)源碼:https://github.com/zccodere/s...學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:責(zé)任鏈模式簡介 1-1 課程簡介 課程大綱 什么是責(zé)任鏈模式 如何實(shí)現(xiàn)責(zé)任鏈模式 責(zé)任鏈模式如何解耦 責(zé)任鏈模式的應(yīng)用 案例:...

    jsyzchen 評論0 收藏0
  • 課網(wǎng)_模式秘密單例模式學(xué)習(xí)總結(jié)

    時(shí)間:2017年08月27日星期日說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)源碼:https://github.com/zccodere/s...學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:單例模式簡介 1-1 簡介 單例模式 概念及應(yīng)用場合 餓漢模式 懶漢模式 餓漢模式與懶漢模式的區(qū)別 什么是設(shè)計(jì)模式 是一套被反...

    afishhhhh 評論0 收藏0
  • 課網(wǎng)_模式秘密策略模式學(xué)習(xí)總結(jié)

    時(shí)間:2017年08月31日星期四說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)源碼:https://github.com/zccodere/s...學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:策略模式簡介 1-1 簡介 課程大綱 什么是策略模式 策略模式如何實(shí)現(xiàn) 策略模式總結(jié)篇 實(shí)例案例分享 日常生活中的策略 Wor...

    zhongmeizhi 評論0 收藏0
  • 課網(wǎng)_模式秘密適配器模式學(xué)習(xí)總結(jié)

    摘要:時(shí)間年月日星期二說明本文部分內(nèi)容均來自慕課網(wǎng)。慕課網(wǎng)教學(xué)源碼學(xué)習(xí)源碼第一章適配器模式的簡介簡介生活中的適配器翻譯軟件插座適配器適配器模式定義適配器模式講將一個(gè)類的接口,轉(zhuǎn)換成客戶期望的另外一個(gè)接口。 時(shí)間:2017年08月29日星期二說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)源碼:https://github.com/zccodere/s.....

    andong777 評論0 收藏0
  • 課網(wǎng)_模式秘密模版模式學(xué)習(xí)總結(jié)

    摘要:時(shí)間年月日星期六說明本文部分內(nèi)容均來自慕課網(wǎng)。案例介紹飲料機(jī)配置模版把水煮沸泡飲料把飲料倒進(jìn)杯子加調(diào)味料第二章模版模式實(shí)現(xiàn)基本框架代碼編寫編寫類模版模式抽象基類,為所有子類提供一個(gè)算法框架。 時(shí)間:2017年09月02日星期六說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)源碼:https://github.com/zccodere/s...學(xué)習(xí)源...

    Hancock_Xu 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<