java自定义动态代理

java自定义动态代理,代码创建->编译->载入

注:如ToolProvider.getSystemJavaCompiler() 返回 null则需JAVA_HOME由java\jdk改为Java\jre,同时将jdk\lib下将tools.jar复制到jre\lib下,改了JAVA_HOME后记得把path还是改成原来的,因为JAVA_HOME变了

HRProxySourceCreator.java

Test.java 测试类

package herui.core;

import java.lang.reflect.Method;

import herui.entity.A;
import herui.entity.B;
import herui.entity.C;

public class Test {

	public static void main(String[] args) {
		
		HRProxy hrProxy = HRProxy.newProxyInstance(B.class.getInterfaces(), new HRInvocationHandler() {
			
			@Override
			public Object invoke(Object proxyObj, Method method, Object[] args) {
				System.out.println("调用:"+method.getName());
				System.out.println("参数:");
				for(int i=0; i< args.length;++i) {
					System.out.print(args[i]+",");
				}
				try {
					System.out.println("\n返回结果:");
					return method.invoke(proxyObj, args);
				} catch (Exception e) {
					e.printStackTrace();
				}
				return null;
			}

		});
		
		B b = new B();
		A a = hrProxy.getProxyObject(A.class, b);
		System.out.println(a.add(3, 5));
		System.out.println(a.sub(13, 1));
		a.print("自定义动态代理");
		
		C c = new C();
		A a2 = hrProxy.getProxyObject(A.class, c);
		System.out.println(a2.add(3, 5));
		System.out.println(a2.sub(13, 1));
		a2.print("自定义动态代理");
	}

}

HRProxySourceCreator.java 代理类构建

package herui.core;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;

public class HRProxySourceCreator{

	final static String BR = "\r\n";
	final static String TB = "\t";
	final static String SP = " ";
	final static String CA = ",";
	final static String SN = ";";
	
	public static File create(Class<?>[] interfaces, HRInvocationHandler h) throws IOException {
		StringBuilder sBuilder = new StringBuilder();
		addPackage(sBuilder, interfaces);
		String className = addClassHead(sBuilder, interfaces);
		addClassBody(sBuilder, interfaces, className);
		System.out.println(sBuilder.toString());
		String path = HRProxySourceCreator.class.getResource("").getPath() + className+".java";
		File file = new File(path);
		FileOutputStream fos = new FileOutputStream(file);
		fos.write(sBuilder.toString().getBytes());
		fos.flush();
		fos.close();
		return file;
	}

	private static void addClassBody(StringBuilder sBuilder, Class<?>[] interfaces, String className) {
		sBuilder.append("{").append(BR)
		.append(TB).append("HRInvocationHandler h;").append(BR)
		.append(TB).append("Object tag;").append(BR)
		.append(TB).append("public ").append(className).append(" (").append("HRInvocationHandler h, Object tag) {").append(BR)
		.append(TB).append(TB).append("this.h = h;").append(BR)
		.append(TB).append(TB).append("this.tag = tag;").append(BR).append(TB).append("}");
		
		for(int i=0; i<interfaces.length; ++i) {
			Method[] methods = interfaces[i].getMethods();
			for(int j=0; j<methods.length; ++j) {
				addMethod(sBuilder, methods[j], interfaces[i].getName(), j);
			}
		}
		sBuilder.append(BR).append("}").append(BR);
	}

	private static void addMethod(StringBuilder sBuilder, Method method, String className, int index) {
		sBuilder.append(BR).append(BR).append(TB).append("public ").append(method.getReturnType().getName())
		.append(SP).append(method.getName()).append(SP)
		.append("(");
		Class<?>[] types = method.getParameterTypes();
		for (int i = 0; i < types.length; i++) {
			sBuilder.append(types[i].getTypeName()).append(SP).append("arg"+i).append(CA).append(SP);
		}
		sBuilder.delete(sBuilder.length()-2, sBuilder.length()-1);
		sBuilder.append(")").append(SP)
		.append("{").append(BR).append(TB).append(TB).append("Method method = ").append(className)
		.append(".class.getMethods()[").append(index).append("]").append(SN).append(BR);
		sBuilder.append(TB).append(TB).append("Object[] args = {");
		for (int i = 0; i < types.length; i++) {
			sBuilder.append("arg"+i).append(CA).append(SP);
		}
		sBuilder.delete(sBuilder.length()-2, sBuilder.length()-1)
		.append("}").append(SN).append(BR).append(TB).append(TB);
		if(!"void".equals(method.getReturnType().getName())) {
			sBuilder.append("return (").append(method.getReturnType().getName()).append(")");
		}
		sBuilder.append("h.invoke(tag, method, args)").append(SN).append(BR)
		.append(TB).append("}").append(BR);
	}

