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

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

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

服務器之家 - 編程語言 - Java教程 - Java中的代理模式詳解及實例代碼

Java中的代理模式詳解及實例代碼

2020-08-03 15:20java教程網 Java教程

這篇文章主要介紹了Java中的代理模式詳解及實例代碼的相關資料,這里附有實例代碼,需要的朋友可以參考下

java 代理模式詳解

前言:

在某些情況下,一個客戶不想或者不能直接引用一個對象,此時可以通過一個稱之為“代理”的第三者來實現間接引用。代理對象可以在客戶端和目標對象之間起到 中介的作用,并且可以通過代理對象去掉客戶不能看到 的內容和服務或者添加客戶需要的額外服務。

簡單來說代理模式就是通過一個代理對象去訪問一個實際對象,并且可以像裝飾模式一樣給對象添加一些功能。

靜態代理

所謂靜態代理即在程序運行前代理類就已經存在,也就是說我們編寫代碼的時候就已經把代理類的代碼寫好了,而動態代理則是在程序運行時自動生成代理類。

描述起來太過抽象,看一下代碼就明白是怎么回事了

main

?
1
2
3
4
5
6
7
8
9
public class Main {
 
  public static void main(String[] args) {
    Water water = new Water();
    WaterProxy waterProxy = new WaterProxy(water);
    waterProxy.drink();
  }
 
}

接口

?
1
2
3
4
//代理類與被代理類共同實現的接口
public interface Drink {
  void drink();
}

被代理類

?
1
2
3
4
5
6
7
8
9
//被代理的類
public class Water implements Drink {
 
  @Override
  public void drink() {
    System.out.println("drink water");
  }
 
}

代理類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//代理類
//與被代理類實現同一個接口
public class DrinkProxy implements Drink {
  
  private Drink drinkImpl;
  
  //通過構造函數傳入Water對象
  public DrinkProxy(Drink drinkImpl) {
    this.drinkImpl = drinkImpl;
  }
  
  @Override
  public void drink() {
    //在執行被代理對象的方法前做一些事情
    System.out.println("before drink");
    //執行被代理對象的方法
    drinkImpl.drink();
    //在執行被代理對象的方法后做一些事
    System.out.println("after drink");
  }
 
}

執行結果

?
1
2
3
before drink
drink water
after drink

動態代理

有時候我們只想改變代理類所代理的類,但是代理對象執行實際對象的方法前后所做的事情是一樣的,正所謂鐵打的代理類,流水的被代理類。而采用靜態代理就只能代理實現了同一接口的類,如果要代理任意類則必須寫很多重復的代理類。此時我們可以采用動態代理,Java已經為實現動態代理提供了一套比較方便的工具。

java.lang.reflect.Proxy類中可以動態生成代理對象的方法

?
1
2
3
4
5
6
7
8
9
10
/**
   *返回實現了指定接口的對象,調用代理對象的方法會調用
   *InvocationHandler的invoke方法
   *
   * @param  loader 獲取代理類所使用的類加載器
   * @param  interfaces 代理類所要實現的接口
   * @param  h 實現了InvocationHandler接口的對象
   * @return 代理對象
   */
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h)

InvocationHandler接口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 *每個代理類都有一個關聯的InvocationHandler
 *當代理對象執行一個方法的時候會直接執行invoke方法
 */
public interface InvocationHandler {
 
  /**
   * @param  調用該方法的代理對象
   * @param  method 代理對象所調用的方法
   * @param  args 調用的方法的參數
   * @return 調用的方法的返回值
   */
  public Object invoke(Object proxy, Method method, Object[] args)
}

描述總是比較抽象,還是看實際例子比較好理解

例子

