动态计算
应用中可能会遇到一些自定义公式功能, 好比,用户可能自定义输入一些公式 a +b, a%2, '000'+s.substr(0,3), 若是你对这样的需求比较头痛, 请往下看吧, 咱们立刻解决.java
Groovy
groovy是一种基于JVM的敏捷开发语言, 代码可以和java很好的结合, groovy 还可使用java的类型, 是否是能力超强, 基本上你想到的均可以解决.shell
如何使用GroovyShell
在使用GroovyShell以前,先Importapp
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
先看看下面的例子:ide
GroovyShell shell = new GroovyShell();
Object result = shell.evaluate("(1+5)/2");
System.out.println(result);
这么简单的示例, 相信你们都不会出错, 咱们继续深刻函数
绑定参数
实际应用中公式{ (a+b)/2 }是用户定义的, 值是应用系统中的数值, 好比系统中的当前a=1, b=5, 如何将值绑定给公式呢, 一切看代码ui
Binding binding = new Binding();
binding.setVariable("p",3.1415926);
binding.setVariable("r",5);
GroovyShell shell = new GroovyShell(binding);
Object result = shell.evaluate("p*r*r");
System.out.println(result);
result: 78.539815
引用数学函数
Java中的数学函数不少, 见Math.xxx, 上面的计算结果由于小数位太长, 咱们需求四舍五入, 能够直接用Math.round,lua
Object result = shell.evaluate("Math.round(p*r*r)");
System.out.println(result);
result: 79
这时候的结果可能并不满意, 咱们须要保留2位小数, 这时候Math.xxx其实并无这样的函数直接拿来即用, groovy代码多是这么写的:code
import java.math.RoundingMode
def result = 78.539815
BigDecimal bg = new BigDecimal(result)
bg.setScale(2,RoundingMode.HALF_DOWN).doubleValue()
要是可以将上面的代码写成一个function, 直接调用那就简单多了...ip
自定义函数
自定义函数, 这个其实能够的, 咱们先建立一个Java Classci
public class EvalBaseScript extends Script {
@Override
public Object run() {
Method[] methods = EvalBaseScript.class.getDeclaredMethods();
StringBuilder sb=new StringBuilder();
for (Method method : methods) {
sb.append(method);
}
return sb.substring(0, sb.length()-1);
}
public static double round(String value, int scale) {
BigDecimal bd = new BigDecimal(value);
return bd.setScale(scale, 4).doubleValue();
}
public static double round(double value, int scale) {
BigDecimal bd = new BigDecimal(value);
return bd.setScale(scale, 4).doubleValue();
}
下面咱们看看groovy中如何使用上面的class
Binding binding = new Binding();
if(vars!=null) {
vars.keySet().forEach(name ->
binding.setVariable(name, vars.get(name))
);
}
CompilerConfiguration cfg = new CompilerConfiguration();
cfg.setScriptBaseClass(EvalBaseScript.class.getName());
GroovyShell shell = new GroovyShell(binding,cfg);
try {
Script script = shell.parse(buildScript());
return script.run();
} catch (Exception ex) {
logger.error("catch script execution error, script:"+buildScript(), ex);
return 0;
}
至此java中执行自定义script的能力已经足够了, 你能够定义出你想要的, 任何脚本.