	private static String addClassHead(StringBuilder sBuilder, Class<?>[] interfaces) {
		sBuilder.append("public class ");
		String className = "$";
		for(int i=0; i<interfaces.length; ++i) {
			className += interfaces[i].getSimpleName();
		}
		sBuilder.append(className);
		
		sBuilder.append(" implements ");
		for(int i=0; i<interfaces.length; ++i) {
			sBuilder.append(interfaces[i].getName()).append(CA);
		}
		sBuilder.deleteCharAt(sBuilder.length()-1);
		sBuilder.append(SP);
		return className;
	}

	private static void addPackage(StringBuilder sBuilder, Class<?>[] interfaces) {
		sBuilder.append("package herui.core;").append(BR);
		sBuilder.append("import java.lang.reflect.Method;");
		sBuilder.append(BR).append(BR);
	}

}

HRProxy.java 代理类编译载入jvm,门面

package herui.core;

import java.io.File;
import java.lang.reflect.Constructor;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

public class HRProxy {
	private HRInvocationHandler h;
	private Class proxyClass;
	private HRProxy() {
		throw new RuntimeException("no new instance by the construtor");
	}
	private HRProxy(Class<?>[] interfaces, HRInvocationHandler h) {
		if(interfaces == null || h == null) {
			throw new RuntimeException("input invalid parameter");
		}
		this.h = h;
		try {
			File file = HRProxySourceCreator.create(interfaces, h);
			
			//把生成的.java文件编译成.class文件
			JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
			StandardJavaFileManager manage = compiler.getStandardFileManager(null, null, null);
			Iterable iterable = manage.getJavaFileObjects(file);

			JavaCompiler.CompilationTask task = compiler.getTask(null, manage, null, null, null, iterable);
			task.call();
			manage.close();
			// 编译生成的.class文件加载到JVM中来
			HRClassLoader loader = new HRClassLoader();
			proxyClass = loader.loadClass(file.getName().replace(".java", ""));
			file.delete();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public <T> T getProxyObject(Class<T> clzz, Object obj) {
		Constructor constructor = null;
		try {
			constructor = proxyClass.getConstructor(new Class[] {HRInvocationHandler.class, Object.class});
			return (T) constructor.newInstance(h, obj);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static HRProxy newProxyInstance(Class<?>[] interfaces, HRInvocationHandler h) {
		return new HRProxy(interfaces, h);
	}
}

HRClassLoader.java 自定义类加载器

package herui.core;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class HRClassLoader extends ClassLoader{

    private File classPathFile;

    public HRClassLoader(){
        String classPath = HRClassLoader.class.getResource("").getPath();
        this.classPathFile = new File(classPath);
    }

    @Override
    public Class<?> findClass(String name) throws ClassNotFoundException {

        String className = HRClassLoader.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;
                    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 {
                    if(null != in){
                        try {
                            in.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }

                    if(out != null){
                        try {
                            out.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

        }

        return null;

    }
}

HRInvocationHandler.java 处理器接口

package herui.core;

import java.lang.reflect.Method;

public interface HRInvocationHandler {
	Object invoke(Object proxyObj, Method method, Object[] args);
}

A.java 接口

package herui.entity;

public interface A {
	Integer add(int a, int b);
	
	int sub(int a, int b);
	
	String print(String s);
}

B.java 实现类1

package herui.entity;

public class B implements A{

	@Override
	public Integer add(int a, int b) {
		return a+b;
	}

	@Override
	public int sub(int a, int b) {
		return a-b;
	}

	@Override
	public String print(String s) {
		if(s == null) {
			s = "";
		}
		System.out.printf(s);
		return s;
	}
}

C.java 实现类2

package herui.entity;

public class C implements A {

	@Override
	public Integer add(int a, int b) {
		return a+b+1000;
	}

	@Override
	public int sub(int a, int b) {
		return a-b-1000;
	}

	@Override
	public String print(String s) {
		if(s != null) {
			StringBuilder sBuilder = new StringBuilder(s);
			s = sBuilder.reverse().toString();
		}
		System.out.println(s);
		return s;
	}

}

示例结果:


本文主要展示一些原理,细节并未关注

猜你喜欢

转载自blog.csdn.net/u012681635/article/details/79719093