Janino官网
Janino是一个轻量级的Java编译器。作为Library,它可以直接在Java程序中调用,动态编译java代码并加载。
编译时可以直接引用JVM中已经加载的类.
支持绝大部分java语法,官方网站上有详细各个版本支持的语法.依据官方的说法简单表达式编译甚至比jdk更快。
官网上的例子及介绍十分详细,有兴趣的同学可以直接查看官网。
增加pom依赖
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>3.0.7</version>
</dependency>
基础用法
简单表达式执行示例
import org.codehaus.janino.*;
public class JaninoDemo {
public static void main(String[] args) throws InvocationTargetException, CompileException {
ExpressionEvaluator ee = new ExpressionEvaluator();
ee.setParameters(new String[]{"param"}, new Class[]{Param.class});
ee.setExpressionType(String.class);
ee.cook("param.getA() + param.getB()");
Param param = new Param();
param.setA("a");
param.setB("B");
String resultStr = (String) ee.evaluate(new Param[]{param});
System.out.println(resultStr);
}
}
//参数实体
public class Param{
private String a;
private String b;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
}
输出结果
Connected to the target VM, address: '127.0.0.1:3797', transport: 'socket'
aB
关键代码说明
- ee.setParameters:设置入参类型
- ee.setExpressionType:设置返回值类型
- ee.cook:设置需处理的表达式,支持多种格式String/File/InputStream……
- ee.evaluate:执行表达式并获取结果
参数所对应的JavaBean需具备get/set方法,不支持lombok相关注解。
代码段执行示例:
public class JaninoDemo {
public static void main(String[] args) throws InvocationTargetException, CompileException {
scriptEvaluator();
}
public static void expressionEvaluator() {
try {
ExpressionEvaluator ee = new ExpressionEvaluator();
ee.setParameters(new String[]{"a", "b"}, new Class[]{int.class, int.class});
ee.setExpressionType(int.class);
ee.cook("a + b");
int result = (Integer) ee.evaluate(new Integer[]{8, 9});
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void scriptEvaluator() throws CompileException, InvocationTargetException {
ScriptEvaluator se = new ScriptEvaluator();
se.cook("import static com.meijm.toolbox.janino.JaninoDemo.*;" +
"expressionEvaluator();");
se.setDebuggingInformation(true, true, true);
se.evaluate(null);
}
}
注意事项
- cook中的代码块支持常见java语法。
- se.setDebuggingInformation:设置调试开关,打开后脚本对应的方法支持调试
- 脚本中调用的静态方法expressionEvaluator() 不能抛出异常,需自己处理异常信息。
参考资料
https://janino-compiler.github.io/janino/
https://github.com/janino-compiler/janino/tree/master/janino/src/test/java/org/codehaus/janino/tests