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

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

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機制詳細解讀,還是非常不錯的,這里分享給大家,需要的朋友可以參考下。

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

一  業(yè)務接口類

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

二 業(yè)務實現(xiàn)類

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

三 業(yè)務代理類

?
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();
 }
}

現(xiàn)在我們看一下打印結果:

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

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

現(xiàn)在我們來分析一下上面的類的工作原理。

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

?
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下面寫如下兩個靜態(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
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);
}

現(xiàn)在我們再看看輸出結果:

?
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,根據(jù)傳入的第二個參數(shù)interfaces動態(tài)生成一個類,實現(xiàn)interfaces中的接口,該例中即BusinessProcessor接口的processBusiness方法。并且繼承了Proxy類,重寫了hashcode,toString,equals等三個方法。具體實現(xiàn)可參看 ProxyGenerator.generateProxyClass(...); 該例中生成了$Proxy0類

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

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

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

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

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

2,bp.processBusiness();

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

總結

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 天若有情1992国语版完整版 | 国产一久久香蕉国产线看观看 | 香蕉人人超人人超碰超国产 | 大香焦在线观看 | 亚偷熟乱区视频在线观看 | 免费在线观看网址入口 | 免费一看一级欧美 | 香蕉精品视频 | 啊好痛嗯轻一点免费 | 欧美男人天堂 | 视频一区在线免费观看 | 99人中文字幕亚洲区 | 乌克兰肛交影视 | 爱福利视频一区二区 | 精品一区二区三区自拍图片区 | 激情五色月| 亚洲AV精品无码喷水直播间 | 好奇害死猫在线观看 | 99这里只有精品66视频 | 国产精品国产高清国产专区 | 日日操天天射 | 国内精品一区二区在线观看 | 日日精品 | 日本特级大片 | 美女gif趴跪式抽搐动态图 | 国产午夜精品一区二区三区 | 欧美va在线播放免费观看 | 国产午夜免费不卡精品理论片 | 非洲一级毛片又粗又长aaaa | 黑人巨大初黑人解禁作品 | 男人在女人下面狂躁 | 天天翘 | chinaese中国女人厕所小便 | 91久久色 | 特黄一级| 精品无码久久久久久久久 | 青青网站 | 亚洲激情网 | 精品欧美一区二区在线观看欧美熟 | 手机看片日韩1024你懂的首页 | 日韩伦理在线免费观看 |