|
public interface MyExtInvocationHandler {
/**
* 纯手写模拟 jdk动态模拟 InvocationHandler接口
*
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException;
}
public class JavaClassLoader extends ClassLoader {
private File classPathFile;
public JavaClassLoader(){ // String classPath=JavaClassLoader.class.getResource("").getPath();
String classPath="D:\\code";
this.classPathFile=new File(classPath);
}
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
String className= JavaClassLoader.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(in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
return null;
}
}
public class ExtJdkInvocationHandler implements MyExtInvocationHandler {
/**
* 目标执行对象 (被代理的对象)
*/
private Object target;
public ExtJdkInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
System.out.println("纯手写JDK动态代理日志拦截开始>>>>>");
Object result = method.invoke(target, args);// 执行代理对象的方法
System.out.println("纯手写JDK动态代理日志拦截结束>>>>>");
return result;
}
// /**
// * 获取代理对象 // *
// * @param <T>
// * @return
// */
public <T> T getProxy() {
return (T) MyProxy.newProxyInstance(new JavaClassLoader(), OrderService.class, this);
}
}
public class MyProxy {
static String rt = "\r\t";
/**
* @param classInfo 被代理实现的接口信息 <br> * @param h
* @return
*/
public static Object newProxyInstance(JavaClassLoader javaClassLoader, Class classInfo, MyExtInvocationHandler h) {
try {
// 1.创建代理类java源码文件,写入到硬盘中..
Method[] methods = classInfo.getMethods();
String proxyClass = "package com.cx.ext.jdk.proxy;" + rt
+ "import java.lang.reflect.Method;" + rt
+ "import com.cx.ext.jdk.proxy.MyExtInvocationHandler;" + rt
+ "public class $Proxy0 implements " + classInfo.getName() + "{" + rt
+ "MyExtInvocationHandler h;" + rt
+ "public $Proxy0(MyExtInvocationHandler h)" + "{" + rt
+ "this.h= h;" + rt + "}"
+ getMethodString(methods, classInfo) + rt + "}";
// 2. 将代理类源码文件写入硬盘中
String filename = "d:/code/$Proxy0.java";
File f = new File(filename);
FileWriter fw = new FileWriter(f);
fw.write(proxyClass);
fw.flush();
fw.close();
// 3.使用JavaJavaCompiler 编译该$Proxy0源代码 获取class文件
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);
Iterable units = fileMgr.getJavaFileObjects(filename);
JavaCompiler.CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units);
t.call();
fileMgr.close();
//4.使用classClassLoader 将$Proxy0.class读取到内存中...
Class proxy0Class = javaClassLoader.findClass("$Proxy0");
//5.使用java反射机制给函数中赋值
Constructor m = proxy0Class.getConstructor(MyExtInvocationHandler.class);
Object o = m.newInstance(h);
return o;
} catch (Exception e) {
e.printStackTrace();
;
}
return null;
}
public static String getMethodString(Method[] methods, Class intf) {
String proxyMe = "";
for (Method method : methods) {
proxyMe += "public void " + method.getName() + "() throws Throwable {" + rt
+ "Method md= " + intf.getName() + ".class.getMethod(\"" + method.getName()
+ "\",new Class[]{});" + rt
+ "this.h.invoke(this,md,null);" + rt + "}" + rt;
}
return proxyMe;
}
}
|