JDK1.8 nashorn 引擎使用

简介: 整理了近期在项目上做的一些技术研究,希望与大家共同探讨交流。 在清算项目的计算模块使用 jdk 1.8 自带的 js 引擎 nashorn 做运算。 使用过程对 nashorn 做了一些简单的测试。

整理了近期在项目上做的一些技术研究,希望与大家共同探讨交流。

在清算项目的计算模块使用 jdk 1.8 自带的 js 引擎 nashorn 做运算。 使用过程对 nashorn 做了一些简单的测试。

使用 nashorn 编译 js 后 执行 invokeFunction 计算 ,一个简单的逻辑判断 加上一个简单的乘法运算 循环执行100w次总耗时约为600~700ms

使用 mozilla 的 rhino js引擎, 编译 js 后 执行 func.call 计算 ,总耗时约为 1400ms 左右。

nashorn 中 eval 方法编译 js 耗时很大, 实际应用时需要进行缓存处理。

除此之外, 使用 nashorn 过程一直调用不到内部的 js 方法。

这里记录下这次的使用方式

public class LiquidationUtil {
    private static Logger logger = LoggerFactory.getLogger(LiquidationUtil.class);
     
    public static final String _expression = "_expression";
    public static final String _conditions = "_conditions";
    // 生成清算规则的计算对象
    public static Invocable  generateLiquidationFuction(String conditions,String expressionMark,String expressionParam) throws ScriptException, NoSuchMethodException {//Liquidation
        StringBuffer sb = new StringBuffer(128);
        if(StringUtils.isEmpty(conditions))
            conditions = "true";
         
        sb.append("var ").append(_conditions).append(" = function (m,o) {")
            .append("\nreturn ").append(_conditions).append("(m,o,null);\n")
        .append("};\n");
        sb.append("var ").append(_expression).append(" = function (m,o) {")
            .append("\nreturn ").append(_expression).append("(m,o,null);\n")
        .append("};\n");
         
        // 条件
        sb.append("var ").append(_conditions).append(" = function (m,o,jh) {")
            .append("\nreturn ").append(conditions).append(";\n")
        .append("};\n");
         
         
        String expressionJs = expressionMap.get(expressionMark);
        // 计算
        sb.append("var ").append(_expression).append(" = function (m,o,jh) {")
            .append("\nvar result=null;\n")
            .append("\n var ").append(expressionParam).append(";\n")
            .append("\n").append(expressionJs).append(";\n")
            .append("\nreturn result;\n")
        .append("};");
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");//nashorn javascript
        engine.eval(sb.toString());
        return (Invocable) engine;
    }
     
     
     
     
    private static final Map<String, String> expressionMap = new HashMap<String, String>();
    static {
        try {
            String path = Thread.currentThread().getContextClassLoader().getResource("liquidation_script").getFile();
            logger.info("加载清算规则js脚本 path:{}", path);
            File dir = new File(path);
            for(File script : dir.listFiles()) {
                String fileName = script.getName();
                String filePath = script.getAbsolutePath();
                logger.info("加载清算规则脚本 mark:{}\tfilePath:{}",fileName, filePath);
                expressionMap.put(fileName.substring(0, fileName.length()-3), readFileContent(filePath));
            }
        } catch (IOException e) {
            logger.error("初始化算费规则脚本出错", e);
        }
    }
    public static String readFileContent(String uri) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(uri));
        String line = "";
        StringBuffer buffer = new StringBuffer();
        while ((line = br.readLine()) != null) {
            buffer.append(line).append("\n");
        }
        String fileContent = buffer.toString();
        return fileContent;
    }
}
调用:
            jsInvocable = (Invocable)LiquidationUtil.generateLiquidationFuction(conditionsJs, expressionMark, expressionParam);// 对 invocable 缓存
            result = jsInvocable.invokeFunction(_conditions, mapping, orderInfo);

js 代码的格式为

var func1 = function(param1, param2){

...

}

var func2 = function(param1, param2){

...

}

对这段字符串执行 eval, 得到 Invocable ,

然后可以执行 Invocable.invokeFunction("func1", param1, param2) 调用 js 方法。

目录
相关文章
|
4月前
|
JSON 编解码 Java
Java升级:JDK 9新特性全面解析“
Java升级:JDK 9新特性全面解析“
142 0
|
9月前
|
移动开发 Java 开发工具
3.JAVA为什么能这么火?---了解Java语言的发展,功能,跨平台的原理以及什么是JDK,JRE
3.JAVA为什么能这么火?---了解Java语言的发展,功能,跨平台的原理以及什么是JDK,JRE
71 1
|
1月前
|
Java API Apache
JDK8到JDK24版本升级的新特性问题之在Java中,HttpURLConnection有什么局限性,如何解决
JDK8到JDK24版本升级的新特性问题之在Java中,HttpURLConnection有什么局限性,如何解决
|
4月前
|
算法 前端开发 JavaScript
【JAVA】JDK11新特性个人分析
【JAVA】JDK11新特性个人分析
86 0
|
3月前
|
安全 Java API
JDK 11 vs JDK 8:探索Java的新特性和改进
JDK 11 vs JDK 8:探索Java的新特性和改进
|
4月前
|
算法 安全 Java
【JAVA】JDK11新特性个人分析(一)
【JAVA】JDK11新特性个人分析
161 0
【JAVA】JDK11新特性个人分析(一)
|
4月前
|
JavaScript 前端开发 Oracle
【JAVA】JDK11新特性个人分析(二)
【JAVA】JDK11新特性个人分析
53 0
【JAVA】JDK11新特性个人分析(二)
|
4月前
|
JavaScript 前端开发 Oracle
云和数据JDK15新特性JAVA15版本
云和数据JDK15新特性JAVA15版本
57 0
|
9月前
|
安全 Java API
JDK 17 – Java 17 中的新特性
JDK 17 – Java 17 中的新特性
351 0
|
11月前
|
Oracle 安全 Java
最新Java JDK 21:全面解析与新特性探讨
最新Java JDK 21:全面解析与新特性探讨
449 0
最新Java JDK 21:全面解析与新特性探讨