国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java動態代理(設計模式)代碼詳解

Java動態代理(設計模式)代碼詳解

2021-03-11 14:03Terence_Jing Java教程

這篇文章主要介紹了Java動態代理(設計模式)代碼詳解,具有一定借鑒價值,需要的朋友可以參考下

基礎:需要具備面向對象設計思想,多態的思想,反射的思想;

java動態代理機制的出現,使得java開發人員不用手工編寫代理類,只要簡單地指定一組接口及委托類對象,便能動態地獲得代理類。代理類會負責將所有的方法調用分派到委托對象上反射執行,在分派執行的過程中,開發人員還可以按需調整委托類對象及其功能,這是一套非常靈活有彈性的代理框架。通過閱讀本文,讀者將會對java動態代理機制有更加深入的理解。本文首先從java動態代理的運行機制和特點出發,對其代碼進行了分析,推演了動態生成類的內部實現。

代理模式的基本概念和分類

代理模式:為其他對象提供一個代理,來控制對這個對象的訪問。代理對象起到中介作用,可以去掉服務或者增加額外的服務,或者引用別人的話:“代理類負責為委托類預處理消息,過濾消息并轉發消息,以及進行消息被委托類執行后的后續處理。”

代理模式在開發中的應用場景

遠程代理:為不同地理的對象提供局域網代表對象。

虛擬代理:根據需要將資源消耗很大的對象進行延遲,真正需要的時候進行創建。比如網頁中的先顯示文字再顯示圖片。

保護代理:控制不同用戶的訪問權限。比如:只有當客戶注冊成功之后,才可以進行增刪改查等操作。

智能引用代理:提供對目標代理額外的服務。

代理模式的實現方式

使用繼承和聚合實現動態代理,哪種更好呢!

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public interface moveable {
    public void move();
}
public class car implements moveable{
    @override
      public void move() {
        try {
            thread.sleep(new random().nextint(1000));
            system.out.println("……行駛中……");
        }
        catch(interruptedexception e) {
            // todo auto-generated catch block
            e.printstacktrace();
        }
    }
}
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("汽車結束行駛……時間:"+(endtime-starttime)+"ms");
    }
}

繼承方式實現代理

moveablecar2=newcar2();
car2.move();

聚合方式實現代理

carcar=newcar();
moveablem=newcar3(car);
m.move();

總結

使用繼承方式不夠靈活,當功能疊加的時候,只能臃腫的擴展代理類;
使用聚合的方式,代理之間可以相互傳遞,靈活的組合代理;

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class carlogproxy extends car{
    @override
      public void move()
      {
        //分離代碼,增加業務邏輯
        long starttime=system.currenttimemillis();
        system.out.println("日志開始……");
        super.move();
        long endtime=system.currenttimemillis();
        system.out.println("日志結束……");
    }
}
public class cartimeproxy implements moveable {
    public cartimeproxy(car car)
      {
        super();
        this.car=car;
    }
    private carcar;
    @override
      public void move() {
        //分離代碼,增加業務邏輯
        long starttime=system.currenttimemillis();
        system.out.println("汽車開始行駛……");
        car.move();
        long endtime=system.currenttimemillis();
        system.out.println("汽車結束行駛……時間:"+(endtime-starttime)+"ms");
    }
}
@test:
car car =new car();
cartimeproxy ctp=new cartimeproxy(car);
carlogproxy clp=new carlogproxy(ctp);
clp.move();
//還可以通過接口相互傳遞代理實例
carlogproxy clp1=new carlogproxy(car);
cartimeproxy ctp1=new cartimeproxy(clp1);
ctp1.move();

jdk動態代理和cglib動態代理

jdk動態代理

代理實現

如果不同的對象要實現相同功能的代理類,應該如何處置?

此時可以試著將其集成在同一個代理類中-----動態代理:實現對不同類/不同方法的代理;

大致過程如下:

Java動態代理(設計模式)代碼詳解

java動態代理類位于java.lang.reflect包下,一般主要涉及到一下兩個類:

(1)interfaceinvocationhandler:該接口中僅定義了一個方法publicobjectinvoke(objectobj,methodmethod,object[]args)

obj:一般是指代理類

method:是被代理的方法

args為該方法的參數數組。

這個抽象的方法在代理類中動態實現。

