J2SE 8的编译

动态加载(修改)服务、高性动态业务逻辑实现(用脚本或模板引擎实现效率满足不了需求)

package compile;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;

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

public class CompileTest {
	public static void main(final String[] args) throws Exception {
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

		StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(null, null, null);
		
		//指定到外层根目录
		URI resource = CompileTest.class.getClassLoader().getResource("").toURI();
		Path path = Paths.get(resource);
		File templateFile = path.toFile();
		
		System.out.println(templateFile.getAbsolutePath());
		
		
        // 指定 javac 的命令行参数  
        // 注意:最好将编译后的.class文件放到当前JVM实例的类路径上,否则加载不了  
        Iterable<String> options = Arrays.asList("-d", templateFile.getAbsolutePath()); 
        
        String className =Thread.currentThread().getStackTrace()[1].getClassName();
		Class<?> currentClass = Class.forName(className);
		String currentPackage = currentClass.getPackage().getName();
        
        JavaFileObject javaFileObject = new StringObject(className, "package "+currentPackage+";" + 
        		"import java.util.ArrayList;"+
        		"import java.util.List;"+
                
                "  class CalculatorTest {" +  
                "   public int multiply(int multiplicand, int multiplier) {" +  
                "       System.out.println(multiplicand);" +  
                "       System.out.println(multiplier);" +  
                "       return multiplicand * multiplier;" +  
                "   }" 
                
	             +"  public List<String> add(String str1, String str2) {"  
	             +"      System.out.println(str1);"  
	             +"      System.out.println(str2);"  
	             +"      List<String> result = new ArrayList<String>();"  
	             +"      result.add(str1);"  
	             +"      result.add(str2);"  
	             +"      return result;"  
	             +"  }"
                
                +"}");  
        Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(javaFileObject); 
        
		CompilationTask compilationTask = compiler.getTask(null, standardFileManager, null, options, null, compilationUnits);
		
        if (compilationTask.call()) {  
            System.out.println("编译成功");  
            Class<?> clazz = Class.forName(currentPackage+".CalculatorTest");  
  
            Object instance = clazz.newInstance();  
  
            Method m = clazz.getMethod("multiply", new Class[]{int.class, int.class});  
            Object[] o = new Object[]{1, 2};  
            Object returnObj =  m.invoke(instance, o);  
            System.out.println("方法返回的结果:" + returnObj.toString());
            
            
            m = clazz.getMethod("add", new Class[]{String.class, String.class});  
            o = new Object[]{"string 1", "string 2"};  
            List returnList =  (List) m.invoke(instance, o);  
            System.out.println("方法返回的结果集个数:" + returnList); 
        } 
	}
}

class StringObject extends SimpleJavaFileObject {  
    private String contents = null;  
  
    public StringObject(String className, String contents) throws Exception {  
        super(new URI(className), Kind.SOURCE);  
        this.contents = contents;  
    }  
  
    public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {  
        return contents;  
    }  
}  

执行结果

D:\Tools\Myeclipse\MyEclipse Configuration\WorkSpace\Base\se\target\classes
编译成功
1
2
方法返回的结果:2
string 1
string 2
方法返回的结果集个数:[string 1, string 2]


猜你喜欢

转载自blog.csdn.net/xiang__liu/article/details/79372431
今日推荐