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

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

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

    千里冰封
    JAVA 濃香四溢
    posts - 151,comments - 2801,trackbacks - 0
    今天上午寫了一個有關于EJB的攔截例子,其實EJB的攔截用的就是JAVA的代理機制.說廣一點,EJB的實現就是利用代理實現的遠程方法調用.
    EJB會在服務器端生成一個實現了所有的接口的類的代理,然后在里面監聽你所做的所有事情,并與之反應,這樣就實現了遠程調用的效果,你在這邊調用,而EJB容器在別的地方也可以知道你調用了什么,并返回與之對應的結果,這一切都是用代理來實現的.

    下面我們就來認識一下,代理的主要類:java.lang.reflect.Proxy
    它定義了一套靜態方法,供我們使用,其中一個最常用的方法就是生成代理對象
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
                                   throws IllegalArgumentException

    它根據你傳入的類加載器和這個代理將會實現的接口,以及一個調用處理器,來生成一個代理對象.說起來比較抽象,還是給點例子吧:
    先聲明一個接口,用來調用代理的方法
    /*
     * MyInterface.java
     *
     * Created on 2007年9月8日, 下午4:38
     *
     * To change this template, choose Tools | Template Manager
     * and open the template in the editor.
     
    */

    package test4;

    /**
     *
     * 
    @author hadeslee
     
    */
    public interface MyInterface {
        
    public void sayHello(String s);
        
    public void doSth();
    }

    然后再寫一個類實現此方法
    /*
     * Test1.java
     *
     * Created on 2007年9月8日, 下午4:31
     *
     * To change this template, choose Tools | Template Manager
     * and open the template in the editor.
     
    */

    package test4;

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.util.ArrayList;
    import java.util.List;


    /**
     *
     * 
    @author hadeslee
     
    */
    public class Test1 implements MyInterface{
        
        
    /** Creates a new instance of Test1 */
        
    public Test1() {
            
        }
        
        
    public static void main(String[] args) throws Exception{
            Test1 list
    =new Test1();
            MyInterface my
    =(MyInterface)Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                    list.getClass().getInterfaces(),
                    
    new MyHandler<MyInterface>(list));
            System.out.println(
    "my.name="+my.getClass().getName());
            my.doSth();
            my.sayHello(
    "千里冰封");
        }
        
    //接口中的方法
        public void sayHello(String s) {
            System.out.println(
    "sayHello to:"+s);
        }
        
    //接口中的方法
        public void doSth() {
            System.out.println(
    "doSth()");
        }
        
    //一個靜態內部類,實現了InvocationHandler的接口,
        
    //它也是一個關鍵的接口,所有代理后的行為都是在這里實現的
        static class MyHandler<T> implements InvocationHandler{
            
    private T t;
            
    public MyHandler(T t){
                
    this.t=t;
            }
            
    //實現方法調用
            
    //可以自己加上自己的一些調用,此例中只是在加上了一個輸出
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println(
    "我知道馬上要被調用的方法是:"+method.getName());
                
    return method.invoke(t,args);
            }
            
        }
    }

    運行上面的類輸出是:

    my.name=$Proxy0
    我知道馬上要被調用的方法是:doSth
    doSth()
    我知道馬上要被調用的方法是:sayHello
    sayHello to:千里冰封

    從這里可以看出,代理的類的名字換成了$Proxy0,其中$Proxy是所有代理類的類名前綴
    我們在調用doSth()和sayHello()的時候,都調用到了我們在代理中設置的輸出.如果你想在這里代理別的類,也是可以的,只要你符合以上的調用規律.
    最后特別要注意的一點是:

    //實現方法調用
            
    //可以自己加上自己的一些調用,此例中只是在加上了一個輸出
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println(
    "我知道馬上要被調用的方法是:"+method.getName());
                
    return method.invoke(t,args);
            }

    在上面的實現中,千萬不能調用method.invoke(proxy,args).因為proxy本身就是一個代理的對象,你如果再在它上面調用一個方法的話,會無限遞歸的調用這個方法,所以,在InvocationHandler的實現里面,最好是傳一個代理對象的真正實現進去,這樣就可以還原本來的調用結果,并加上自己的東西在里面.



    盡管千里冰封
    依然擁有晴空

    你我共同品味JAVA的濃香.
    posted on 2007-09-08 18:12 千里冰封 閱讀(6519) 評論(11)  編輯  收藏 所屬分類: JAVASE

    FeedBack:
    # re: JAVA代理機制初探
    2007-09-09 07:07 | sitinspring
    真是不錯,這個方式用對地方了能有很大作為.每天看看Blogjava的首頁更新都能有所收獲,有時還有意外驚喜.  回復  更多評論
      
    # re: JAVA代理機制初探
    2007-09-09 09:34 | 兵臨城下
    這其實和Spring的AOP是一個概念,實現方法都是一致的  回復  更多評論
      
    # re: JAVA代理機制初探
    2007-09-09 12:39 | BeanSoft
    呵呵, 確切說 AOP 的底層實現應該是用代理. 基本上大部分的連接池啊啥的都用代理來做了. 方法攔截(Interceptors)本質上也是代理.  回復  更多評論
      
    # re: JAVA代理機制初探
    2007-09-10 00:04 | 楊愛友
    @BeanSoft
    有了spring的 aop不知道方法攔截還有什么必要,AOP完全可以實現方法攔截啊。  回復  更多評論
      
    # re: JAVA代理機制初探
    2007-09-10 02:12 | yexiaozi
    (1)生成代理對象:
    MyInterface my=(MyInterface)Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
    list.getClass().getInterfaces(),
    new MyHandler<MyInterface>(list));
    (2)然后怎么調用 invoke(*,*,*)?
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("我知道馬上要被調用的方法是:"+method.getName());
    return method.invoke(t,args);
    }
    樓主,給個答復看???????????????????????????????????????????  回復  更多評論
      
    # re: JAVA代理機制初探
    2007-09-10 02:14 | yexiaozi
    樓主:你能否把代碼調用的流程,幫我解釋下(越詳細越好),偶剛接觸代理,
    麻煩了!辛苦了!謝謝了!  回復  更多評論
      
    # re: JAVA代理機制初探
    2007-09-10 14:37 | 千里冰封
    @yexiaozi
    關于invoke的使用方法如下:
    invoke(Object obj, Object... args)
    對帶有指定參數的指定對象調用由此 Method 對象表示的底層方法。
    第一個obj表示你要調用哪個對象上的方法,后面的可變參數表示你傳入的參數列表
      回復  更多評論
      
    # re: JAVA代理機制初探
    2007-09-10 14:38 | 千里冰封
    @yexiaozi
    生成了代理對象之后,代理對象會自動攔截你對方法的調用,而調用你在InvokcationHandler里面定義的invoke方法,從而實現所有調用的方法對你來說都是可知道的  回復  更多評論
      
    # re: JAVA代理機制初探
    2007-09-10 16:05 | 黑盒子
    盼望后續深入研究~~~~~  回復  更多評論
      
    # re: JAVA代理機制初探
    2007-09-16 22:29 | yexiaozi
    謝謝樓主!好幾天沒來看了?今天發現樓主回復了!
    理解了一點哦!  回復  更多評論
      
    # re: JAVA代理機制初探[未登錄]
    2008-09-22 10:28 | ben
    不錯,謝謝樓主分享。  回復  更多評論
      
    主站蜘蛛池模板: 国产一区二区三区免费在线观看| 成人福利免费视频| 黄桃AV无码免费一区二区三区| 亚洲jizzjizz在线播放久| 中文字幕亚洲免费无线观看日本| 亚洲第一二三四区| 亚洲av无码专区青青草原| 阿v视频免费在线观看| 中文字幕视频在线免费观看| 精品一区二区三区无码免费视频 | 亚洲欧洲精品一区二区三区| 亚洲人6666成人观看| 人人爽人人爽人人片av免费 | 日韩成人免费视频| 香蕉视频在线观看免费国产婷婷 | 57PAO成人国产永久免费视频| 香蕉视频在线观看免费国产婷婷| 亚洲午夜国产精品无码老牛影视| 亚洲一区二区在线免费观看| 亚洲日韩国产AV无码无码精品| 边摸边脱吃奶边高潮视频免费| 一区二区免费视频| 国产性爱在线观看亚洲黄色一级片| 337p日本欧洲亚洲大胆色噜噜| xxxx日本在线播放免费不卡| 在线观看特色大片免费视频| 亚洲乱码中文字幕手机在线| 亚洲AV无码一区二区三区牲色| 久久香蕉国产线看免费| 免费大片在线观看网站| 亚洲性线免费观看视频成熟| 91在线手机精品免费观看| 亚洲熟妇无码另类久久久| 一本久久免费视频| 亚洲av中文无码| 一级特黄录像免费播放中文版| 国产一精品一aⅴ一免费| 亚洲丶国产丶欧美一区二区三区| 国产h肉在线视频免费观看| 亚洲国产精品一区二区第一页| 人与动性xxxxx免费|