接口Moveable:
public interface Moveable {
public void move();
public void stop();
}
接口的实现类Tank:
public class Tank implements Moveable{
public void move() {
System.out.println("tank is moving...");
try {
Thread.sleep(new Random().nextInt(10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void stop() {
System.out.println("tank stoped...");
}
}
模拟的InvocationHandler:
public interface InvocationHandler {
public void invoke(Object object,Method method);
}
InvocationHandler的实现,也即应用类LogHandler:
public class LogHandler implements InvocationHandler{
private Object target;//被代理对象
public LogHandler(Object object) {
super();
this.target = object;
}
@Override
public void invoke(Object object,Method method) {
//先调用自己的逻辑,然后调用被代理对象的方法,最后再调用自己的逻辑
System.out.println("log begin...");
try {
method.invoke(target);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("log end...");
}
}
本文中最重要的代理类Proxy:
public class Proxy {
public static Object newProxyInstance(Class interClass,InvocationHandler handler) throws Exception{
String srcString="";//源代码字符串
String rt = "\r\n";//回车换行符
String methodString = "";//方法字符串
Method[] methods = interClass.getMethods();//找出接口interClass中的所有方法
for(Method method:methods){
//将接口中的所有方法拼接为方法字符串
methodString +=
" public void " + method.getName() +"(){" + rt +//方法头部
" try{" + rt +
" Method md = " +interClass.getName() +".class.getMethod(\"" + method.getName() +"\");" + rt +//获得接口中的一个方法
" handler.invoke(this,md);" + rt +//用处理器handler进行处理
" }catch(Exception e){" + rt +
" e.printStackTrace();" + rt +
" }" + rt +
" }" + rt ;
}
srcString = "package com.hibernate.proxy;" + rt +
"import java.lang.reflect.Method;" + rt +
"public class $Proxy1 implements "+ interClass.getName() + "{" + rt +//此处应注意:@Proxy1一定要记得实现传过来的接口
" private InvocationHandler handler;" + rt +//代理中应该保存一个处理器handler,并在构造函数中进行传递
" public $Proxy1(InvocationHandler handler){" +rt +
" this.handler = handler;" + rt +
" }" + rt +
methodString + rt +
"}";
String fileName = System.getProperty("user.dir")+"/src/com/hibernate/proxy/$Proxy1.java";//这个是文件的名称
File file = new File(fileName);//新建文件
if(!file.exists()){
file.createNewFile();
}
FileWriter writer = new FileWriter(file);
writer.write(srcString);//将源代码写到文件中
writer.flush();
writer.close();
//以下的部分是对刚才新建的源代码文件尽心编译
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager manager = compiler.getStandardFileManager(null, null, null);
Iterable units = manager.getJavaFileObjects(fileName);
CompilationTask task = compiler.getTask(null, manager, null, null, null, units);
task.call();
manager.close();
//将编译后的文件加载到内存
URL[] urls = new URL[]{new URL("file:/" + System.getProperty("user.dir"+"/src"))};
URLClassLoader classLoader = new URLClassLoader(urls);
Class class1 = classLoader.loadClass("com.hibernate.proxy.$Proxy1");
//生成新的对象
//获得代理对象$proxy1的构造方法,并将参数的类型传给它
Constructor constructor = class1.getConstructor(InvocationHandler.class);
//构造一个新的代理对象,参数为传进来的handler
Object object = (Object)constructor.newInstance(handler);
//返回新生成的代理对象
return object;
}
}
测试类:
public class ProxyTest {
public static void main(String[] args) {
Tank tank = new Tank();
InvocationHandler handler = new LogHandler(tank);
try {
Moveable moveable = (Moveable)Proxy.newProxyInstance(Moveable.class, handler);//生成一个和被代理对象具有相同接口的代理对象
moveable.move();
moveable.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
编译生成的$Proxy1类:
package com.hibernate.proxy;
import java.lang.reflect.Method;
public class $Proxy1 implements com.hibernate.proxy.Moveable{
private InvocationHandler handler;
public $Proxy1(InvocationHandler handler){
this.handler = handler;
}
public void stop(){
try{
Method md = com.hibernate.proxy.Moveable.class.getMethod("stop");
handler.invoke(this,md);
}catch(Exception e){
e.printStackTrace();
}
}
public void move(){
try{
Method md = com.hibernate.proxy.Moveable.class.getMethod("move");
handler.invoke(this,md);
}catch(Exception e){
e.printStackTrace();
}
}
}