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

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

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

服務器之家 - 編程語言 - Java教程 - 詳解java JDK 動態代理類分析(java.lang.reflect.Proxy)

詳解java JDK 動態代理類分析(java.lang.reflect.Proxy)

2020-11-11 16:52Alex_zhuang Java教程

這篇文章主要介紹了詳解java JDK 動態代理類分析(java.lang.reflect.Proxy)的相關資料,需要的朋友可以參考下

詳解java JDK 動態代理類分析(java.lang.reflect.Proxy)

?
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/**
 * JDK 動態代理類分析(java.lang.reflect.Proxy使用)
 *
 * @author 張明學
 *
 */
public class ProxyStudy {
   
  @SuppressWarnings("unchecked")
  public static void main(String[] args) throws Exception {
    // 動態代理類:通用指定類加載器,和接口產生一類
    // getProxyClass()返回代理類的 java.lang.Class 對象,并向其提供類加載器和接口數組。
    Class clazzProxy = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
    System.out.println("動態產生的類名為:" + clazzProxy.getName());
    System.out.println("----------獲取動態產生的類的構造方法---------");
    Constructor[] constructors = clazzProxy.getConstructors();
    int i = 1;
    for (Constructor constructor : constructors) {
      System.out.println("第" + (i++) + "個構造方法名:" + constructor.getName());
      Class[] parameterClazz = constructor.getParameterTypes();
      System.out.println("第" + (i++) + "個構造方法參數:" + Arrays.asList(parameterClazz));
    }
    System.out.println("----------獲取動態產生的類的普通方法---------");
    Method[] methods = clazzProxy.getDeclaredMethods();
    for (int j = 0; j < methods.length; j++) {
      Method method = methods[j];
      System.out.println("第" + (j + 1) + "個普通方法名:" + method.getName());
      Class[] parameterClazz = method.getParameterTypes();
      System.out.println("第" + (j + 1) + "個普通方法參數:" + Arrays.asList(parameterClazz));
    }
    System.out.println("---------獲取動態代理對象的構造方法---------");
    // 動態代理產生的對象的構造方法需要一個實現java.lang.reflect.InvocationHandler接口的對象,故不能通過
    // clazzProxy.newInstance();產生一個對象,可以根據構造方法產生一個對象
    // InvocationHandler 是代理實例的調用處理程序 實現的接口。
    Constructor constructor = clazzProxy.getConstructor(InvocationHandler.class);
 
    // 代理產生的對象
    Collection proxyBuildCollection = (Collection) constructor
        .newInstance(new InvocationHandler() {
          // 為什么這里選擇ArrayList作為目標對象?
          // 因為這里的constructor是clazzProxy這個動態類的構造方法,clazzProxy是通過Proxy.getProxyClass()方法產生的,
          // 該方法有兩個參數,一個是指定類加載器,一個是指定代理要實現的接口,這個接口我上面指定了Collection
          // 而ArrayList實現了Collection接口,固可以為該動態類的目標對象
          ArrayList target = new ArrayList();// 動態類的目標對象
 
          public Object invoke(Object proxy, Method method,
              Object[] args) throws Throwable {
            System.out.println("執行目標" + method.getName() + "方法之前:"
                + System.currentTimeMillis());
            Object result = method.invoke(target, args);// 其實代理對象的方法調用還是目標對象的方法
            System.out.println("執行目標" + method.getName() + "方法之后:"
                + System.currentTimeMillis());
            return result;
          }
 
        });
    proxyBuildCollection.clear();
    proxyBuildCollection.add("abc");
    proxyBuildCollection.add("dbc");
    System.out.println(proxyBuildCollection.size());
    System.out.println(proxyBuildCollection.getClass().getName());
     
    /**
     * 動態代理:總結如下:
     * 1,通過Proxy.getProxyClass(classLoader,interface)方法產生一個動態類的class字節碼(clazz)
     *  該getProxyClass()方法有兩個參數:一個是指定該動態類的類加載器,一個是該動態類的要實現的接口(從這里可以看現JDK的動態代理必須要實現一個接口)
     *  
     * 2,通過第一步的獲取的clazz對象可以獲取它的構造方法constructor,那么就可以通用constructor的newInstance()方法構造出一個動態實體對象
     *  但constructor的newInstance()方法需要指定一個實現了InvocationHandler接口的類handler,在該類中需要一個目標對象A和實現invoke方法
     *  目標對象A要求能對第一步中的接口的實現,因為在invoke方法中將會去調用A中的方法并返回結果。
     *  過程如下:調用動態代理對象ProxyObject的x方法 ————> 進入構造方法傳進的handler的invoke方法 ————> invoke方法調用handler中的target對象
     *      的x方法(所以要求target必須要實現構造動態代理類時指定的接口)并返回它的返回值。(其實如果我們代理P類,那么target就可以選中P類,只是要求P必需實現一個接口)
     *  
     *  那么上述中x方法有哪些呢?除了從Object繼承過來的方法中除toString,hashCode,equals外的方法不交給handler外,其它的方法全部交給handler處理
     *  如上面proxyBuildCollection.getClass().getName()就沒有調用handler的getClass方法,而是調用自己的
     *  
     * 3,在handler的invoke方法中return method.invoke(target,args)就是將方法交給target去完成。那么在這個方法執行之前,之后,異常時我們都可以做一些操作,
     *  并且可以在執行之前檢查方法的參數args,執行之后檢查方法的結果
     */
    System.out.println("-------------------下面的寫法更簡便--------------------");
     
    // proxyBuildColl是對ArrayList進行代理
    Collection proxyBuildCollection2 = (Collection) Proxy.newProxyInstance(
        Collection.class.getClassLoader(),// 指定類加載器
        new Class[] { Collection.class },// 指定目標對象實現的接口
        // 指定handler
        new InvocationHandler() {
          ArrayList target = new ArrayList();
 
          public Object invoke(Object proxy, Method method,
              Object[] args) throws Throwable {
            System.out.println(method.getName() + "執行之前...");
            if (null != args) {
              System.out.println("方法的參數:" + Arrays.asList(args));
            } else {
              System.out.println("方法的參數:" + null);
            }
            Object result = method.invoke(target, args);
            System.out.println(method.getName() + "執行之后...");
            return result;
          }
        });
    proxyBuildCollection2.add("abc");
    proxyBuildCollection2.size();
    proxyBuildCollection2.clear();
    proxyBuildCollection2.getClass().getName();
     
    System.out.println("-------------------對JDK動態代理的重構--------------------");
    Set proxySet = (Set) buildProxy(new HashSet(), new MyAdvice());
    proxySet.add("abc");
    proxySet.size();
  }
  /**
   * 構造一個目標對象的代理對象
   *
   * @param target
   *      目標對象(需要實現某個接口)
   * @return
   */
  public static Object buildProxy(final Object target,final AdviceInter advice) {
    Object proxyObject = Proxy.newProxyInstance(
        target.getClass().getClassLoader(),// 指定類加載器
        target.getClass().getInterfaces(), // 指定目標對象實現的接口
        // handler
        new InvocationHandler() {
           
          public Object invoke(Object proxy, Method method,
              Object[] args) throws Throwable {
            advice.beforeMethod(target, method, args);
            Object result = method.invoke(target, args);
            advice.afterMethod(target, method, args);
            return result;
          }
        });
    return proxyObject;
  }
   
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
 * 代理中執行目標方法之前之后的操作的一個實例
 *
 * @author 張明學
 *
 */
public class MyAdvice implements AdviceInter {
 
