java自定义动态代理
程序员文章站
2024-03-22 16:06:16
...
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;
}
}
示例结果:
本文主要展示一些原理,细节并未关注