InvocationHandler接口的實現類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class CommonInvocationHandler implements InvocationHandler {
  
  //被代理的對象
  private Object proxied;
  
  public CommonInvocationHandler(Object proxied) {
    this.proxied = proxied;
  }
  
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    //在調用被代理對象的方法前做一些事情
    System.out.println("before doing something");
    //調用被代理對象的方法
    Object result = method.invoke(proxied, args);
    //在調用被代理對象的方法后做一些事情
    System.out.println("after doing something");;
    return result;
  }
 
}

Main

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Main {
 
  public static void main(String[] args) {
    //被代理的對象
    Water water = new Water();
    //動態獲取代理對象
    Drink waterProxy =
        (Drink) Proxy.newProxyInstance(water.getClass().getClassLoader(),
            water.getClass().getInterfaces(),
            new CommonInvocationHandler(water));
    //通過代理對象調用方法
    waterProxy.drink();
  }
 
}

輸出結果

?
1
2
3
before doing something
drink water
after doing something

也可以不要具體的被代理對象,但是必須有相應的接口(沒有實現接口的類可以使用cglib實現動態代理)才可以動態獲取代理對象。像最近比較火的Retrofit就直接通過聲明好的接口使用動態代理進行網絡請求。

例子

簡單的模擬一下retrofit

POST注解

?
1
2
3
4
5
6
//Post請求注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface POST {
 String value() default "";
}

Query注解

?
1
2
3
4
5
6
//Post請求注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface POST {
 String value() default "";
}

Service接口

?
1
2
3
4
5
6
7
public interface Service {
  //用POST注解聲明請求的方式和相對路徑
  @POST("/login")
  //@Query注解聲明請求的參數名
  void login(@Query("username")String username,
      @Query("password")String password);
}

Main

?
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
public class Main {
 
  public static void main(String[] args) {
    // 動態獲取Service接口的代理
    Service service = (Service) Proxy.newProxyInstance(Service.class.getClassLoader(),
        new Class[] { Service.class }, new InvocationHandler() {
 
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 通過注解獲取請求的相對路徑
            String retativePath = ((POST) method.getAnnotations()[0]).value();
            System.out.println("relative path: " + retativePath);
            // 獲取參數的注解
            Annotation[][] parameterAnnotations = method.getParameterAnnotations();
            // 通過參數的注解獲取請求參數
            for (int i = 0; i < parameterAnnotations.length; i++) {
              if (parameterAnnotations[i].length != 0) {
                for (int j = 0; j < parameterAnnotations[i].length; j++) {
                  Query query = (Query) parameterAnnotations[i][j];
                  System.out.println(query.value() + ": " + args[i].toString());
                }
              }
            }
            return null;
          }
        });
    // 調用代理對象的方法
    service.login("hello", "world");
  }
 
}

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

延伸 · 閱讀

精彩推薦
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人影片在线观看 | 久久久91精品国产一区二区三区 | 成人欧美一区二区三区在线播放 | 91福利视频免费 | 日韩在线观看中文字幕 | 欧美一区二区三区电影 | 日韩免费在线 | 欧美日本精品 | 久久久人成影片一区二区三区 | 成人精品久久久 | 亚洲狠狠爱| 亚洲午夜视频 | 黄色免费在线观看 | 超碰九七在线 | 激情久久av一区av二区av三区 | 成人在线一区二区 | 亚洲人成网站b2k3cm | 免费的黄色网 | 亚洲喷水 | 中文字幕第一区 | 日本免费在线观看 | 青青伊人久久 | 欧美精品一区二区三区一线天视频 | 亚洲一区二区在线播放 | 欧美久久久久久 | 欧美日韩久久精品 | 香蕉久久夜色精品国产使用方法 | 国产黄视频在线观看 | 欧美日韩精品综合 | 91久久久久久 | 久久国产精品久久久久久电车 | 网站毛片 | 成人在线一区二区 | 国产高清精品在线 | 亚洲第一区在线 | 欧美激情国产日韩精品一区18 | 亚洲人成在线播放 | 亚洲福利一区二区 | 国产色| 国产精品久久精品 |