  public void afterMethod(Object target, Method method, Object[] args) {
    System.out.println("目標對象為:" + target.getClass().getName());
    System.out.println(method.getName() + "執行完畢!");
  }
 
  public void beforeMethod(Object target, Method method, Object[] args) {
    System.out.println(method.getName() + "開始執行");
    if (null != args) {
      System.out.println("參數為:" + Arrays.asList(args));
    } else {
      System.out.println("參數為:" + null);
    }
  }
}
?
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
/**
 * 代理中執行目標方法之前之后的操作
 *
 * @author 張明學
 *
 */
public interface AdviceInter {
  /**
   * 目標方法執行之前
   *
   */
  public void beforeMethod(Object target, Method method, Object[] args);
 
  /**
   * 目標方法執行之后
   *
   * @param target
   *      目標對象
   * @param method
   *      方法
   * @param args
   *      參數
   */
  public void afterMethod(Object target, Method method, Object[] args);
}
 

 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久久久久久国产 | 午夜精品福利在线观看 | 婷婷色视频 | av免费黄色| 91视频免费看片 | 国产免费一区二区三区最新6 | 欧美午夜精品一区二区三区电影 | 久久av网| av中文字幕第一页 | 亚洲精品久久久久久一区二区 | 国产一区二区三区视频 | 国产精品中文字幕在线观看 | 欧美日韩综合精品 | 国产精品成人国产乱一区 | 香蕉成人啪国产精品视频综合网 | 国产成人jvid在线播放 | 99精品视频在线观看 | 国产精品成人在线视频 | 国产综合在线视频 | 国产午夜精品视频 | 亚洲精品一区二区三区四区高清 | 国产黄色电影 | 伊人91视频 | 亚洲免费观看视频 | 欧美精品一级二级 | 日韩精品一区二区三区在线 | 偷拍自拍网 | 91精品蜜臀在线一区尤物 | 亚洲国产区 | 欧美影 | 精品在线一区二区 | 欧美一区永久视频免费观看 | 久久99精品久久久久久久 | 国产在线中文字幕 | 欧美日韩精品一区二区三区 | 精品国产黄a∨片高清在线 成人欧美 | 韩日一区二区 | 欧美影院| 亚洲精品视频在线播放 | 91精品国产乱码久久久久久 | 九九综合九九 |