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 方法。

目录
相关文章
|
7月前
|
JSON 编解码 Java
Java升级:JDK 9新特性全面解析“
Java升级:JDK 9新特性全面解析“
166 0
|
2月前
|
开发框架 Oracle Java
【编程基础知识】《Java 世界探秘:JRE、JDK 与 JDK 版本全解析》
JRE(Java Runtime Environment)是运行Java程序所需的环境,包含JVM和Java核心类库,适合普通用户使用。JDK(Java Development Kit)则是Java开发工具包,不仅包含JRE,还提供了编译器、调试器等开发工具,适用于开发者。两者的主要区别在于JDK用于开发,而JRE仅用于运行Java程序。JDK各版本不断引入新特性,如Java 8中的Lambda表达式和默认方法等。环境配置方面,Windows和Linux系统都有详细的步骤,确保Java程序能够顺利编译和运行。
43 1
|
4月前
|
Java API Apache
JDK8到JDK24版本升级的新特性问题之在Java中,HttpURLConnection有什么局限性,如何解决
JDK8到JDK24版本升级的新特性问题之在Java中,HttpURLConnection有什么局限性,如何解决
|
4月前
|
安全 Java 编译器
JDK8到JDK21版本升级的新特性问题之JDK17重要的新特性有哪些
JDK8到JDK21版本升级的新特性问题之JDK17重要的新特性有哪些
|
7月前
|
算法 前端开发 JavaScript
【JAVA】JDK11新特性个人分析
【JAVA】JDK11新特性个人分析
119 0
|
6月前
|
安全 Oracle Java
Java一分钟之-GraalVM:高性能运行时与编译器
【6月更文挑战第12天】GraalVM是Oracle实验室的高性能运行时和编译器,支持Java、JavaScript等多语言,提供即时编译和提前编译技术,提升应用性能和跨语言互操作性。其核心亮点包括多语言支持、高性能、Native Image(AOT编译)和安全沙箱。常见问题涉及Native Image构建失败、反射与动态加载处理及资源消耗误解。解决这些问题需要详细阅读官方文档、利用GraalVM工具链和参考社区资源。通过Native Image,开发者可以构建接近零启动时间的原生应用。GraalVM是打破语言壁垒、提升应用效率的有力工具,随着生态发展,将在技术领域发挥更大作用。
158 1
|
7月前
|
JavaScript 前端开发 Oracle
【JAVA】JDK11新特性个人分析(二)
【JAVA】JDK11新特性个人分析
73 0
【JAVA】JDK11新特性个人分析(二)
|
7月前
|
算法 安全 Java
【JAVA】JDK11新特性个人分析(一)
【JAVA】JDK11新特性个人分析
266 0
【JAVA】JDK11新特性个人分析(一)
|
7月前
|
JavaScript 前端开发 Oracle
云和数据JDK15新特性JAVA15版本
云和数据JDK15新特性JAVA15版本
68 0
JDK各个版本的特性分析|JDK7|JDK8|JDK9|JDK10|JDK11|JDK12|JDK13特性分析
JDK各个版本的特性分析|JDK7|JDK8|JDK9|JDK10|JDK11|JDK12|JDK13特性分析