一、被代理类
public interface Product {
void method() throws Throwable;
}
public class ProductImpl implements Product{
public void method() {
System.out.println("执行方法");
}
}
二、MyInvocationHandler
public interface MyInvocationHandler {
Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}
public class MyProxyHandler implements MyInvocationHandler {
private Product product;
public MyProxyHandler(Product product){
this.product = product;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object object = method.invoke(product,args);
after();
return object;
}
public void before(){
System.out.println("前调用");
}
public void after(){
System.out.println("后调用");
}
}
三、MyProxy的代码
public class MyProxy {
public static final String RT = "\r\n";
public static final String PROXY_CLASS_NAME = "$Proxy0";
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,MyInvocationHandler handler)
throws Exception{
Method[] methods = interfaces[0].getMethods();
//1、用流的方式创建一个Java文件
String proxyClass = MyProxy.class.getPackage() + ";" + RT
+ "import java.lang.reflect.Method;" + RT
+ "public class "+ PROXY_CLASS_NAME +" implements " + interfaces[0].getName() + "{" + RT
+ "MyInvocationHandler h;" + RT
+ "public "+ PROXY_CLASS_NAME + "(MyInvocationHandler h) {" +RT
+ "this.h = h ;" + RT + "}"
+ getMethodString(methods,interfaces[0]) + RT + "}";
try {
String rootPath = "F:\\IdeaProjects\\proxy\\";
//2、把类生成文件
String fileName = rootPath + PROXY_CLASS_NAME + ".java";
File file = new File(fileName);
FileWriter fw = new FileWriter(file);
fw.write(proxyClass);
fw.flush();
fw.close();
//3、编译Java文件
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null,null,null);
Iterable units = fileManager.getJavaFileObjects(fileName);
JavaCompiler.CompilationTask task = compiler.getTask(null,fileManager,null,null,null,units);
task.call();
fileManager.close();
//4、把class加载到内存
MyClassLoader loader1 = new MyClassLoader(rootPath);
Class proxy0Class = loader1.findClass(PROXY_CLASS_NAME);
Constructor con = proxy0Class.getConstructor(MyInvocationHandler.class);
Object object = con.newInstance(handler);
//5、删除生成的代理类
File classFile = new File(rootPath + PROXY_CLASS_NAME +".class");
if(classFile.exists()){
classFile.delete();
}
if(file.exists()){
file.delete();
}
return object;
}catch (IOException e){
e.printStackTrace();
}
return null;
}
private static String getMethodString(Method[] methods,Class cla){
String proxyStr = "";
for (Method method : methods){
proxyStr += "public void " + method.getName() + "() throws Throwable {" + RT
+ "Method md = " + cla.getName() + ".class.getMethod( \"" + method.getName()
+ "\",new Class[]{});" + RT
+ "this.h.invoke(this,md,null);" + RT
+ "}" + RT;
}
return proxyStr;
}
}
四、类加载器
public class MyClassLoader extends ClassLoader{
private File file;
MyClassLoader(String path){
file = new File(path);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
if(file != null){
File clazzFile = new File(file,name + ".class");
if(clazzFile.exists()){
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(clazzFile);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1){
baos.write(buffer,0,len);
}
return defineClass(MyClassLoader.class.getPackage().getName()+ "." + name,baos.toByteArray(),0,baos.size());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(inputStream != null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
return super.findClass(name);
}
}
五、调用类
public class MyHandle {
public static void main(String[] args) throws Throwable{
Product product = (Product) MyProxy.newProxyInstance(Product.class.getClassLoader(),
new Class[]{Product.class}, new MyProxyHandler(new ProductImpl()));
product.method();
}
}