JDK动态代理实现原理Word下载.docx

上传人:b****1 文档编号:3560984 上传时间:2023-05-02 格式:DOCX 页数:21 大小:26.58KB
下载 相关 举报
JDK动态代理实现原理Word下载.docx_第1页
第1页 / 共21页
JDK动态代理实现原理Word下载.docx_第2页
第2页 / 共21页
JDK动态代理实现原理Word下载.docx_第3页
第3页 / 共21页
JDK动态代理实现原理Word下载.docx_第4页
第4页 / 共21页
JDK动态代理实现原理Word下载.docx_第5页
第5页 / 共21页
JDK动态代理实现原理Word下载.docx_第6页
第6页 / 共21页
JDK动态代理实现原理Word下载.docx_第7页
第7页 / 共21页
JDK动态代理实现原理Word下载.docx_第8页
第8页 / 共21页
JDK动态代理实现原理Word下载.docx_第9页
第9页 / 共21页
JDK动态代理实现原理Word下载.docx_第10页
第10页 / 共21页
JDK动态代理实现原理Word下载.docx_第11页
第11页 / 共21页
JDK动态代理实现原理Word下载.docx_第12页
第12页 / 共21页
JDK动态代理实现原理Word下载.docx_第13页
第13页 / 共21页
JDK动态代理实现原理Word下载.docx_第14页
第14页 / 共21页
JDK动态代理实现原理Word下载.docx_第15页
第15页 / 共21页
JDK动态代理实现原理Word下载.docx_第16页
第16页 / 共21页
JDK动态代理实现原理Word下载.docx_第17页
第17页 / 共21页
JDK动态代理实现原理Word下载.docx_第18页
第18页 / 共21页
JDK动态代理实现原理Word下载.docx_第19页
第19页 / 共21页
JDK动态代理实现原理Word下载.docx_第20页
第20页 / 共21页
亲,该文档总共21页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

JDK动态代理实现原理Word下载.docx

《JDK动态代理实现原理Word下载.docx》由会员分享,可在线阅读,更多相关《JDK动态代理实现原理Word下载.docx(21页珍藏版)》请在冰点文库上搜索。

JDK动态代理实现原理Word下载.docx

18. 

