码迷,mamicode.com
首页 > 其他好文 > 详细

动态代理模式

时间:2016-05-09 07:06:23      阅读:276      评论:0      收藏:0      [点我收藏+]

标签:

一、动态代理生成类

      

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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

import com.proxy.invocation.InvocationHandler;

public class Proxy {
	private static String rt = "\r\n";
	private static String porjectPath = System.getProperty("user.dir");
    private static String fileName = "$Proxy1";
    private static String handlerClass = "com.proxy.invocation.InvocationHandler";
	
	public static <T> T newProxyInstance(Class<T> clazz, InvocationHandler invocation) {
		StringBuffer proxyClass = Proxy.getProxyClass(clazz);
		Proxy.createClass(clazz , proxyClass.toString() , fileName+".java");
		Proxy.compilerClass(clazz,fileName);
		return Proxy.loadClass(clazz,fileName,invocation);
	}

	//生成代理类内容
	private static StringBuffer getProxyClass(Class clazz) {
		StringBuffer strB = new StringBuffer();
		strB.append(clazz.getPackage() +";"+rt+rt);
		strB.append("import java.lang.reflect.Method;"+rt + rt);
		strB.append("public class " + fileName + " extends "+clazz.getName()+" {"+rt + rt);
		strB.append("     private "+handlerClass + " h;" + rt+ rt);
		strB.append("	 public "+fileName+"("+ handlerClass +" h){"+rt);
		strB.append("         this.h = h;" + rt);
		strB.append("    }" + rt + rt);
		Method[] methods = clazz.getDeclaredMethods();
		for(Method m : methods){
			strB.append("    @Override"+rt);
			Class returnType = m.getReturnType();
			String Modifiers = Modifier.toString(m.getModifiers());
			
			//获取方法参数及类型,并包装成各种字符串
			Class[] paramTypes = m.getParameterTypes();
			StringBuffer params = new StringBuffer();
			StringBuffer paramsClass = new StringBuffer();
			StringBuffer paramsName = new StringBuffer();
			for(int i = 0,length = paramTypes.length;i < length;i++){
				Class paramClass = paramTypes[i];
				if(params.length()>0){
					paramsName.append(',');
					params.append(',');
				}
				String paramName = "arg"+i;
				paramsName.append(paramName);
				paramsClass.append(','+paramClass.getName()+".class");
				params.append(paramClass.getName()+" "+paramName);
				
			}
			
			//生成代理方法
			strB.append("	 "+Modifiers+" "+ returnType.getName()+" "+ m.getName() + "("+params+"){" + rt);
			strB.append("	     Object[] params = new Object[]{"+paramsName+"};"+rt);
			if("void"!=returnType.getName()){
				strB.append("	     "+returnType.getName()+" returnValue = null;"+rt);	
			}
			strB.append("	     try {"+rt);
			strB.append("            Method m = " + clazz.getName()+".class.getMethod(\""+m.getName()+"\""+paramsClass+");"+rt);
			//判断代理方法是否有返回值,据此调用不同方法
			if("void"!=returnType.getName()){
			    strB.append("            returnValue = ("+returnType.getName()+")h.invokeObj(this,m,params);" + rt);
			}else{
				strB.append("            h.invokeVoid(this,m,params);" + rt);
			}
			
			strB.append("        } catch (NoSuchMethodException | SecurityException e) {"+rt);
			strB.append("            e.printStackTrace();"+rt);
			strB.append("        }"+rt);
			if("void"!=returnType.getName()){
				strB.append("        return returnValue;"+rt);
			}		
			strB.append("    }"+rt + rt);
		}
		
		strB.append("}"+rt);	
		return strB;
	}

	//生成.java源文件
	private static void createClass(Class orignalClass , String classContend , String fileName) {
		String packagePath = orignalClass.getPackage().getName().replace('.', '/');//将包路径转为文件路径
		File newClass = new File(porjectPath + "/src/"+ packagePath + "/" + fileName);
		FileWriter fw = null;
		try {
			fw = new FileWriter(newClass);
			fw.write(classContend);
			fw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (null != fw) {
				try {
					fw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	// 编译class文件
	private static void compilerClass(Class clazz,String fileName) {
		String packagePath = clazz.getPackage().getName().replace('.', '\\');
		String srcFile = porjectPath + "\\src\\"+ packagePath + "\\" + fileName+".java";
		String classOutputFolder = porjectPath + "\\bin";
		JavaCompiler compiler = null;
		StandardJavaFileManager fileMgr = null;
		Iterable units = null;
		Iterable options = null;
		CompilationTask t = null;
		try {
			compiler = ToolProvider.getSystemJavaCompiler();
			fileMgr = compiler.getStandardFileManager(null, null, null);
			units = fileMgr.getJavaFileObjects(srcFile);
			options = Arrays.asList("-d", classOutputFolder);//生成位置
			t = compiler.getTask(null, fileMgr, null, options, null, units);
			t.call();
			fileMgr.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	//加载编译的class至内存中
	@SuppressWarnings("unchecked")
	private static <T> T loadClass(Class<T> clazz,String fileName, InvocationHandler invocation){
		T instance = null;
		try {
			URL[] urls = new URL[] {new URL("file:\\"+porjectPath+"\\bin\\")};
			URLClassLoader ul = new URLClassLoader(urls);
			Class c = ul.loadClass(clazz.getPackage().getName()+"."+fileName);
			Constructor constructor = c.getConstructor(Class.forName(handlerClass));
			instance = (T) constructor.newInstance(invocation);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return instance;
	}
}

动态代理模式

标签:

原文地址:http://blog.csdn.net/sw_san/article/details/51348787

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!