(2)proxy:該類即為動態代理類

statixobjectnewproxyinstance(classloaderloader,class[]interfaces,invocationhandlerh)

返回甙類類的一個實例,返回后的代理類可以當做被代理類使用(可以使用被代理類在接口中聲明過的方法);

實現實例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@ timehandler
public class timehandler   implements invocationhandler {
    public timehandler(object target) {
        super();
        this.target = target;
    }
    private objecttarget;
    /*
  * 參數:
  * proxy 被代理對象
  * method 被代理對象的方法
  * args 方法的參數
  *
  * 返回值:
  * 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("汽車結束行駛……時間:"+(endtime-starttime)+"ms");
        return null;
    }
}
?
1
2
3
4
5
@被代理類的接口
public interface moveable {
  public void move();
}
@被代理的類
?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class car implements moveable{
    @override
      public void move() {
        try {
            thread.sleep(new random().nextint(1000));
            system.out.println("……行駛中……");
        }
        catch (interruptedexception e) {
            // todo auto-generated catch block
            e.printstacktrace();
        }
    }
}

@測試

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class test {
  /**
  * jdk動態代理的測試類
  */
  public static void main(string[] args) {
   car car=new car();
   invocationhandler h=new timehandler(car);
   class<?>cls=car.getclass();
   /*
    * loader 類加載器
    * interfaces 實現接口
    * h invocationhandler
    */
   moveable m=(moveable)proxy.newproxyinstance(cls.getclassloader(),cls.getinterfaces(),h);
   m.move();
  }
}

&&測試結果

Java動態代理(設計模式)代碼詳解

梳理總結

所為的dynamicproxy是這樣一種class:

它是在運行時生成的class,該class需要實現一組interface,使用動態代理類的時候,必須實現invocationhandler接口。

jdk動態代理的一般步驟

1.創建一個實現接口invocationhandler的類,它必須實現invoke()

2.創建被代理的類以及接口

3.調用proxy的靜態方法,創建一個代理類

newproxyinstance(classloaderloader,class[]interfaces,invocationhandlerh)

4.通過代理調用方法

Java動態代理(設計模式)代碼詳解

cglib動態代理的實現

代理實現

@引入cglib-node-2.2.jar包

@cglibproxy攔截類實現接口methodinterceptor:重寫intercept攔截方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class cglibproxy implements methodinterceptor {
    private enhancerenhancer=new enhancer();
    public object getproxy(class cl)
      {
        //設置創建子類的類
        enhancer.setsuperclass(cl);
        enhancer.setcallback(this);
        return enhancer.create();
    }
    /*
  * 攔截所有目標類方法的調用
  * object 目標類的實例
  * m 目標方法的反射對象
  * args 方法的參數
  * proxy 代理類的實例
  *
  */
    @override
      public object intercept(object obj, method m,object[] args,  methodproxy proxy)throws throwable
    {
        system.out.println("日志開始……");
        //代理類調用父類的方法
        proxy.invokesuper(obj, args);
        system.out.println("日志結束……");
        return null;
    }
}

@被代理類train

?
1
2
3
4
5
6
public class train {
  public void move()
  {
   system.out.println("火車行駛中……");
  }
}

@測試類

?
1
2
3
4
5
6
7
8
9
10
public class test {
  /**
  * cglibproxy動態代理測試類
  */
  public static void main(string[] args) {
   cglibproxy proxy=new cglibproxy();
   train t=(train)proxy.getproxy(train.class);
   t.move();
  }
}

##測試結果:

Java動態代理(設計模式)代碼詳解

梳理總結

使用cglibproxy實現動態代理的一般步驟

1、創建類實現接口methodinterceptor,并重寫intercept方法

2、創建被代理類

3、調用代理類自定義的方法,得到一個代理實例

4、通過代理實例調用被代理類的需要執行的方法

比較總結

jdk動態代理

1、只能代理實現了接口的類

2、沒有實現接口的類不能實現jdk的動態代理

cglib動態代理

1、針對類來實現代理

2、對執行目標類產生一個子類,通過方法攔截技術攔截所有父類方法的調用。

模擬代理產生步驟

思路:

實現功能:通過proxy的newproxyinstance返回代理對象

1、聲明一段源碼(動態產生代理)

