激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

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

服務(wù)器之家 - 編程語言 - Java教程 - 老生常談設(shè)計(jì)模式之動(dòng)態(tài)代理

老生常談設(shè)計(jì)模式之動(dòng)態(tài)代理

2020-11-13 10:40Java教程網(wǎng) Java教程

下面小編就為大家?guī)硪黄仙U勗O(shè)計(jì)模式之動(dòng)態(tài)代理。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

一、動(dòng)態(tài)代理概念

動(dòng)態(tài)代理分為JDK動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理兩種方式。

jdk動(dòng)態(tài)代理是由Java內(nèi)部的反射機(jī)制來實(shí)現(xiàn)的,cglib動(dòng)態(tài)代理底層則是借助asm來實(shí)現(xiàn)的。

總的來說,反射機(jī)制在生成類的過程中比較高效,而asm在生成類之后的相關(guān)執(zhí)行過程中比較高效(可以通過將asm生成的類進(jìn)行緩存,這樣解決asm生成類過程低效問題)。

還有一點(diǎn)必須注意:jdk動(dòng)態(tài)代理的應(yīng)用前提,必須是目標(biāo)類基于統(tǒng)一的接口。如果沒有上述前提,jdk動(dòng)態(tài)代理不能應(yīng)用

由此可以看出,jdk動(dòng)態(tài)代理有一定的局限性,cglib這種第三方類庫實(shí)現(xiàn)的動(dòng)態(tài)代理應(yīng)用更加廣泛,且在效率上更有優(yōu)勢。

二、JDK動(dòng)態(tài)代理

以下代碼使用代理模式實(shí)現(xiàn)一個(gè)大小寫字符轉(zhuǎn)換的功能。

定義接口和實(shí)現(xiàn)類:

ISomeService接口:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.ietree.basicskill.designpattern.dynamicproxy.jdk;
 
/**
 * 接口類
 *
 * @author Root
 */
public interface ISomeService {
  
  String doFirst();
  
  void doSecond();
}

SomeServiceImpl實(shí)現(xiàn)類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.ietree.basicskill.designpattern.dynamicproxy.jdk;
 
/**
 * 實(shí)現(xiàn)類
 *
 * @author Root
 */
public class SomeServiceImpl implements ISomeService {
 
  @Override
  public String doFirst() {
    System.out.println("執(zhí)行doFirst()...");
    String result = "abcde";
    return result;
  }
 
  @Override
  public void doSecond() {
    System.out.println("執(zhí)行doSecond()...");
  }
 
}

JDK動(dòng)態(tài)代理類:

?
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
package com.ietree.basicskill.designpattern.dynamicproxy.jdk;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
public class Main {
  public static void main(String[] args) {
 
    final ISomeService target = new SomeServiceImpl();
    
    // 使用JDK的Proxy動(dòng)態(tài)代理,要求目標(biāo)類和代理類必須實(shí)現(xiàn)相同的接口,因?yàn)槠涞讓拥膱?zhí)行原理與靜態(tài)代理的相同
    ISomeService service = (ISomeService) Proxy.newProxyInstance(
        // 目標(biāo)類的類加載器
        target.getClass().getClassLoader(),
        // 目標(biāo)類所實(shí)現(xiàn)的所有接口
        target.getClass().getInterfaces(),
        new InvocationHandler() {
          // proxy:代理對象
          // method:目標(biāo)方法
          // args:目標(biāo)方法的參數(shù)列表
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 調(diào)用目標(biāo)方法
            Object result = method.invoke(target, args);
            if (result != null) {
              result = ((String) result).toUpperCase();
            }
            return result;
          }
        });
    String result = service.doFirst();
    System.out.println(result);
 
    service.doSecond();
  }
}

三、cglib動(dòng)態(tài)代理

Cglib是一個(gè)優(yōu)秀的動(dòng)態(tài)代理框架,它的底層使用ASM在內(nèi)存中動(dòng)態(tài)的生成被代理類的子類,使用CGLIB即使代理類沒有實(shí)現(xiàn)任何接口也可以實(shí)現(xiàn)動(dòng)態(tài)代理功能。CGLIB具有簡單易用,它的運(yùn)行速度要遠(yuǎn)遠(yuǎn)快于JDK的Proxy動(dòng)態(tài)代理:

CGLIB的核心類:

net.sf.cglib.proxy.Enhancer – 主要的增強(qiáng)類

net.sf.cglib.proxy.MethodInterceptor – 主要的方法攔截類,它是Callback接口的子接口,需要用戶實(shí)現(xiàn)

