MyProxy.java:模拟Proxy
package com.proxy;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
/**
- 模拟实现jdk动态代理 (基于接口实现)
- @author Administrator
- */
- public class MyProxy {
- static String rt = "\r\t";
- static String packageDir="com.proxy";
/**
- 此方法为产生代理对象的方法
- @param loader
- 类加载器
- @param interfaces
- 代理接口类(原jdk里面是数组 因为一个类可以实现多个接口)
- @param h
- 代理对象
- @return
- */
- public static Object newProxyInstance(ClassLoader loader, Class interfaces,
- MyInvocationHandler h) {
- String javaDir = "src/"+packageDir.replace(".", "/");
- String javaName = "$Proxy0";
- String fileName = javaDir + "/" + javaName + ".java";
- // 1产生动态代理类源文件 get$proxy0.java
- String javaFileStr = get$Proxy0(interfaces);
- // 2生成源文件
- createJavaFile(javaFileStr, fileName);
- // 3编译源文件
- compilerJava(fileName);
// 4加载类 生成Class对象
Class cls=findClass(javaDir,javaName);
// 5构建代理对象
Object obj=newInstance(cls,h);
//6 删除文件
deleteFile(fileName);
return obj;
}
private static void deleteFile(String fileName) {
// TODO Auto-generated method stub
File file=new File(fileName);
file.delete();
}
private static Object newInstance(Class cls, MyInvocationHandler h) {
// TODO Auto-generated method stub
Constructor cons;
Object obj=null;
try {
cons = cls.getConstructor(MyInvocationHandler.class);
obj=cons.newInstance(h);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return obj;
}
private static Class findClass(String javaDir, String javaName) {
// TODO Auto-generated method stub
MyClassLoader myloader = new MyClassLoader(javaDir);
Class cls = null;
try {
cls = myloader.findClass(javaName);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return cls;
}
// 通过代码编译java
private static void compilerJava(String fileName) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();// 获取编译器
StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null,
null, null);
Iterable units = fileMgr.getJavaFileObjects(fileName);
CompilationTask task = compiler.getTask(null, fileMgr, null, null,
null, units);
task.call();
try {
fileMgr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 生成java文件
private static void createJavaFile(String javaFileStr, String fileName) {
File file = new File(fileName);// File类
FileWriter fw = null;
try {
fw = new FileWriter(file);
fw.write(javaFileStr);
fw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
}
}
}
}
/**
- 拼接代理类字符串
- @return
- */
- private static String get$Proxy0(Class interfaces) {
- StringBuffer javaFile = new StringBuffer("package com.proxy;" + rt);// 定义包
- javaFile.append("import java.lang.reflect.Method;" + rt);// 导入包
- javaFile.append("public class $Proxy0 implements "
- interfaces.getName() + "{" + rt);// 定义类实现接口
- javaFile.append("MyInvocationHandler h;" + rt);// 定义代理对象
- javaFile.append("public $Proxy0(MyInvocationHandler h){" + rt);
- javaFile.append("this.h=h;" + rt);
- javaFile.append("}" + rt);
- javaFile.append(getMethodStr(interfaces.getMethods(), interfaces) + rt);// 拼接方法
- javaFile.append("}" + rt);
- return javaFile.toString();
- }
/**
- 方法的拼接
- @return
- */
- private static String getMethodStr(Method[] methods, Class infs) {
- // TODO Auto-generated method stub
- StringBuffer methodStr = new StringBuffer();// 方法字符串
- for (Method method : methods) {// 遍历方法对象
- methodStr.append("public void " + method.getName() + "() throws Throwable {" + rt);
- methodStr.append("Method md=" + infs.getName()
- ".class.getMethod(\"" + method.getName()
- "\",new Class[]{});" + rt);
- methodStr.append("this.h.invoke(this,md,null);" + rt);
- methodStr.append("}" + rt);
- }
- return methodStr.toString();
- }
- }
- MyInvocationHandler.java 模拟InvocationHandler
- package com.proxy;
import java.lang.reflect.Method;
/**
- 定义代理拦截器
- @author Administrator
- */
- public interface MyInvocationHandler {
- /**
- 代理接口实现方法
- @param proxy 代理对象
- @param method 代理方法
- @param args 参数
- @return 返回源目标方法结果
- @throws Throwable 异常声明
- */
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
- }
- MyClassLoader.java 实现自定义类加载器
- package com.proxy;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
- 自定义类加载器
- @author Administrator
- */
- public class MyClassLoader extends ClassLoader {
- private File dir;
- public MyClassLoader(String filePath){
- dir=new File(filePath);
- }
- @Override
- /**
- 找类
- */
- protected Class<?> findClass(String name) throws ClassNotFoundException {
- // TODO Auto-generated method stub
- if(dir!=null){
- File classFile=new File(dir,name+".class");
- if(classFile.exists()){
- FileInputStream fis=null;
- try {
- fis=new FileInputStream(classFile);
- //创建字节数组流对象
- ByteArrayOutputStream bais=new ByteArrayOutputStream();
- //创建字节数组
- byte[] buffer=new byte[1024];
- int len=0;
- while((len=fis.read(buffer))>0){//循环读取
- bais.write(buffer, 0, len);
- }
- //bais.size() 字节流大小
- Class cls=defineClass(MyProxy.packageDir+"."+name, bais.toByteArray(), 0, bais.size());
- return cls;
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }finally{
- if(fis!=null)try {fis.close();} catch (IOException e) {e.printStackTrace();}
- }
- }
- }
- return super.findClass(name);
- }
- }
- Person.java代理接口类
- package com.proxy;
/**
- jdk动态代理实现 基于接口实现
- 人类接口
- @author Administrator
- */
- public interface Person {
/**
- 吃的方法
- */
- public void eat() throws Throwable;
- }
- PersonInvocationHandler.java 代理目标对象类
- package com.proxy;
import java.lang.reflect.Method;
/**
- jdk动态代理对象
- @author Administrator
- */
- public class PersonInvocationHandler implements MyInvocationHandler {
- //代理目标对象
- private Object target;
- //构造方法 传入代理目标对象
- public PersonInvocationHandler(Object target){
- this.target=target;
- }
- @Override
- //proxy 生成的代理对象
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- before();
- method.invoke(target, args);
- after();
- return null;
- }
- public void before(){
- System.out.println("吃饭前洗手");
- }
- public void after(){
- System.out.println("吃饭后漱口");
- }
- }
- ZhanSan.java 目标对象类
- package com.proxy;
public class ZhanSan implements Person {
@Override
public void eat() {
System.out.println("吃饭的方法");
}
}
Test.java测试类
package com.proxy;
public class Test {
/**
- @param args
- @throws Throwable
- */
- public static void main(String[] args) throws Throwable {
- // TODO Auto-generated method stub
- Person person=new ZhanSan();
- MyInvocationHandler handler=new PersonInvocationHandler(person);
- person=(Person)MyProxy.newProxyInstance(Test.class.getClassLoader(), Person.class, handler);
- person.eat();
- }
}