設計模式之代理模式

前提:代理類和被代理類均繼承自統一接口。代理模式是使用代理類去控制被代理類的方法。(ps:好久沒更新,不知道更啥,先發着以前寫的。。。)

 
靜態代理、JDK動態代理、Cglib動態代理區別(面試題):
靜態代理需要目標對象、代理對象均實現同一接口。JDK動態代理僅需目標對象實現接口。Cglib動態代理中目標對象、代理對象均不用實現接口,其底層通過ASM轉換字節碼來生成目標對象子類,從而實現對目標對象的功能擴展。Aop也是根據目標對象是否有接口來決定用JDK還是Cglib動態代理。
 
--------------------------------靜態代理----------------------------------------
1 公用接口類(買房方式):
public interface BuyHouse {
    void buyHosue();
}
 
2 被代理類類(買房的人-自己找):
public class BuyHouseImpl implements BuyHouse {
    @Override
    public void buyHosue() {
            System.out.println("我要買房");    
    }
}
 
3 代理類(中介-中介找):
public class BuyHouseProxy implements BuyHouse {
    private BuyHouse buyHouse;
 
    public BuyHouseProxy(final BuyHouse buyHouse) {
        this.buyHouse = buyHouse;
    }
 
    @Override
    public void buyHosue() {
            System.out.println("買房前準備");
      buyHouse.buyHosue();
            System.out.println("買房後裝修");
    }
}
 
4 調用:
public class Test {
    public static void main(String[] args) {
    BuyHouse buyHouseProxy = new BuyHouseProxy(new BuyHouseImpl());
        buyHouseProxy.buyHosue();  //結果:“買房前準備     我要買房     買房後裝修
    }
}
--------------------------------靜態代理----------------------------------------
--------------------------------JDK動態代理----------------------------------------
/** * 創建動態代理對象
* 動態代理不需要實現接口,但是需要指定接口類型
*/ 
public class ProxyFactory{ 
    //維護一個目標對象 
    private Object target; 
    public ProxyFactory(Object target){ this.target=target; } 
    //給目標對象生成代理對象 
    public Object getProxyInstance(){ 
        return Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(), 
            new InvocationHandler() { 
                @Override public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                    System.out.println("開始事務2"); 
                    //執行目標對象方法 Object returnValue = method.invoke(target, args);
                    System.out.println("提交事務2");     
                    return returnValue;
                }
            }
        );
    }
}
public class App { 
    public static void main(String[] args) { 
        // 目標對象 
        IUserDao target = new UserDao(); 
        // 【原始的類型 class cn.itcast.b_dynamic.UserDao】 
        System.out.println(target.getClass()); 
        // 給目標對象,創建代理對象 
        IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance(); 
        // class $Proxy0 內存中動態生成的代理對象 
        System.out.println(proxy.getClass()); 
        // 執行方法 【代理對象】 
        proxy.save();
    }
}
--------------------------------Cglib動態代理----------------------------------------
/** * Cglib子類代理工廠 * 對UserDao在內存中動態構建一個子類對象 */ 
public class ProxyFactory implements MethodInterceptor{ 
    //維護目標對象 
    private Object target; 
    public ProxyFactory(Object target) { this.target = target; } 
    //給目標對象創建一個代理對象 
    public Object getProxyInstance(){ 
        //1.工具類 
        Enhancer en = new Enhancer(); 
        //2.設置父類 
        en.setSuperclass(target.getClass()); 
        //3.設置回調函數 
        en.setCallback(this); 
        //4.創建子類(代理對象) 
        return en.create();
    } 
    @Override 
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
        throws Throwable {
        System.out.println("開始事務..."); 
        //執行目標對象的方法 
        Object returnValue = method.invoke(target, args);
        System.out.println("提交事務..."); 
        return returnValue;
    }
}
--------------------------------Cglib動態代理----------------------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章