使用javax.tools.JavaCompiler根據字符串內容動態生成新的Java類並編譯成.class

測試代碼:

package dynamicproxy;

public class DynamicProxy implements IHelloWorld
{
	IHelloWorld helloWorld;

	public DynamicProxy(IHelloWorld helloWorld)
	{
		this.helloWorld = helloWorld;
	}

	public void print()
	{
		System.out.println("Before Hello World!");
		helloWorld.print();
		System.out.println("After Hello World!");
	}
}

package dynamicproxy;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.net.URLClassLoader;

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

class HelloWorldImp implements IHelloWorld {
	public void print() {
		System.out.println("Hello World");
	}
}

public class DynamicProxyDemo implements Serializable {
	private static final long serialVersionUID = 1L;

	public static void main(String[] arg) throws Exception {
		Class<?> c = getProxyClass();
		Constructor<?> constructor = c.getConstructor(IHelloWorld.class);
		IHelloWorld helloWorldImpl = new HelloWorldImp();
		IHelloWorld helloWorld = (IHelloWorld) constructor.newInstance(helloWorldImpl);

		helloWorld.print();
	}

	private static String getSourceCode() {
		String src = "package dynamicproxy;\n\n"
				+ "public class DynamicProxy implements IHelloWorld\n" + "{\n"
				+ "\tIHelloWorld helloWorld;\n\n"
				+ "\tpublic DynamicProxy(IHelloWorld helloWorld)\n" + "\t{\n"
				+ "\t\tthis.helloWorld = helloWorld;\n" + "\t}\n\n"
				+ "\tpublic void print()\n" + "\t{\n"
				+ "\t\tSystem.out.println(\"Before Hello World!\");\n"
				+ "\t\thelloWorld.print();\n"
				+ "\t\tSystem.out.println(\"After Hello World!\");\n" + "\t}\n"
				+ "}";
		return src;
	}

	private static String createJavaFile(String sourceCode) {
		String fileName = "C:\\Users\\i042416\\git\\JavaTwoPlusTwoEquals5\\src\\dynamicproxy\\DynamicProxy.java";
		File javaFile = new File(fileName);
		Writer writer;
		try {
			writer = new FileWriter(javaFile);
			writer.write(sourceCode);
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return fileName;
	}

	private static void compile(String fileName) {
		try {
			JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
			StandardJavaFileManager sjfm = compiler.getStandardFileManager(null, null, null);
			Iterable<? extends JavaFileObject> iter = sjfm.getJavaFileObjects(fileName);
			CompilationTask ct = compiler.getTask(null, sjfm, null, null, null, iter);
			ct.call();
			sjfm.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static Class<?> loadClass() {
		URL[] urls;
		Class<?> c = null;
		try {
			urls = new URL[] { (new URL("file:\\"
					+ "C:\\Users\\i042416\\git\\JavaTwoPlusTwoEquals5\\src\\")) };
			URLClassLoader ul = new URLClassLoader(urls);
			c = ul.loadClass("dynamicproxy.DynamicProxy");
			System.out.println("Class loaded successfully: " + c.getName());
			ul.close();
		} catch (ClassNotFoundException | IOException e) {
			e.printStackTrace();
		}
		return c;
	}

	private static Class<?> getProxyClass() {
		String sourceCode = getSourceCode();
		String javaFile = createJavaFile(sourceCode);
		compile(javaFile);
		return loadClass();
	}
}

package dynamicproxy;

import java.io.File;
import java.io.FileWriter;
import java.io.Serializable;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.net.URLClassLoader;

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

interface HelloWorld
{
    void print();
}

class HelloWorldImpl implements HelloWorld
{
    public void print()
    {
        System.out.println("Hello World");
    }
}


public class DynamicProxyTest implements Serializable
{
    private static final long serialVersionUID = 1L;
 
    private static void test() throws Exception{
    	long start = System.currentTimeMillis();
        HelloWorld helloWorld = (HelloWorld) newProxyInstance();
        System.out.println("動態生成代理耗時:" + (System.currentTimeMillis() - start) + "ms");
        helloWorld.print();
        System.out.println();
    }
    
    public static void main(String[] arg) throws Exception{
    	test();
    }
    public static Object newProxyInstance() throws Exception
    {
        String src = "package dynamicproxy;\n\n" + 
                     "public class StaticProxy implements HelloWorld\n" + 
                     "{\n" + 
                     "\tHelloWorld helloWorld;\n\n" + 
                     "\tpublic StaticProxy(HelloWorld helloWorld)\n" + 
                     "\t{\n" + 
                     "\t\tthis.helloWorld = helloWorld;\n" + 
                     "\t}\n\n" + 
                     "\tpublic void print()\n" + 
                     "\t{\n" + 
                     "\t\tSystem.out.println(\"Before Hello World!\");\n" + 
                     "\t\thelloWorld.print();\n" + 
                     "\t\tSystem.out.println(\"After Hello World!\");\n" + 
                     "\t}\n" + 
                     "}";
 
        /** 生成一段Java代碼 */
        String fileDir = System.getProperty("user.dir");
        String fileName = "C:\\Users\\i042416\\git\\JavaTwoPlusTwoEquals5\\src\\dynamicproxy\\StaticProxyDemo.java";
        File javaFile = new File(fileName);
        Writer writer = new FileWriter(javaFile);
        writer.write(src);
        writer.close();
 
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager sjfm = compiler.getStandardFileManager(null, null, null);
        Iterable<? extends JavaFileObject> iter = sjfm.getJavaFileObjects(fileName);
        CompilationTask ct = compiler.getTask(null, sjfm, null, null, null, iter);
        ct.call();
        sjfm.close();
 
        URL[] urls = new URL[] {(new URL("file:\\" + "C:\\Users\\i042416\\git\\JavaTwoPlusTwoEquals5\\dynamicproxy\\src"))};
        URLClassLoader ul = new URLClassLoader(urls);
        System.out.println("class loader for url");
        Class<?> c = ul.loadClass("dynamicproxy.StaticProxy");
 
        Constructor<?> constructor = c.getConstructor(HelloWorld.class);
        HelloWorld helloWorldImpl = new HelloWorldImpl();
        HelloWorld helloWorld = (HelloWorld)constructor.newInstance(helloWorldImpl);
 
        File classFile = new File(fileDir + "\\src\\com\\xrq\\proxy\\StaticProxy.class");
        javaFile.delete();
        classFile.delete();
        ul.close();
 
        return helloWorld;
    }
}

package dynamicproxy;

public interface IHelloWorld
{
    void print();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章