一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

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

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

服務器之家 - 編程語言 - Java教程 - Java Proxy機制詳細解讀

Java Proxy機制詳細解讀

2021-01-17 14:46Santinel Java教程

這篇文章主要介紹了Java Proxy機制詳細解讀,還是非常不錯的,這里分享給大家,需要的朋友可以參考下。

 動態代理其實就是java.lang.reflect.Proxy類動態的根據您指定的所有接口生成一個class byte,該class會繼承Proxy類,并實現所有你指定的接口(您在參數中傳入的接口數組);然后再利用您指定的classloader將 class byte加載進系統,最后生成這樣一個類的對象,并初始化該對象的一些值,如invocationHandler,以即所有的接口對應的Method成員。 初始化之后將對象返回給調用的客戶端。這樣客戶端拿到的就是一個實現你所有的接口的Proxy對象。請看實例分析:

一  業務接口類

?
1
2
3
public interface BusinessProcessor {
 public void processBusiness();
}

二 業務實現類

?
1
2
3
4
5
public class BusinessProcessorImpl implements BusinessProcessor {
 public void processBusiness() {
 System.out.println("processing business.....");
 }
}

三 業務代理類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class BusinessProcessorHandler implements InvocationHandler {
 private Object target = null;
 BusinessProcessorHandler(Object target){
 this.target = target;
 }
 public Object invoke(Object proxy, Method method, Object[] args)
  throws Throwable {
 System.out.println("You can do something here before process your business");
 Object result = method.invoke(target, args);
 System.out.println("You can do something here after process your business");
 return result;
 }
}

四 客戶端應用類

?
1
2
3
4
5
6
7
8
9
10
11
12
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
public class Test {
 public static void main(String[] args) {
 BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();
 BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl);
 BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(bpimpl.getClass().getClassLoader(), bpimpl.getClass().getInterfaces(), handler);
 bp.processBusiness();
 }
}

現在我們看一下打印結果:

?
1
2
3
You can do something here before process your business
processing business.....
You can do something here after process your business

通過結果我們就能夠很簡單的看出Proxy的作用了,它能夠在你的核心業務方法前后做一些你所想做的輔助工作,如log日志,安全機制等等。

現在我們來分析一下上面的類的工作原理。

類一二沒什么好說的。先看看類三吧。 實現了InvocationHandler接口的invoke方法。其實這個類就是最終Proxy調用的固定接口方法。Proxy不管客戶端的業務方法是怎么實現的。當客戶端調用Proxy時,它只會調用InvocationHandler的invoke接口,所以我們的真正實現的方法就必須在invoke方法中去調用。關系如下:

?
1
2
3
4
BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();
 BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl);
BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);
bp.processBusiness()-->invocationHandler.invoke()-->bpimpl.processBusiness();

那么bp到底是怎么樣一個對象呢。我們改一下main方法看一下就知道了:

?
1
2
3
4
5
6
7
public static void main(String[] args) {
BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();
BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl);
BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(bpimpl.getClass().getClassLoader(), bpimpl.getClass().getInterfaces(), handler);
bp.processBusiness();
System.out.println(bp.getClass().getName());
}

輸出結果:

?
1
2
3
4
You can do something here before process your business
processing business.....
You can do something here after process your business
$Proxy0

bp原來是個$Proxy0這個類的對象。那么這個類到底是長什么樣子呢?好的。我們再寫二個方法去把這個類打印出來看個究竟,是什么三頭六臂呢?我們在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
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
public static String getModifier(int modifier){
 String result = "";
 switch(modifier){
  case Modifier.PRIVATE:
  result = "private";
  case Modifier.PUBLIC:
  result = "public";
  case Modifier.PROTECTED:
  result = "protected";
  case Modifier.ABSTRACT :
  result = "abstract";
  case Modifier.FINAL :
  result = "final";
  case Modifier.NATIVE :
  result = "native";
  case Modifier.STATIC :
  result = "static";
  case Modifier.SYNCHRONIZED :
  result = "synchronized";
  case Modifier.STRICT :
  result = "strict";
  case Modifier.TRANSIENT :
  result = "transient";
  case Modifier.VOLATILE :
  result = "volatile";
  case Modifier.INTERFACE :
  result = "interface";
 }
 return result;
 }
 public static void printClassDefinition(Class clz){
 String clzModifier = getModifier(clz.getModifiers());
 if(clzModifier!=null && !clzModifier.equals("")){
  clzModifier = clzModifier + " ";
 }
 String superClz = clz.getSuperclass().getName();
 if(superClz!=null && !superClz.equals("")){
  superClz = "extends " + superClz;
 }
 Class[] interfaces = clz.getInterfaces();
 String inters = "";
 for(int i=0; i<interfaces.length; i++){
  if(i==0){
  inters += "implements ";
  }
  inters += interfaces[i].getName();
 }
 System.out.println(clzModifier +clz.getName()+" " + superClz +" " + inters );
 System.out.println("{");
 Field[] fields = clz.getDeclaredFields();
 for(int i=0; i<fields.length; i++){
  String modifier = getModifier(fields[i].getModifiers());
  if(modifier!=null && !modifier.equals("")){
  modifier = modifier + " ";
  }
  String fieldName = fields[i].getName();
  String fieldType = fields[i].getType().getName();
  System.out.println("  "+modifier + fieldType + " "+ fieldName + ";");
 }
 System.out.println();
 Method[] methods = clz.getDeclaredMethods();
 for(int i=0; i<methods.length; i++){
  Method method = methods[i];
  String modifier = getModifier(method.getModifiers());
  if(modifier!=null && !modifier.equals("")){
  modifier = modifier + " ";
  }
  String methodName = method.getName();
  Class returnClz = method.getReturnType();
  String retrunType = returnClz.getName();
  Class[] clzs = method.getParameterTypes();
  String paraList = "(";
  for(int j=0; j<clzs.length; j++){
  paraList += clzs[j].getName();
  if(j != clzs.length -1 ){
   paraList += ", ";
  }
  }
  paraList += ")";
  clzs = method.getExceptionTypes();
  String exceptions = "";
  for(int j=0; j<clzs.length; j++){
  if(j==0){
   exceptions += "throws ";
  }
  exceptions += clzs[j].getName();
  if(j != clzs.length -1 ){
   exceptions += ", ";
  }
  }
  exceptions += ";";
  String methodPrototype = modifier +retrunType+" "+methodName+paraList+exceptions;
  System.out.println("  "+methodPrototype );
 }
 System.out.println("}");
 }