/** 

19. 

构造方法 

20. 

@param 

target 

21. 

22. 

public 

MyInvocationHandler(Object 

target) 

23. 

super();

24. 

this.target 

25. 

26. 

27. 

28. 

29. 

执行目标对象的方法 

30. 

31. 

invoke(Object 

proxy, 

Method 

method, 

Object[] 

args) 

throws 

Throwable 

32. 

33. 

在目标对象的方法执行之前简单的打印一下 

34. 

System.out.println("

------------------before------------------"

);

35. 

36. 

37. 

result 

method.invoke(target, 

args);

38. 

39. 

在目标对象的方法执行之后简单的打印一下 

40. 

-------------------after------------------"

41. 

42. 

return 

result;

43. 

44. 

45. 

46. 

获取目标对象的代理对象 

47. 

@return 

代理对象 

48. 

49. 

getProxy() 

50. 

Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), 

51. 

target.getClass().getInterfaces(), 

this);

52. 

53.} 

54. 

55.package 

56. 

57./** 

58. 

目标对象实现的接口,用JDK来生成代理对象一定要实现一个接口 

59. 

60. 

61. 

62. 

63.public 

interface 

UserService 

64. 

65. 

66. 

目标方法 

67. 

68. 

abstract 

void 

add();

69. 

70.} 

71. 

72.package 

73. 

74./** 

75. 

76. 

77. 

78. 

79. 

80.public 

UserServiceImpl 

81. 

82. 

/* 

(non-Javadoc) 

83. 

@see 

dynamic.proxy.UserService#add() 

84. 

85. 

add() 

86. 

--------------------add---------------"

87. 

88.} 

89. 

90.package 

91. 

92.import 

org.junit.Test;

93. 

94./** 

95. 

动态代理测试类 

96. 

97. 

98. 

99. 

100.public 

ProxyTest 

101. 

102. 

@Test 

103. 

testProxy() 

104. 

实例化目标对象 

105. 

userService 

new 

UserServiceImpl();

106. 

107. 

实例化InvocationHandler 

108. 

invocationHandler 

MyInvocationHandler(userService);

109. 

110. 

根据目标对象生成代理对象 

111. 

proxy 

(UserService) 

invocationHandler.getProxy();

112. 

113. 

调用代理对象的方法 

114. 

proxy.add();

115. 

116. 

117.} 

执行结果如下:

------------------before------------------ 

--------------------add--------------- 

-------------------after------------------ 

用起来是很简单吧,其实这里基本上就是AOP的一个简单实现了,在目标对象的方法执行之前和执行之后进行了增强。

Spring的AOP实现其实也是用了Proxy和InvocationHandler这两个东西的。

用起来是比较简单,但是如果能知道它背后做了些什么手脚,那就更好不过了。

首先来看一下JDK是怎样生成代理对象的。

既然生成代理对象是用的Proxy类的静态方newProxyInstance,那么我们就去它的源码里看一下它到底都做了些什么?

1./** 

loader:

类加载器 

3. 

interfaces:

目标对象实现的接口 

4. 

h:

InvocationHandler的实现类 

5. 

6.public 

static 

newProxyInstance(ClassLoader 

loader, 

7. 

Class<

?

>

[] 

interfaces, 

h) 

IllegalArgumentException 

if 

(h 

== 

null) 

throw 

NullPointerException();

13. 

Look 

up 

or 

generate 

the 

designated 

class. 

Class 

cl 

getProxyClass(loader, 

interfaces);

Invoke 

its 

constructor 

with 

invocation 

handler. 

try 

调用代理对象的构造方法(也就是$Proxy0(InvocationHandler 

h)) 

Constructor 

cons 

cl.getConstructor(constructorParams);

生成代理类的实例并把MyInvocationHandler的实例传给它的构造方法 

(Object) 

cons.newInstance(new 

});

catch 

(NoSuchMethodException 

e) 

InternalError(e.toString());

(IllegalAccessException 

(InstantiationException 

(InvocationTargetException 

我们再进去getProxyClass方法看一下 

1.public 

getProxyClass(ClassLoader 

... 

interfaces) 

如果目标类实现的接口数大于65535个则抛出异常(我XX,谁会写这么NB的代码啊?

) 

(interfaces.length 

65535) 

IllegalArgumentException("

limit 

exceeded"

声明代理对象所代表的Class对象(有点拗口) 

proxyClass 

null;

String[] 

interfaceNames 

String[interfaces.length];

Set 

interfaceSet 

HashSet();

for 

detecting 

duplicates 

遍历目标类所实现的接口 

(int 

0;

<

interfaces.length;

i++) 

拿到目标类实现的接口的名称 

String 

interfaceName 

interfaces[i].getName();

interfaceClass 

加载目标类实现的接口到内存中 

Class.forName(interfaceName, 

false, 

loader);

(ClassNotFoundException 

(interfaceClass 

!

interfaces[i]) 

IllegalArgumentException( 

interfaces[i] 

"

is 

not 

visible 

from 

loader"

中间省略了一些无关紧要的代码 

....... 

把目标类实现的接口代表的Class对象放到Set中 

interfaceSet.add(interfaceClass);

interfaceNames[i] 

interfaceName;

把目标类实现的接口名称作为缓存(Map)中的key 

key 

Arrays.asList(interfaceNames);

Map 

cache;

synchronized 

(loaderToCache) 

从缓存中获取cache 

cache 

(Map) 

loaderToCache.get(loader);

(cache 

如果获取不到,则新建地个HashMap实例 

HashMap();

把HashMap实例和当前加载器放到缓存中 

53. 

loaderToCache.put(loader, 

cache);

55. 

57. 

(cache) 

do 

根据接口的名称从缓存中获取对象 

value 

cache.get(key);

63. 

(value 

instanceof 

Reference) 

(Class) 

((Reference) 

value).get();

(proxyClass 

如果代理对象的Class实例已经存在,则直接返回 

proxyClass;

else 

pendingGenerationMarker) 

70. 

cache.wait();

72. 

(InterruptedException 

74. 

continue;

cache.put(key, 

pendingGenerationMarker);

break;

while 

(true);

80. 

中间省略了一些代码 

这里就是动态生成代理对象的最关键的地方 

byte[] 

proxyClassFile 

ProxyGenerator.generateProxyClass( 

proxyName, 

88. 

根据代理类的字节码生成代理类的实例 

90. 

defineClass0(loader, 

proxyClassFile, 

0, 

proxyClassFile.length);

92. 

(ClassFormatError 

IllegalArgumentException(e.toString());

94. 

add 

to 

set 

of 

all 

generated 

classes, 

isProxyClass 

proxyClasses.put(proxyClass, 

null);

100. 

进去ProxyGenerator类的静态方法generateProxyClass,这里是真正生成代理类class字节码的地方。

generateProxyClass(final 

name, 

Class[] 

ProxyGenerator 

gen 

ProxyGenerator(name, 

这里动态生成代理类的字节码,由于比较复杂就不进去看了 

final 

classFile 

gen.generateClassFile();

如果saveGeneratedFiles的值为true,则会把所生成的代理类的字节码保存到硬盘上 

(saveGeneratedFiles) 

java.security.AccessController.doPrivileged( 

java.security.PrivilegedAction<

Void>

() 

Void 

run() 

FileOutputStream 

file 

FileOutputStream(dotToSlash(name) 

.class"

file.write(classFile);

file.close();

(IOException 

InternalError( 

I/O 

exception 

saving 

file:

e);

返回代理类的字节码 

classFile;

}

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2