2、編譯源碼(jdkcompilerapi)產生新的類(代理類)

3、將這個類load到內存當中,產生一個新的對象(代理對象)

4、返回代理對象

完善動態代理實現

首先得到系統編譯器,通過編譯器得到文件管理者,然后獲取文件,然后編譯器執行編譯任務,完成編譯之后,將class文件加載到類加載器中,通過構造方法得到實例,然后調用newinstance()接收一個對象的實例。

(1)拿到編譯器javacompilercompiler=toolprovider.getsystemjavacompiler();

(2)文件管理者standardjavafilemanagerfilemgr=compiler.getstandardfilemanager(null,null,null);

(3)獲取文件iterableunits=filemgr.getjavafileobjects(filename);

(4)編譯任務compilationtaskt=compiler.gettask(null,filemgr,null,null,null,units);

(5)load到內存

classloadercl=classloader.getsystemclassloader();

classc=cl.loadclass(”com.imooc.proxy.$proxy0”);

(6)通過代理對象的構造器構造實例

constructorctr=c.getconstructor(infce);

ctr.newinstance(newcar());

-------

上說所說,內部的業務邏輯是硬編碼的,如何實現真正的動態代理,動態的指定業務邏輯呢?

1、需要創建一個事務處理器,首先創建一個接口也就是invocationhandler,為了模擬jdk,這里把接口的名字和jdk事務處理器名稱一樣,同樣寫一個方法叫做invoke(),用來表示對某個對象的某個方法進行業務處理,所以需要把某個對象以及對象的方法作為invoke()方法的參數傳遞進來,invoke(objectobj,methodmethod),方法作為參數使用到了java反射,需要把此包引入。這樣invocationhandler接口就完成了。

2、創建事務處理實現類比如說時間代理timerproxy,實現了invocationhandler接口,這樣結構就成了

?
1
2
3
4
5
6
7
8
——————timerproxyimplementsinvocationhandler{
————————-@override
————————-voidinvoke(objectobj,methodmethod){
———————————//業務邏輯<br>
—————————————method.invoke(目標對象,參數);
————————————//業務邏輯<br>
——————————}
—————————}

需要將目標對象傳入,沒有參數可以不寫參數,創建代理對象的構造方法,初始化目標對象

3、在proxy類的newproxyinstance()方法中,除了要把目標class接口作為參數外,還需要把事務處理器invocationhandler傳進去,然后更改創建實例對象中硬編碼的部分用事務處理器方法替代即可。難點在于字符串的拼接。

總結

在我們項目中代理模式有自己的實際意義,比如說我們想要調用某個jar包下的某個類,可以在調用這個類之前之后添加一些特殊的業務邏輯,這種方式也叫作aop面向切面編程。(在不改變原有功能的基礎上,添加額外的功能。)

以上就是本文關于java動態代理(設計模式)代碼詳解的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

原文鏈接:http://blog.csdn.net/csdn_terence/article/details/52860221

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 羞羞视频在线播放 | 黄片毛片免费观看 | 国产毛片av | 国产精品久久久久久久久久免费动 | 日韩一区二区三区在线观看 | 亚洲精品在线看 | 一区自拍| 国产在线一区二区三区 | 久久久久久免费毛片精品 | 欧美日韩综合精品 | 中文学幕专区 | 国产一区二区在线视频 | 99精品久久久久久久免费 | 欧美色综合天天久久综合精品 | 久久久久成人精品 | 亚洲片国产一区一级在线观看 | 国产精品久久精品 | 久久这里只有精品8 | 国产精品国产三级国产aⅴ中文 | 中文字幕亚洲欧美 | 欧美国产精品一区二区 | 透逼视频| 亚洲精品成人在线 | 精品日韩一区二区 | 久久性| 黄色国产视频 | 欧美成人一区二免费视频软件 | 亚洲欧美一区二区三区情侣bbw | 免费特级黄毛片 | 亚洲免费视频网站 | 欧美激情国产日韩精品一区18 | 国产成人一区 | 欧美一区二区在线视频 | 伊人干 | 婷婷亚洲五月 | 男女羞羞网站 | 久久久午夜爽爽一区二区三区三州 | 亚洲欧美观看 | 中文字幕av一区二区三区 | 国产精品亚洲第一区 | 91免费在线视频 |