使用ClassFactory,可以在运行时生成类,但是如果我们只需要编译源代码而无需加载它们或仅生成源代码,该怎么办呢?
这是源代码生成器组件和Burningwave Core的JavaMemoryCompiler ,对我们有帮助。使用源代码生成器,我们可以生成源代码并将其存储在驱动器上,或者通过JavaMemoryCompiler对其进行编译。
现在,让我们尝试生成并存储以下类:
package source.generation.test; import java.util.Arrays; import java.util.List; public class MyClass { private List<String> words; public MyClass(String... words) { this.words = Arrays.asList(words); } public void print() { System.out.print(String.join(" ", words)); } public static void main(String[] args) { new MyClass(args).print(); } }
使用源代码生成器:
package source.generation.test; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.List; import org.burningwave.core.classes.ClassSourceGenerator; import org.burningwave.core.classes.FunctionSourceGenerator; import org.burningwave.core.classes.GenericSourceGenerator; import org.burningwave.core.classes.TypeDeclarationSourceGenerator; import org.burningwave.core.classes.UnitSourceGenerator; import org.burningwave.core.classes.VariableSourceGenerator; public class SourceGenerationTester { public static UnitSourceGenerator generate() { return UnitSourceGenerator.create(SourceGenerationTester.class.getPackage().getName()) .addClass( ClassSourceGenerator.create(TypeDeclarationSourceGenerator.create("MyClass")) .addField( VariableSourceGenerator.create( TypeDeclarationSourceGenerator.create(List.class) .addGeneric(GenericSourceGenerator.create(String.class)), "words" ) ) .addConstructor( FunctionSourceGenerator.create().addParameter( VariableSourceGenerator.create( TypeDeclarationSourceGenerator.create(String.class) .setAsVarArgs(true), "words" ) ).addBodyCodeLine("this.words = Arrays.asList(words);").useType(Arrays.class) ) .addMethod( FunctionSourceGenerator.create("print") .addModifier(Modifier.PUBLIC).setReturnType(void.class) .addBodyCodeLine( "System.out.println(\"\\n\\t\" + String.join(\" \", words) + \"\\n\");" ) ) .addMethod( FunctionSourceGenerator.create("main") .addModifier(Modifier.PUBLIC | Modifier.STATIC) .setReturnType(void.class) .addParameter(VariableSourceGenerator.create(String[].class, "args")) .addBodyCodeLine("new MyClass(args).print();") ) ); } public static void main(String[] args) { UnitSourceGenerator unitSG = SourceGenerationTester.generate(); unitSG.storeToClassPath(System.getProperty("user.home") + "/Desktop/sources"); System.out.println("\nGenerated code:\n" + unitSG); } }
现在,让我们尝试编译源代码,并使用JavaMemoryCompiler存储编译后的文件:
package source.compilation.test; import org.burningwave.core.assembler.ComponentContainer; import org.burningwave.core.classes.JavaMemoryCompiler; import org.burningwave.core.classes.JavaMemoryCompiler.Compilation; import org.burningwave.core.concurrent.QueuedTasksExecutor.ProducerTask; import org.burningwave.core.io.FileSystemItem; import source.generation.test.SourceGenerationTester; public class SourceCompilationTester { public static void main(String[] args) throws ClassNotFoundException { ComponentContainer componentContainer = ComponentContainer.getInstance(); JavaMemoryCompiler javaMemoryCompiler = componentContainer.getJavaMemoryCompiler(); ProducerTask<Compilation.Result> compilationTask = javaMemoryCompiler.compile( Compilation.Config.forUnitSourceGenerator( SourceGenerationTester.generate() ) .storeCompiledClassesTo( System.getProperty("user.home") + "/Desktop/classes" ) ); Compilation.Result compilationResult = compilationTask.join(); System.out.println("\n\tAbsolute path of compiled file: " + compilationResult.getClassPath() .findFirstInAllChildren( FileSystemItem.Criteria.forAllFileThat(FileSystemItem::isFile) ).getAbsolutePath() + "\n" ); } }
现在让我们尝试加载已编译的文件:
package source.compilation.test; import static org.burningwave.core.assembler.StaticComponentContainer.ClassLoaders; import static org.burningwave.core.assembler.StaticComponentContainer.Methods; import org.burningwave.core.assembler.ComponentContainer; import org.burningwave.core.classes.JavaMemoryCompiler; import org.burningwave.core.classes.JavaMemoryCompiler.Compilation; import org.burningwave.core.concurrent.QueuedTasksExecutor.ProducerTask; import source.generation.test.SourceGenerationTester; public class SourceCompilationTester { public static void main(String[] args) throws ClassNotFoundException { ComponentContainer componentContainer = ComponentContainer.getInstance(); JavaMemoryCompiler javaMemoryCompiler = componentContainer.getJavaMemoryCompiler(); ProducerTask<Compilation.Result> compilationTask = javaMemoryCompiler.compile( Compilation.Config.forUnitSourceGenerator( SourceGenerationTester.generate() ) .storeCompiledClassesTo( System.getProperty("user.home") + "/Desktop/classes" ) ); Compilation.Result compilattionResult = compilationTask.join(); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); ClassLoaders.addClassPaths(classLoader, compilattionResult.getDependencies()); ClassLoaders.addClassPath(classLoader, compilattionResult.getClassPath().getAbsolutePath()); Class<?> cls = classLoader.loadClass("source.generation.test.MyClass"); Methods.invokeStaticDirect(cls, "main", new Object[] {new String[] {"Hello", "world!"}}); } }
原文链接:http://codingdict.com