靜態代理和動態代理demo

//抽象接口 ,描述了服務提供者的行爲 代理接口
public interface ManToolsFactory {
    void saleManTools(String size);
}

 

//抽象接口 ,描述了服務提供者的行爲 代理接口
public interface WomanToolsFactory {
    void saleWomanTools(float length);
}
/**
 * 靜態代理和動態代理的區別
 * 靜態代理通常只代理一個類,動態代理是代理一個接口下的多個實現類。
 * 靜態代理要事先知道要代理的是什麼,而動態代理不知道具體要代理的是什麼東西,只有在運行時才知道。
 * 動態代理是實現jdk 裏的invocationHandler接口的invoke 方法,但注意的是代理的是接口,
 * 也就是你的實現類必須要實現接口,通過proxy裏的 newProxyInstance得到代理對象。
 *
 * 靜態代理優點:
 *  業務類只需要關注業務邏輯本身,保證了業務類的重用性,這是代理共有的優點。
 *  缺點:
 *      1,代理對象的一個接口只服務於一種類型的對象。如果要代理的方法很多。要爲每一種方法都進行代理。
 *      2,如果接口增加一個方法,除了所有實現類需要實現這個方法外,所有代理類也需要實現此方法,增加了代碼維護的複雜性。
 */

//真正提供服務的類 具體業務邏輯類
public class AaFactory implements ManToolsFactory {

    @Override
    public void saleManTools(String size) {
        System.out.println("根據你的需求提供了Size爲"+size+"手機");
    }
}

 

/**
 * 靜態代理和動態代理的區別
 * 靜態代理通常只代理一個類,動態代理是代理一個接口下的多個實現類。
 * 靜態代理要事先知道要代理的是什麼,而動態代理不知道具體要代理的是什麼東西,只有在運行時才知道。
 * 動態代理是實現jdk 裏的invocationHandler接口的invoke 方法,但注意的是代理的是接口,
 * 也就是你的實現類必須要實現接口,通過proxy裏的 newProxyInstance得到代理對象。
 *
 * 靜態代理優點:
 *  業務類只需要關注業務邏輯本身,保證了業務類的重用性,這是代理共有的優點。
 *  缺點:
 *      1,代理對象的一個接口只服務於一種類型的對象。如果要代理的方法很多。要爲每一種方法都進行代理。
 *      2,如果接口增加一個方法,除了所有實現類需要實現這個方法外,所有代理類也需要實現此方法,增加了代碼維護的複雜性。
 */
public class BbFactory  implements  WomanToolsFactory{
    @Override
    public void saleWomanTools(float length) {
        System.out.println("根據你的需求,定製長度爲"+length+"的手機");
    }
}

靜態代理對象 

//代理對象,包含真實的對象,爲真實的對象的服務進行真強,和真實對象繼承於同一個接口
public class Chinar implements ManToolsFactory {

    //被包含的真實對象
    public ManToolsFactory factory;

    public Chinar(ManToolsFactory factory){
        super();
        this.factory = factory;
    }

    @Override
    public void saleManTools(String size) {
        dosomeThingBefore();//前置真強
        factory.saleManTools(size);
        dosomeThingEnd();//後置增強
    }

    //售前服務
    private void dosomeThingBefore(){
        System.out.println("精美包裝,快遞一條龍服務");
    }

    //售後服務
    private void dosomeThingEnd(){
        System.out.println("根據你的需求,進行市場調研和分析");
    }
}

靜態代理 

/**
 * 生成靜態代理類工廠
 */
public class SubjectStaticFactory {
    //客戶類調用此工廠方法獲得代理對象。  
    //對客戶類來說,其並不知道返回的是代理類對象還是委託類對象。  
    public static ManToolsFactory getinstance(){
        //具體實現業務邏輯類
        ManToolsFactory factory = new AaFactory();
        //我代理這個公司的產品  代理對象
        Chinar chinar = new Chinar(factory);
        return chinar;
       // return new Chinar(new AaFactory());
    }
}

 靜態代理測試

/**
 * 靜態代理測試類
 */
public class ZhanSan {
    public static void main(String []args){
        //靜態代理
        ManToolsFactory factory = new AaFactory();
        //我代理這個公司的產品
        Chinar chinar = new Chinar(factory);
        //調用該產品方法
        chinar.saleManTools("20");

        System.out.println("-----------------------------------------------------------");

        //利用靜態代理工廠來調用
        ManToolsFactory proxy = SubjectStaticFactory.getinstance();
        proxy.saleManTools("22");
        System.out.println("-----------------------------------------------------------");
    }
}

動態代理

/**
 * 動態測試類
 */
public class WangWu {

    public static void main(String []args){
        //動態代理  只增加接口和接口實現,代理類不需要修改代碼
        //A代理公司
        ManToolsFactory aFactory = new AaFactory();
        //B代理公司
        WomanToolsFactory bbFactory = new BbFactory();
        //代購公司
        Chinarui chinarui = new Chinarui();
        //張三來找我要代購產品
        chinarui.setFactory(aFactory);

        System.out.println("-----------------------------------------------------------");

        //1號業務員對這個行業收悉,派1號業務員爲他服務
        ManToolsFactory chinarui1= (ManToolsFactory) chinarui.getProxyInstance();
        chinarui1.saleManTools("21");
        System.out.println("-----------------------------------------------------------");

//        //張三朋友來找我,代購xxx產品
//        chinarui.setFactory(bbFactory);
//        //2號業務員對這個行業收悉,派2號業務員爲他服務
//        WomanToolsFactory chinarui2= (WomanToolsFactory) chinarui.getProxyInstance();
//        chinarui2.saleWomanTools(1.9F);
//
//        ProxyUtil.generateClassFile(aFactory.getClass(),chinarui1.getClass().getSimpleName());
//        ProxyUtil.generateClassFile(aFactory.getClass(),chinarui2.getClass().getSimpleName());
    }
}

 


import sun.misc.FileURLMapper;
import sun.misc.ProxyGenerator;

import java.io.FileOutputStream;
import java.io.IOException;

public class ProxyUtil {

    /**
     * 將動態生成的2進制字節碼保存到硬盤中,
     * @param classz   需要動態代理的類
     * @param proxuyName 爲動態代理生成的類的名稱
     */
    public static void generateClassFile(Class classz, String proxuyName){

        //根據類信息和代理類名稱生成字節碼。
        byte[] classFile = ProxyGenerator.generateProxyClass(proxuyName, new Class[]{classz});

        String paths = classz.getResource(".").getPath();
        System.out.println(paths);

        FileOutputStream out = null ;

        //保存到硬盤中
        try{
            out = new FileOutputStream(paths + proxuyName + ".class");
            out.write(classFile);
            out.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                out.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

 

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