使用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