再改寫main方法

?
1
2
3
4
5
6
7
8
9
public static void main(String[] args) {
BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();
BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl);
BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(bpimpl.getClass().getClassLoader(), bpimpl.getClass().getInterfaces(), handler);
bp.processBusiness();
System.out.println(bp.getClass().getName());
Class clz = bp.getClass();
printClassDefinition(clz);
}

現在我們再看看輸出結果:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
You can do something here before process your business
processing business.....
You can do something here after process your business
$Proxy0
$Proxy0 extends java.lang.reflect.Proxy implements com.tom.proxy.dynamic.BusinessProcessor
{
  java.lang.reflect.Method m4;
  java.lang.reflect.Method m2;
  java.lang.reflect.Method m0;
  java.lang.reflect.Method m3;
  java.lang.reflect.Method m1;
  void processBusiness();
  int hashCode();
  boolean equals(java.lang.Object);
  java.lang.String toString();
}

很明顯,Proxy.newProxyInstance方法會做如下幾件事:

1,根據傳入的第二個參數interfaces動態生成一個類,實現interfaces中的接口,該例中即BusinessProcessor接口的processBusiness方法。并且繼承了Proxy類,重寫了hashcode,toString,equals等三個方法。具體實現可參看 ProxyGenerator.generateProxyClass(...); 該例中生成了$Proxy0類

2,通過傳入的第一個參數classloder將剛生成的類加載到jvm中。即將$Proxy0類load

3,利用第三個參數,調用$Proxy0的$Proxy0(InvocationHandler)構造函數 創建$Proxy0的對象,并且用interfaces參數遍歷其所有接口的方法,并生成Method對象初始化對象的幾個Method成員變量

4,將$Proxy0的實例返回給客戶端。
現在好了。我們再看客戶端怎么調就清楚了。

1,客戶端拿到的是$Proxy0的實例對象,由于$Proxy0繼承了BusinessProcessor,因此轉化為BusinessProcessor沒任何問題。

?
1
BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);

2,bp.processBusiness();

實際上調用的是$Proxy0.processBusiness();那么$Proxy0.processBusiness()的實現就是通過InvocationHandler去調用invoke方法啦!

總結

以上就是本文關于Java Proxy機制詳細解讀的全部內容,希望對大家有所幫助。有什么問題可以隨時留言,小編會及時回復大家。

原文鏈接:http://blog.csdn.net/rokii/article/details/4046098

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: a级毛片毛片免费很很综合 a级黄色视屏 | 成人免费视屏 | 色淫影院| 国产一级片免费视频 | 国产精品嫩草影院一二三区 | 日韩毛片免费在线观看 | www一区二区| 帅老头恋帅老头同性tv | 亚洲zooz人禽交xxxx | 爱爱亚洲 | 亚洲精品一二三四 | 91视频无限看 | 亚洲色图丝袜 | 亚洲精品视频观看 | 91av免费 | 小兰被扒开内裤露出p | 亚洲国产日韩欧美mv | 亚洲国产精品久久无套麻豆 | 男女做污事 | 亚洲成av人在线视 | 肉色欧美久久久久久久蜜桃 | 精品福利一区二区免费视频 | 91精品国产综合久久精品 | 果冻传媒mv在线观看入口免费 | 国产日韩欧美色视频色在线观看 | 亚洲第一色区 | 美女靠逼的视频 | 日本漫画被黄漫免费动 | 日本亚洲欧洲高清有码在线播放 | 四虎在线精品免费高清在线 | oneday日本在线观看完整版 | 午夜dj免费视频观看社区 | 欧美久久影院 | 美女被到爽流动漫 | 亚洲好色网 | 99久久国产综合精品女小说 | 亚洲狠狠婷婷综合久久久久网站 | 男女视频在线观看网站 | 日韩一区视频在线 | 国产精品网页 | 天天狠天天透 |