<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    qileilove

    blog已經轉移至github,大家請訪問 http://qaseven.github.io/

    Java 代理(proxy)模式

    代理模式(Proxy Pattern)
      代理模式是常用的Java 設計模式,它的特征是代理類與委托類有同樣的接口,代理類主要負責為委托類預處理消息、過濾消息、把消息轉發給委托類,以及事后處理消息等。代理類與委托類之間通常會存在關聯關系,一個代理類的對象與一個委托類的對象關聯,代理類的對象本身并不真正實現服務,而是通過調用委托類的對象的相關方法,來提供特定的服務。
      如下列子:
    package proxy;
    interface Dao{
    public void insert();
    }
    class JdbcDao implements Dao{
    public void insert(){
    System.out.println("in jdbc insert");
    }
    }
    class HibernateDao implements Dao{
    public void insert(){
    System.out.println("in hibernate insert");
    }
    }
    class ProxyDao implements Dao{
    private Dao dao;
    public ProxyDao(Dao dao){
    this.dao=dao;
    }
    public void insert() {
    System.out.println("write log before invoke");
    dao.insert();
    System.out.println("write log after invoke");
    }
    }
    public class Test {
    public static void main(String[] args) {
    Dao jdbcDao =new JdbcDao();
    Dao proxydao = new ProxyDao(jdbcDao);
    proxydao.insert();
    }
    }
      運行結果:
      write log before invoke
      in jdbc insert
      write log after invoke
      隨著Proxy的流行,Sun把它納入到JDK1.3實現了Java的動態代理。動態代理和普通的代理模式的區別,就是動態代理中的代理類是由 java.lang.reflect.Proxy類在運行期時根據接口定義,采用Java反射功能動態生成的。和 java.lang.reflect.InvocationHandler結合,可以加強現有類的方法實現。如圖2,圖中的自定義Handler實現 InvocationHandler接口,自定義Handler實例化時,將實現類傳入自定義Handler對象。自定義Handler需要實現 invoke方法,該方法可以使用Java反射調用實現類的實現的方法,同時當然可以實現其他功能,例如在調用實現類方法前后加入Log。而Proxy類根據Handler和需要代理的接口動態生成一個接口實現類的對象。當用戶調用這個動態生成的實現類時,實際上是調用了自定義Handler的 invoke方法。
      Proxy類提供了創建動態代理類及其實例的靜態方法。
      (1)getProxyClass()靜態方法負責創建動態代理類,它的完整定義如下:
      public static Class<?> getProxyClass(ClassLoader loader, Class<?>[] interfaces) throws IllegalArgumentException
      參數loader 指定動態代理類的類加載器,參數interfaces 指定動態代理類需要實現的所有接口。
      (2)newProxyInstance()靜態方法負責創建動態代理類的實例,它的完整定義如下:
      public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) throws
      IllegalArgumentException
      參數loader 指定動態代理類的類加載器,參數interfaces 指定動態代理類需要實現的所有接口,參數handler 指定與動態代理類關聯的 InvocationHandler 對象。
      以下兩種方式都創建了實現Foo接口的動態代理類的實例:
      /**** 方式一 ****/
      //創建InvocationHandler對象
      InvocationHandler handler = new MyInvocationHandler(...);
      //創建動態代理類
      Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), new Class[] { Foo.class });
      //創建動態代理類的實例
      Foo foo = (Foo) proxyClass.getConstructor(new Class[] { InvocationHandler.class }).
      newInstance(new Object[] { handler });
      /**** 方式二 ****/
      //創建InvocationHandler對象
      InvocationHandler handler = new MyInvocationHandler(...);
      //直接創建動態代理類的實例
      Foo foo = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[] { Foo.class }, handler);
      由Proxy類的靜態方法創建的動態代理類具有以下特點:
      動態代理類是public、final和非抽象類型的;
      動態代理類繼承了java.lang.reflect.Proxy類;
      動態代理類的名字以“$Proxy”開頭;
      動態代理類實現getProxyClass()和newProxyInstance()方法中參數interfaces指定的所有接口;
      Proxy 類的isProxyClass(Class<?> cl)靜態方法可用來判斷參數指定的類是否為動態代理類。只有通過Proxy類創建的類才是動態代理類;
      動態代理類都具有一個public 類型的構造方法,該構造方法有一個InvocationHandler 類型的參數。
      由Proxy類的靜態方法創建的動態代理類的實例具有以下特點:
      1. 假定變量foo 是一個動態代理類的實例,并且這個動態代理類實現了Foo 接口,那么“foo instanceof Foo”的值為true。把變量foo強制轉換為Foo類型是合法的:
      (Foo) foo //合法
      2.每個動態代理類實例都和一個InvocationHandler 實例關聯。Proxy 類的getInvocationHandler(Object proxy)靜態方法返回與參數proxy指定的代理類實例所關聯的InvocationHandler 對象。
      3.假定Foo接口有一個amethod()方法,那么當程序調用動態代理類實例foo的amethod()方法時,該方法會調用與它關聯的InvocationHandler 對象的invoke()方法。
      InvocationHandler 接口為方法調用接口,它聲明了負責調用任意一個方法的invoke()方法:
      Object invoke(Object proxy,Method method,Object[] args) throws Throwable
      參數proxy指定動態代理類實例,參數method指定被調用的方法,參數args 指定向被調用方法傳遞的參數,invoke()方法的返回值表示被調用方法的返回值。
      最后看一個例子,該例子模仿spring 的AOP原理。
    package proxy;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    class Logic{
    public void logic(){
    Dao dao = Factory.create();
    System.out.println("dynamic proxy's name: "+dao.getClass().getName());
    dao.insert();
    }
    }
    class Factory{
    static Dao create(){
    Dao dao = new JdbcDao();
    MyInvocationHandler hand = new MyInvocationHandler();
    return (Dao)hand.get(dao);
    }
    }
    interface Dao{
    public void update();
    public void insert();
    }
    class JdbcDao implements Dao{
    public void update(){
    System.out.println("in jdbc update");
    }
    public void insert(){
    System.out.println("in jdbc insert");
    }
    }
    class HibernateDao implements Dao{
    public void update(){
    System.out.println("in hibernate update");
    }
    public void insert(){
    System.out.println("in hibernate insert");
    }
    }
    class MyInvocationHandler implements InvocationHandler {
    Object o;
    public Object get(Object o){
    System.out.println("in get method of MyInvocationHandler");
    this.o = o;
    return Proxy.newProxyInstance(o.getClass().getClassLoader(),o.getClass().getInterfaces(),this);
    }
    public Object invoke(Object arg0, Method arg1, Object[] arg2)
    throws Throwable {
    System.out.println("write log before invoke");
    Object result = arg1.invoke(o, arg2);
    System.out.println("write log after invoke");
    return result;
    }
    }
    public class Test {
    public static void main(String[] args) {
    Logic l = new Logic();
    l.logic();
    }
    }
      運行結果:
      in get method of MyInvocationHandler
      dynamic proxy's name: proxy.$Proxy0
      write log before invoke
      in jdbc insert
      write log after invoke
      結論: JDK的動態代理并不能隨心所欲的代理所有的類。Proxy.newProxyInstance方法的第二個參數只能是接口數組, 也就是Proxy只能代理接口。

    posted on 2014-08-05 10:01 順其自然EVO 閱讀(205) 評論(0)  編輯  收藏 所屬分類: 測試學習專欄

    <2014年8月>
    272829303112
    3456789
    10111213141516
    17181920212223
    24252627282930
    31123456

    導航

    統計

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 女人与禽交视频免费看| 一区在线免费观看| 亚洲av无码成人精品国产 | ASS亚洲熟妇毛茸茸PICS| 久久精品国产亚洲av天美18| 特级av毛片免费观看| 天堂在线免费观看| 日本免费网址大全在线观看| 女人张开腿等男人桶免费视频 | 黄色毛片视频免费| 国产成人精品无码免费看| 国产免费久久精品99re丫y| 四虎影视永久免费视频观看| 在线观看亚洲精品国产| 337p日本欧洲亚洲大胆色噜噜| 亚洲高清中文字幕免费| 免费无遮挡无遮羞在线看| 男人的天堂网免费网站| 处破痛哭A√18成年片免费| 在线观看亚洲天天一三视| 337p日本欧洲亚洲大胆精品555588| 亚洲另类无码专区丝袜| 日韩电影免费在线观看网站| 无码国产精品一区二区免费I6| 亚洲真人日本在线| 亚洲午夜成人精品无码色欲| 最近中文字幕免费大全| 在线免费观看a级片| 久久久久亚洲av无码专区导航| 色一情一乱一伦一视频免费看| 亚洲一级毛片免费看| 青青草原亚洲视频| 国产天堂亚洲国产碰碰| 182tv免费视视频线路一二三| 免费中文字幕在线观看| 亚洲综合久久一本伊伊区| 你是我的城池营垒免费观看完整版| 超pen个人视频国产免费观看| 亚洲精品视频在线观看视频| 国产午夜成人免费看片无遮挡| 免费人成视频在线观看视频|