net.sf.cglib.proxy.MethodProxy – JDK的java.lang.reflect.Method類的代理類,可以方便的實(shí)現(xiàn)對源對象方法的調(diào)用,如使用:

Object o = methodProxy.invokeSuper(proxy, args);//雖然第一個(gè)參數(shù)是被代理對象,也不會(huì)出現(xiàn)死循環(huán)的問題。

net.sf.cglib.proxy.MethodInterceptor接口是最通用的回調(diào)(callback)類型,它經(jīng)常被基于代理的AOP用來實(shí)現(xiàn)攔截(intercept)方法的調(diào)用。這個(gè)接口只定義了一個(gè)方法

public Object intercept(Object object, java.lang.reflect.Method method, Object[] args, MethodProxy proxy) throws Throwable;

第一個(gè)參數(shù)是代理對像,第二和第三個(gè)參數(shù)分別是攔截的方法和方法的參數(shù)。原來的方法可能通過使用java.lang.reflect.Method對象的一般反射調(diào)用,或者使用 net.sf.cglib.proxy.MethodProxy對象調(diào)用。net.sf.cglib.proxy.MethodProxy通常被首選使用,因?yàn)樗臁?/p>

以下程序?qū)崿F(xiàn)了大小寫轉(zhuǎn)換的功能:

實(shí)現(xiàn)類SomeService:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.ietree.basicskill.designpattern.dynamicproxy.cglib;
 
/**
 * 實(shí)現(xiàn)類
 *
 * @author Root
 */
public class SomeService {
 
  public String doFirst() {
    System.out.println("執(zhí)行doFirst()...");
    String result = "abcde";
    return result;
  }
 
  public void doSecond() {
    System.out.println("執(zhí)行doSecond()...");
  }
 
}

代理類MyCglibFactory:

?
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
39
package com.ietree.basicskill.designpattern.dynamicproxy.cglib;
 
import java.lang.reflect.Method;
 
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
 
public class MyCglibFactory implements MethodInterceptor {
 
  private SomeService target;
  
  public MyCglibFactory() {
    super();
    target = new SomeService();
  }
 
  public SomeService myCglibCreator() {
    // 創(chuàng)建增強(qiáng)器對象
    Enhancer enhancer = new Enhancer();
    // 指定目標(biāo)類,即父類
    enhancer.setSuperclass(SomeService.class);
    // 設(shè)置回調(diào)接口對象
    enhancer.setCallback(this);
 
    return (SomeService) enhancer.create();
  }
 
  @Override
  public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    // 調(diào)用目標(biāo)方法
    Object result = method.invoke(target, args);
    if (result != null) {
      result = ((String) result).toUpperCase();
    }
    return result;
  }
 
}

測試:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.ietree.basicskill.designpattern.dynamicproxy.cglib;
 
public class Main {
  public static void main(String[] args) {
 
    SomeService service = new MyCglibFactory().myCglibCreator();
    
    String result = service.doFirst();
    System.out.println("result = " + result);
 
    service.doSecond();
  }
}

運(yùn)行結(jié)果:

?
1
2
3
執(zhí)行doFirst()...
result = ABCDE
執(zhí)行doSecond()...

以上這篇老生常談設(shè)計(jì)模式之動(dòng)態(tài)代理就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持服務(wù)器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 狼网| 蜜桃网站免费 | 黄色毛片视频在线观看 | 精品国产一区二区三区久久久蜜月 | 中国老女人一级毛片视频 | 国产免费乱淫av | 国产精品久久久久久一区二区三区 | 欧美成人精品h版在线观看 久久久久久三区 | 毛片一区二区三区四区 | 免费观看一区二区三区视频 | 久久99亚洲精品 | 国产一级毛片高清视频完整版 | 鲁人人人鲁人人鲁精品 | av成人在线观看 | 视频在线色 | 欧美18一12sex性处hd | 国产日韩在线观看一区 | av电影在线观看免费 | 91看片成人| 日韩av电影在线免费观看 | 日韩av电影在线免费观看 | 天天碰夜夜操 | 黄色免费入口 | 精品国产一区二区三区免费 | 特大黑人videos与另类娇小 | 在线播放黄色网址 | 欧美日韩视频第一页 | 狠狠干伊人网 | 蜜桃视频最新网址 | hd极品free性xxx护士人 | 久久久久久久久久久久久久av | 性欧美一区 | 99精美视频 | 伊人久操视频 | 国产精品久久久久久影院8一贰佰 | 欧美精品久久久久久久久久 | 98国内自拍在线视频 | 久久国产精品99久久人人澡 | 99精品视频在线观看免费 | 欧美日韩中文字幕在线视频 | 一本色道久久综合狠狠躁篇适合什么人看 |