自己完成一个jdk动态代理
1、自定义类加载器
package proxy.custom;
import java.io.*;
public class GPClassLoader extends ClassLoader {
private File classPathFile;
public GPClassLoader() {
String classPath = GPClassLoader.class.getResource("").getPath();
this.classPathFile = new File(classPath);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
String className = GPClassLoader.class.getPackage().getName() + "." + name;
if (classPathFile != null) {
File classFile = new File(classPathFile, name.replaceAll("\\.", "/")+".class");
System.out.println(classFile);
if (classFile.exists()) {
FileInputStream in = null;
ByteArrayOutputStream out = null;
try {
in = new FileInputStream(classFile);
out = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
return defineClass(className, out.toByteArray(), 0, out.size());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
return null;
}
}
2、自定义InvocationHandler
package proxy.custom;
import java.lang.reflect.Method;
public interface GPInvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}
3、自定义代理对象生成类GPProxy
package proxy.custom;
import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class GPProxy {
public static String ln="\r\n";
public static Object newProxyInstance(GPClassLoader classLoader,Class<?>[] interfaces,GPInvocationHandler h){
//动态生成源代码,java文件
String str=generateSrc(interfaces);
//java文件输出到磁盘
String filePath=GPProxy.class.getResource("").getPath();
System.out.println("filePath:"+filePath);
File f=new File(filePath+"$Proxy0.java");
FileWriter fw= null;
try {
fw = new FileWriter(f);
fw.write(str);
fw.flush();
fw.close();
//编译成.class文件
JavaCompiler compiler=ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager manage=compiler.getStandardFileManager(null,null,null);
Iterable iterable=manage.getJavaFileObjects(f);
JavaCompiler.CompilationTask task = compiler.getTask(null,manage,null,null,null,iterable);
task.call();
manage.close();
f.delete();
//编译生成的.class文件加载到JVM中
Class proxyClass=classLoader.findClass("$Proxy0");
Constructor constructor=proxyClass.getConstructor(GPInvocationHandler.class);
//返回字节码重组以后的新的代理对象
return constructor.newInstance(h);
} catch (IOException e) {
e.printStackTrace();
}catch (ClassNotFoundException e){
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
return null;
};
private static String generateSrc(Class<?>[] interfaces){
StringBuffer sb=new StringBuffer();
sb.append("package proxy.custom;"+ln);
sb.append("import proxy.Person;"+ln);
sb.append("import java.lang.reflect.Method;");
sb.append("public class $Proxy0 implements "+interfaces[0].getName()+"{"+ln);
sb.append("GPInvocationHandler h;");
sb.append("public $Proxy0(GPInvocationHandler h){"+ln);
sb.append("this.h=h;");
sb.append("}");
for (Method m:interfaces[0].getMethods()
) {
sb.append("public "+m.getReturnType().getName()+" "+m.getName()+"(){"+ln);
sb.append("try{"+ln);
sb.append("Method m = "+interfaces[0].getName()+".class.getMethod(\""+m.getName()+"\",new Class[]{});"+ln);
sb.append("this.h.invoke(this,m,null);"+ln);
sb.append("}catch (Throwable e){"+ln);
sb.append("e.printStackTrace();"+ln);
sb.append("}"+ln);
sb.append("}"+ln);
}
sb.append("}"+ln);
return sb.toString();
}
}
4、代理生成类CustomProxy
package proxy.custom;
import proxy.Person;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class CustomProxy implements GPInvocationHandler
{
//被代理的对象
private Person target;
public Object getProxy(Person target){
this.target=target;
Class<?> clazz=target.getClass();
//生成代理对象
return GPProxy.newProxyInstance(new GPClassLoader(),clazz.getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("这里是珍爱网,已拿到你的要求,帮你寻找真爱");
method.invoke(this.target,args);
System.out.println("有情人终成眷属");
return null;
}
}
5、测试:
package proxy.custom;
import proxy.Person;
import proxy.jdk.JDKProxy;
import proxy.jdk.XiaoMing;
public class CustomProxyTest {
public static void main(String[] args) {
Person xiaoming =new XiaoMing();
Person person=(Person) new CustomProxy().getProxy(xiaoming);
System.out.println(person.getClass());
person.findLove();
}
}