java可用的动态脚本引擎和动态代码执行

java的ScriptEngine脚本引擎,支持代码动态执行,代码修改后不需要重启JVM进程,就可以使用解析或编译方式执行,非常方便,在动态业务规则、热更新、热修复等场景中会非常方便。
本文介绍3个支持javascript语法和1个支持java语法和脚本引擎。

1、javascript语法引擎

支持运行javascript语法的脚本引擎,主要有三个:

1.1、rhino

官网:https://github.com/mozilla/rhino
Rhino是JavaScript 的一种基于Java的实现,由Mozilla开发,JDK6和JDK7已集成,其它版本JDK需要添加依赖包。
pom.xml

<dependency>
      <groupId>org.mozilla</groupId>
      <artifactId>rhino-engine</artifactId>
      <version>1.7.14</version>
    </dependency>

使用例子

package com.penngo.script;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class RhinoTest {
    public static void main(String[] args) throws Exception{
        String js = """  
                function add (a, b) {
                    var sum = a + b; 
                    // js调用java类
                    java.lang.System.out.println("Script sum=" + sum);
                    return java.lang.Integer.valueOf(sum); 
                }
                """;
        //获得脚本引擎
        ScriptEngineManager sem = new ScriptEngineManager();
        ScriptEngine engine = sem.getEngineByName("rhino");
        engine.eval(js);

        Invocable jsInvoke = (Invocable) engine;
        //java中调用js
        Object result = jsInvoke.invokeFunction("add", new Object[] { 13.1, 20.1 });
        System.out.println("Rhino result=" + result);

    }
}

运行结果:

Script sum=33.2
Rhino result=33

1.2、nashorn

官网:https://github.com/openjdk/nashorn
在JDK8-JDK13,Nashorn取代Rhino成为Java的内置集成JavaScript引擎,Nashorn完整支持ECMAScript 5.1的规范以及一些扩展。在JDK8-JDK13外的版本需要添加依赖包:
pom.xml

<dependency>
    <groupId>org.openjdk.nashorn</groupId>
    <artifactId>nashorn-core</artifactId>
    <version>15.4</version>
</dependency>

使用例子

package com.penngo.script;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class NashornTest {
    public static void main(String[] args) throws Exception{

        String js = """
                // js调用java
                var Integer = Java.type("java.lang.Integer");
                var System = Java.type("java.lang.System");
                function add (a, b) {
                    var sum = a + b; 
                    System.out.println("Script sum=" + sum);
                    return Integer.valueOf(sum); 
                }
                """;
        ScriptEngineManager sem = new ScriptEngineManager();
        ScriptEngine engine = sem.getEngineByName("nashorn");
        engine.eval(js);
        Invocable jsInvoke = (Invocable) engine;
        //java中调用js
        Object result = jsInvoke.invokeFunction("add", new Object[] { 13.1, 20.1 });
        System.out.println("Nashorn result=" + result);
    }
}

运行结果:

Script sum=33.2
Nashorn result=33

1.3、j2v8

官网:https://github.com/eclipsesource/j2v8
J2V8是一套针对谷歌浏览器chrome的V8 Javascript引擎的java绑定,支持在Android、Windows、Linux、MacOS上运行,需要根据不同平台使用不同时依赖包:

<dependency>
    <groupId>com.eclipsesource.j2v8</groupId>
    <artifactId>j2v8_win32_x86_64</artifactId>
    <version>4.6.0</version>
</dependency>

不同平台的依赖包

  • j2v8_linux_x86_64
  • j2v8_win32_x86_64
  • j2v8_win32_x86
  • j2v8_android_x86
  • j2v8_android_armv7l
  • j2v8_macosx_x86_64

2、Java语法引擎

2.1、Groovy

官网:
http://groovy-lang.org/
https://github.com/groovy
Groovy是在Java虚拟机上实现的动态语言,提供了动态将java代码编译为Java Class对象的功能。需要添加依赖包
pom.xml

<dependency>
  <groupId>org.codehaus.groovy</groupId>
  <artifactId>groovy-all</artifactId>
  <version>3.0.14</version>
  <type>pom</type>
</dependency>

使用例子

package com.penngo.script;

import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;

public class GroovyTest {
    public static void main(String[] args) throws Exception{
        GroovyClassLoader loader = new GroovyClassLoader();
        // java代码
        String java = """
                public class Test01 {
                    public int add(double a, double b) {
                       double sum = a + b;
                       System.out.println("Script sum=" + sum); 
                       return sum.intValue();
                    }
                  
                }
                """;
        Class scriptClass = loader.parseClass(java);
        GroovyObject scriptInstance = (GroovyObject) scriptClass.getDeclaredConstructor().newInstance();
        Object result = scriptInstance.invokeMethod("add", new Object[]{13.1,20.1});
        System.out.println("Groovy result=" + result);
    }
}

运行结果

Script sum=33.2
Groovy result=33

本文测试源码

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

penngo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值