整个过程中用到了手写类加载器,
手写动态生成java代码
手写编译代码
最后实现动态代理
手写Proxy示例代码:
package com.example.demo.proxy.custom;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
public class GPProxy {
public static final String ln = "\r\n";
public static Object newProxyInstance(GPClassLoader classLoader,Class<?>[] interfaces,GPInvocationHandler h){
//生成java代码
String s = generateSrc(interfaces);
//将代码写入到本地
String path = GPProxy.class.getResource("").getPath();
System.out.println(path);
File file = new File(path + "$Proxy0.java");
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(s.getBytes());
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(fileOutputStream != null){
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//编译代码
JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager manager = javaCompiler.getStandardFileManager(null, null, null);
Iterable<? extends JavaFileObject> javaFileObjects = manager.getJavaFileObjects(file);
JavaCompiler.CompilationTask task = javaCompiler.getTask(null, manager, null, null, null, javaFileObjects);
task.call();
try {
manager.close();
} catch (IOException e) {
e.printStackTrace();
}
//删除.java文件
file.delete();
//将代码读取到jvm,并生成对应的类
Object o = null;
try {
Class<?> clazz = classLoader.findClass("$Proxy0");
Constructor<?> constructor = clazz.getConstructor(GPInvocationHandler.class);
o = constructor.newInstance(h);
} catch (ClassNotFoundException | NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//返回字节码重组以后的新的代理对象
return o;
}
private static String generateSrc(Class<?>[] interfaces ) {
StringBuffer sb = new StringBuffer();
sb.append(GPProxy.class.getPackage() + ";" + ln);
sb.append("import " + interfaces[0].getPackage().toString().substring(8) + "." + interfaces[0].getSimpleName() +";" + ln);
sb.append("import java.lang.reflect.*;" + ln);
sb.append("public class $Proxy0 implements " + interfaces[0].getSimpleName() + "{" + ln);
sb.append("GPInvocationHandler h;" + ln);
//初始化GPInvocationHandler
sb.append("public $Proxy0(GPInvocationHandler h){" + ln);
sb.append("this.h = h;" + ln);
sb.append("}" + ln);
//循环调用方法
for (Method m : interfaces[0].getMethods()) {
sb.append("public final " + 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();
}
}
手写ClassLoader示例代码:
package com.example.demo.proxy.custom;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
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");
if(classFile.exists()){
FileInputStream in = null;
ByteArrayOutputStream out = null;
try{
in = new FileInputStream(classFile);
out = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int len = 0;
while ((len = in.read(buff)) != -1){
out.write(buff,0,len);
}
return defineClass(className,out.toByteArray(),0,out.size());
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(in != null)
in.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(out != null)
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
return null;
}
}
手写InvocationHandler
package com.example.demo.proxy.custom;
import java.lang.reflect.Method;
@FunctionalInterface
public interface GPInvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args);
}
动态代理类的示例代码:
package com.example.demo.proxy.custom;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class GPMeipo implements GPInvocationHandler{
Object object;
public Object getInstance(Object object){
this.object = object;
Object o = GPProxy.newProxyInstance(new GPClassLoader(), object.getClass().getInterfaces(), this);
return o;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) {
System.out.println("媒婆拿到需求");
System.out.println("媒婆匹配姑娘!");
Object invoke = null;
try {
invoke = method.invoke(object, args);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
System.out.println("媒婆安排婚事");
return invoke;
}
}
测试接口的代码:
package com.example.demo.proxy;
public interface Person {
void findLove();
void zufangzi();
}
测试被代理类的代码:
package com.example.demo.proxy;
public class ZH implements Person {
@Override
public void findLove() {
System.out.println("肤白貌美大长腿!");
}
@Override
public void zufangzi() {
}
}
测试手写代理类:
package com.example.demo.proxy.custom;
import com.example.demo.proxy.Person;
import com.example.demo.proxy.ZH;
public class CustomProxyTest {
public static void main(String[] args) {
Person zh = (Person) new GPMeipo().getInstance(new ZH());
zh.findLove();
}
}
更多内容请访问:IT源点
注意:本文归作者所有,未经作者允许,不得转载