Skip to content

Commit b19450f

Browse files
committed
proxy
1 parent b4f948d commit b19450f

File tree

3 files changed

+125
-0
lines changed

3 files changed

+125
-0
lines changed

src/main/java/org/javacore/proxy/README.md

+60
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,65 @@
3636
);
3737
// 调用Hello接口里面的方法
3838
helloproxy.say("aa");
39+
40+
41+
# 问题
42+
43+
### Proxy的newProxyInstance是如何生成一个代理对象的?
44+
45+
jdk1.8 Proxy 详情看[链接](http://blog.csdn.net/bluetjs/article/details/52263410)
46+
47+
大概的步骤:
48+
1. newProxyInstance提供类装载器和一组接口类
49+
Proxy.newProxyInstance(
50+
hello.getClass().getClassLoader(),
51+
hello.getClass().getInterfaces(),
52+
proxy
53+
);
54+
2. 在newProxyInstance方法中的部分代码
55+
/*
56+
* 获得与指定类装载器和一组接口相关的代理类类型对象
57+
*/
58+
Class<?> cl = getProxyClass0(loader, intfs);
59+
... ... ...
60+
//获取代理对象的构造方法(也就是$Proxy0(InvocationHandler h))
61+
final Constructor<?> cons = cl.getConstructor(constructorParams);
62+
... ... ...
63+
//生成代理类的实例并把动态代理对象(也就是上面的proxy对象)的实例传给它的构造方法
64+
return cons.newInstance(new Object[]{h});
65+
66+
3. 在测试模块将生成的class文件保存,使用jd-jui反编译工具得到内部的say实现方法
67+
private static Method m4;
68+
public final String SayHello(String paramString)
69+
{
70+
try
71+
{
72+
return (String)this.h.invoke(this, m4, new Object[] { paramString });
73+
}
74+
catch (Error|RuntimeException localError)
75+
{
76+
throw localError;
77+
}
78+
catch (Throwable localThrowable)
79+
{
80+
throw new UndeclaredThrowableException(localThrowable);
81+
}
82+
}
83+
因此,可知在调用接口的方法时,生成的代理对象会去执行invoke方法
84+
# 相关链接
85+
86+
[1]https://www.ibm.com/developerworks/cn/java/j-lo-proxy1/
87+
88+
[2]http://www.cnblogs.com/flyoung2008/archive/2013/08/11/3251148.html
89+
90+
[3]https://www.zhihu.com/question/20794107
91+
92+
[4]http://blog.csdn.net/bluetjs/article/details/52263410
93+
94+
[看这个](ttp://rejoy.iteye.com/blog/1627405)
95+
96+
97+
98+
3999

40100

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package org.javacore.proxy;
2+
3+
import sun.misc.ProxyGenerator;
4+
5+
import java.io.File;
6+
import java.io.FileNotFoundException;
7+
import java.io.FileOutputStream;
8+
import java.io.IOException;
9+
import java.lang.reflect.InvocationHandler;
10+
import java.lang.reflect.Proxy;
11+
12+
/**
13+
* 动态代理演示
14+
*/
15+
public class DynamicProxyDemonstration
16+
{
17+
public static void main(String[] args)
18+
{
19+
//代理的真实对象
20+
Hello realSubject = new HelloImpl();
21+
22+
/**
23+
* InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发
24+
* 其内部通常包含指向委托类实例的引用,用于真正执行分派转发过来的方法调用.
25+
* 即:要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法
26+
*/
27+
InvocationHandler handler = new DynamicProxy(realSubject);
28+
29+
ClassLoader loader = handler.getClass().getClassLoader();
30+
Class[] interfaces = realSubject.getClass().getInterfaces();
31+
/**
32+
* 该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例
33+
*/
34+
Hello subject = (Hello) Proxy.newProxyInstance(loader, interfaces, handler);
35+
36+
System.out.println("动态代理对象的类型:"+subject.getClass().getName());
37+
38+
String hello = subject.say("jiankunking");
39+
System.out.println(hello);
40+
// 将生成的字节码保存到本地,
41+
createProxyClassFile();
42+
}
43+
private static void createProxyClassFile(){
44+
String directory = "src/test/java/org/javacore/proxy/";
45+
String name = "ProxySubject";
46+
byte[] data = ProxyGenerator.generateProxyClass(name,new Class[]{Hello.class});
47+
FileOutputStream out =null;
48+
try {
49+
out = new FileOutputStream(directory + name+".class");
50+
System.out.println((new File("src/test/java/org/javacore/proxy")).getAbsolutePath());
51+
out.write(data);
52+
} catch (FileNotFoundException e) {
53+
e.printStackTrace();
54+
} catch (IOException e) {
55+
e.printStackTrace();
56+
}finally {
57+
if(null!=out) try {
58+
out.close();
59+
} catch (IOException e) {
60+
e.printStackTrace();
61+
}
62+
}
63+
}
64+
65+
}
Binary file not shown.

0 commit comments

Comments
 (0)