在Java 8和更高版本中执行字符串化的源代码


在Java中执行字符串化的源代码是很难只用JDK核心库来实现,但是,如果我们要使用CodeExecutor 的Burningwave核心,任务将变得简单,我们可以在三种不同的方式,我们可以选择一个完成它:

  • 通过BodySourceGenerator
  • 通过位于Burningwave配置文件中的属性
  • 通过位于自定义属性文件中的属性

使用BodySourceGenerator执行代码 对于第一种方法,我们必须使用静态方法forBodySourceGenerator 创建一个ExecuteConfig ,该方法必须传递包含源代码及其内部使用的参数的BodySourceGenerator :之后,必须将创建的配置传递给CodeExecutor的execute方法,如下所示:如下图所示:

package org.burningwave.core.examples.codeexecutor;
import java.util.ArrayList;
import java.util.List;
import org.burningwave.core.assembler.ComponentContainer;
import org.burningwave.core.assembler.ComponentSupplier;
import org.burningwave.core.classes.ExecuteConfig;
import org.burningwave.core.classes.BodySourceGenerator;
public class SourceCodeExecutor {


    public static Integer execute() {
        ComponentSupplier componentSupplier = ComponentContainer.getInstance();
        return componentSupplier.getCodeExecutor().execute(
            ExecuteConfig.forBodySourceGenerator(
                BodySourceGenerator.createSimple().useType(ArrayList.class, List.class)
                .addCodeRow("System.out.println(\"number to add: \" + parameter[0]);")
                .addCodeRow("List<Integer> numbers = new ArrayList<>();")
                .addCodeRow("numbers.add((Integer)parameter[0]);")
                .addCodeRow("System.out.println(\"number list size: \" + numbers.size());")
                .addCodeRow("System.out.println(\"number in the list: \" + numbers.get(0));")
                .addCodeRow("Integer inputNumber = (Integer)parameter[0];")
                .addCodeRow("return (T)new Integer(inputNumber + (Integer)parameter[1]);")
            ).withParameter(Integer.valueOf(5), Integer.valueOf(3))
        );

    }


    public static void main(String[] args) {
        System.out.println("Total is: " + execute());
    }
}

执行位于Burningwave配置文件中的属性的代码 要从Burningwave配置文件(burningwave.properties或我们用来创建ComponentContainer的另一个文件:请参阅体系结构概述和配置)中执行代码,我们必须向其中添加一个包含代码的属性,如果需要导入类,您必须将它们添加到名为该属性的另一个属性中,该属性包含代码和后缀“ imports”。例如:

code-block-1=\
    Date now= new Date();\
    return (T)now;
code-block-1.imports=java.util.Date;

也可以在另一个属性中包含一个属性的代码:

code-block-1=\
    ${code-block-2}\
    return (T)Date.from(zonedDateTime.toInstant());
code-block-1.imports=\
    ${code-block-2.imports}\
    java.util.Date;
code-block-2=\
    LocalDateTime localDateTime = (LocalDateTime)parameter[0];\
    ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
code-block-2.imports=\
    static org.burningwave.core.assembler.StaticComponentContainer.Strings;\
    java.time.LocalDateTime;\
    java.time.ZonedDateTime;\
    java.time.ZoneId;

之后,为了执行属性的代码,我们必须调用CodeExecutor的executeProperty方法,并将要执行的属性名称和属性代码中使用的参数传递给该方法:

package org.burningwave.core.examples.codeexecutor;
import java.time.LocalDateTime;
import org.burningwave.core.assembler.ComponentContainer;
import org.burningwave.core.assembler.ComponentSupplier;
public class SourceCodeExecutor {


    public static void execute() {
        ComponentSupplier componentSupplier = ComponentContainer.getInstance();
        System.out.println("Time is: " +
        componentSupplier.getCodeExecutor().execute("code-block-1", LocalDateTime.now())    
        );
    }

    public static void main(String[] args) {
        execute();
    }
}

执行位于自定义属性文件中的属性的代码 要从自定义属性文件执行代码,我们必须向其中添加一个包含代码的属性,并且,如果有必要导入类,则必须将它们添加到另一个名为该属性的属性中,该属性包含代码和后缀“ imports ” 。例如:

code-block-1=\
    Date now= new Date();\
    return (T)now;
code-block-1.imports=java.util.Date;

也可以在另一个属性中包含一个属性的代码:

code-block-1=\
    ${code-block-2}\
    return (T)Date.from(zonedDateTime.toInstant());
code-block-1.imports=\
    ${code-block-2.imports}\
    java.util.Date;
code-block-2=\
    LocalDateTime localDateTime = (LocalDateTime)parameter[0];\
    ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
code-block-2.imports=\
    static org.burningwave.core.assembler.StaticComponentContainer.Strings;\
    java.time.LocalDateTime;\
    java.time.ZonedDateTime;\
    java.time.ZoneId;

之后,为了执行属性的代码,我们必须创建一个ExecuteConfig 对象并对其进行设置:

  • 我们的自定义属性文件的路径(相对或绝对)
  • 要执行的属性名称
  • 属性代码中使用的参数

然后,我们必须使用创建的ExecuteConfig对象调用CodeExecutor的execute方法:

package org.burningwave.core.examples.codeexecutor;
import java.time.LocalDateTime;
import org.burningwave.core.assembler.ComponentContainer;
import org.burningwave.core.assembler.ComponentSupplier;
import org.burningwave.core.classes.ExecuteConfig;
public class SourceCodeExecutor {

    public static void execute() {
        ComponentSupplier componentSupplier = ComponentContainer.getInstance();
        System.out.println("Time is: " +
            componentSupplier.getCodeExecutor().execute(
                ExecuteConfig.forPropertiesFile("custom-folder/code.properties")
                //Uncomment the line below if the path supplied is an absolute path
                //.setFilePathAsAbsolute(true)
                .setPropertyName("code-block-1")
                .withParameter(LocalDateTime.now())
            )    
        );
    }

    public static void main(String[] args) {
        execute();
    }
}


原文链接:http://codingdict.com