当前位置:   article > 正文

Spring boot 集成GraalVM JS引擎快速入门demo

Spring boot 集成GraalVM JS引擎快速入门demo

一、GraalVM.js介绍

是一款 JavaScript 解释器/编译器,能够在 JVM 上运行 Node.js 应用;

主要应用场景

因为JS是动态语言,不需要编译,因此可以通过JS动态改变程序执行逻辑,比如:风控规则,服务编排等等

二、代码工程

pom.xml

 
 
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>springboot-demo</artifactId>
  7. <groupId>com.et</groupId>
  8. <version>1.0-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>graalvm-js</artifactId>
  12. <properties>
  13. <maven.compiler.source>8</maven.compiler.source>
  14. <maven.compiler.target>8</maven.compiler.target>
  15. </properties>
  16. <dependencies>
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-starter-web</artifactId>
  20. </dependency>
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-autoconfigure</artifactId>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.springframework.boot</groupId>
  27. <artifactId>spring-boot-starter-test</artifactId>
  28. <scope>test</scope>
  29. </dependency>
  30. <dependency>
  31. <groupId>org.graalvm.js</groupId>
  32. <artifactId>js-scriptengine</artifactId>
  33. <version>20.2.0</version>
  34. </dependency>
  35. <dependency>
  36. <groupId>org.graalvm.js</groupId>
  37. <artifactId>js</artifactId>
  38. <version>20.2.0</version>
  39. </dependency>
  40. </dependencies>
  41. </project>

属性文件

 
 
  1. server:
  2. port: 8088

启动类

 
 
  1. package com.et.graalvm.js;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class DemoApplication {
  6. public static void main(String[] args) {
  7. SpringApplication.run(DemoApplication.class, args);
  8. }
  9. }

代码仓库

  • https://github.com/Harries/springboot-demo

三、测试

本地调用

 
 
  1. package com.et.graalvm.js;
  2. import org.junit.Test;
  3. import javax.script.*;
  4. /**
  5. * @author liuhaihua
  6. * @version 1.0
  7. * @ClassName com.et.graalvm.js.JSTest
  8. * @Description todo
  9. * @date 2024年03月07日 9:47
  10. */
  11. public class JSTest {
  12. @Test
  13. public void test10(){
  14. // 创建JavaScript引擎
  15. ScriptEngine jsEngine = new ScriptEngineManager().getEngineByName("js");
  16. // ScriptEngine jsEngine = new ScriptEngineManager().getEngineByExtension("js");
  17. // ScriptEngine jsEngine = new ScriptEngineManager().getEngineByMimeType("text/javascript");
  18. // 方式一,默认设置变量
  19. jsEngine.put("hello", "jack");
  20. // 方式二,使用binding设置变量
  21. SimpleBindings bindings = new SimpleBindings();
  22. bindings.put("hello","world");
  23. jsEngine.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);
  24. // 方式三,使用Context设置变量
  25. ScriptContext scriptContext = jsEngine.getContext();
  26. scriptContext.setAttribute("hello", "polo", ScriptContext.ENGINE_SCOPE);
  27. try {
  28. // 方式一,直接调用
  29. jsEngine.eval("print(hello)");
  30. // 方式二,编译调用(需要重复调用,建议先编译后调用)
  31. if (jsEngine instanceof Compilable){
  32. CompiledScript compileScript = ((Compilable) jsEngine).compile("print(hello)");
  33. if (compileScript != null){
  34. for (int i = 0; i < 10; i++) {
  35. compileScript.eval();
  36. }
  37. }
  38. }
  39. Invocable invocable = ((Invocable)jsEngine);
  40. // 方式三,使用JavaScript中的顶层方法
  41. jsEngine.eval("function greet(name) { print('Hello, ' + name); } ");
  42. invocable.invokeFunction("greet", "tom");
  43. // 方式四,使用某个对象的方法
  44. jsEngine.eval("var obj = { getGreeting: function(name){ return 'hello, ' + name; } } ");
  45. Object obj = jsEngine.get("obj");
  46. Object result = invocable.invokeMethod(obj, "getGreeting", "kitty");
  47. System.out.println(result);
  48. } catch (ScriptException | NoSuchMethodException e) {
  49. e.printStackTrace();
  50. }
  51. }
  52. }

远程调用

 
 
  1. package com.et.graalvm.js;
  2. import java.io.InputStream;
  3. import java.io.InputStreamReader;
  4. import java.io.BufferedReader;
  5. import java.io.IOException;
  6. import java.net.URL;
  7. import java.net.URLConnection;
  8. import javax.script.ScriptEngine;
  9. import javax.script.ScriptEngineManager;
  10. import javax.script.ScriptException;
  11. public class RemoteJSTest {
  12. public static void main(String[] args) throws IOException, ScriptException {
  13. URL jsUrl = new URL("https://example.com/script.js"); // js文件的URL
  14. URLConnection connection = jsUrl.openConnection();
  15. InputStream inputStream = connection.getInputStream(); // 获取js文件的流
  16. BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
  17. StringBuilder sb = new StringBuilder();
  18. String line;
  19. while ((line = reader.readLine()) != null) {
  20. sb.append(line).append("\n"); // 将js文件的内容存入StringBuilder
  21. }
  22. reader.close();
  23. inputStream.close();
  24. ScriptEngineManager engineManager = new ScriptEngineManager();
  25. ScriptEngine engine = engineManager.getEngineByName("nashorn"); // 获取Nashorn引擎
  26. String script = sb.toString(); // js文件的内容
  27. engine.eval(script); // 运行js文件
  28. Object result = engine.eval("hello()"); // 调用js文件中名为"hello"的函数
  29. System.out.println(result); // 输出结果
  30. }
  31. }

四、引用

  • https://www.graalvm.org/reference-manual/js/JavaInteroperability/

  • https://github.com/graalvm/graaljs/blob/master/docs/user/JavaScriptCompatibility.md

  • http://www.liuhaihua.cn/archives/710296.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/215917
推荐阅读
相关标签