为了在spring boot项目中能够更快捷灵活地增加新的功能,我想到了在spring boot中执行python等脚本语言的设想。然后通过前端新增任务,无需修改后端。 ## [GraalJS官方DEMO](https://github.com/graalvm/graal-languages-demos/tree/main/graaljs/graaljs-maven-webpack-guide) ``` Source bundleSrc = Source.newBuilder("js",App.class.getResource("/bundle/bundle.mjs")).build(); Value exports = context.eval(bundleSrc); QRCode qrCode = exports.getMember("QRCode").as(QRCode.class); String input = "https://www.graalvm.org/javascript/"; Promise resultPromise = qrCode.toString(input); ``` **跟着DEMO走,代码执行到这里,qrCode内容为:**`方法抛出 'org.graalvm.polyglot.PolyglotException' 异常。 无法对 jdk.proxy2.$Proxy67.toString() 求值`,似乎是无法获取到qrCode的toString实现类。暂时放弃。 ## [GraalPY spring boot DEMO](https://github.com/graalvm/graal-languages-demos/tree/main/graalpy/graalpy-spring-boot-guide) **记录一些经验:** 1. **官网中只让添加了两个依赖:** ``` org.graalvm.polyglot polyglot 24.2.1 org.graalvm.polyglot python 24.2.1 pom ``` **但是需要注意的是,如果你要引入第三方依赖,例如**`request`这样的包,还需要导入一个依赖: ``` org.graalvm.python python-embedding 24.2.1 ``` **同时使用**`org.graalvm.python.embedding.GraalPyResources`创建上下文,以下是一个工具类: ``` import jakarta.annotation.PreDestroy; import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Value; import org.graalvm.python.embedding.GraalPyResources; import org.springframework.stereotype.Component; @Component // ① public class GraalPyContext { static final String PYTHON = "python"; private final Context context; public GraalPyContext() { context = GraalPyResources.contextBuilder().build(); // ② context.initialize(PYTHON); // ③ } public Value eval(String source) { return context.eval(PYTHON, source); // ④ } @PreDestroy public void close() { context.close(true); // ⑤ } } ``` * **积极地将其初始化为单例组件。** * **所创建的 GraalPy 上下文将作为整个应用程序访问 GraalPy 的唯一入口。** * **初始化 GraalPy 上下文的代价较高,因此我们在创建时就进行初始化,以避免后续响应时间延迟。** * **在 GraalPy 上下文中执行 Python 代码。** * **在应用程序关闭时关闭 GraalPy 上下文。** 2. **导入python依赖** ``` org.graalvm.python graalpy-maven-plugin ${org.graalvm.version} requests process-graalpy-resources ``` 3. **然后就可以愉快的运行python代码了** ``` public void testForGraalPy() throws ScriptException { String CODE = """ import requests def http_get(url, timeout=5): try: response = requests.get(url, timeout=timeout) print(f"Status Code: {response.status_code}") print("Response Body:") print(response.text) except requests.exceptions.Timeout: print("请求超时") except requests.exceptions.ConnectionError: print("连接失败") except requests.exceptions.RequestException as e: print(f"请求异常: {e}") # 示例用法 if __name__ == "__main__": print("hello world") http_get("https://www.baidu.com") """; graalPyContext.eval(CODE); } ``` Loading... 为了在spring boot项目中能够更快捷灵活地增加新的功能,我想到了在spring boot中执行python等脚本语言的设想。然后通过前端新增任务,无需修改后端。 ## [GraalJS官方DEMO](https://github.com/graalvm/graal-languages-demos/tree/main/graaljs/graaljs-maven-webpack-guide) ``` Source bundleSrc = Source.newBuilder("js",App.class.getResource("/bundle/bundle.mjs")).build(); Value exports = context.eval(bundleSrc); QRCode qrCode = exports.getMember("QRCode").as(QRCode.class); String input = "https://www.graalvm.org/javascript/"; Promise resultPromise = qrCode.toString(input); ``` **跟着DEMO走,代码执行到这里,qrCode内容为:**`方法抛出 'org.graalvm.polyglot.PolyglotException' 异常。 无法对 jdk.proxy2.$Proxy67.toString() 求值`,似乎是无法获取到qrCode的toString实现类。暂时放弃。 ## [GraalPY spring boot DEMO](https://github.com/graalvm/graal-languages-demos/tree/main/graalpy/graalpy-spring-boot-guide) **记录一些经验:** 1. **官网中只让添加了两个依赖:** ``` <dependency> <groupId>org.graalvm.polyglot</groupId> <artifactId>polyglot</artifactId> <version>24.2.1</version> </dependency> <dependency> <groupId>org.graalvm.polyglot</groupId> <artifactId>python</artifactId> <version>24.2.1</version> <type>pom</type> </dependency> ``` **但是需要注意的是,如果你要引入第三方依赖,例如**`request`这样的包,还需要导入一个依赖: ``` <dependency> <groupId>org.graalvm.python</groupId> <artifactId>python-embedding</artifactId> <version>24.2.1</version> </dependency> ``` **同时使用**`org.graalvm.python.embedding.GraalPyResources`创建上下文,以下是一个工具类: ``` import jakarta.annotation.PreDestroy; import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Value; import org.graalvm.python.embedding.GraalPyResources; import org.springframework.stereotype.Component; @Component // ① public class GraalPyContext { static final String PYTHON = "python"; private final Context context; public GraalPyContext() { context = GraalPyResources.contextBuilder().build(); // ② context.initialize(PYTHON); // ③ } public Value eval(String source) { return context.eval(PYTHON, source); // ④ } @PreDestroy public void close() { context.close(true); // ⑤ } } ``` * **积极地将其初始化为单例组件。** * **所创建的 GraalPy 上下文将作为整个应用程序访问 GraalPy 的唯一入口。** * **初始化 GraalPy 上下文的代价较高,因此我们在创建时就进行初始化,以避免后续响应时间延迟。** * **在 GraalPy 上下文中执行 Python 代码。** * **在应用程序关闭时关闭 GraalPy 上下文。** 2. **导入python依赖** ``` <plugin> <groupId>org.graalvm.python</groupId> <artifactId>graalpy-maven-plugin</artifactId> <version>${org.graalvm.version}</version> <executions> <execution> <configuration> <packages> <package>requests</package> </packages> </configuration> <goals> <goal>process-graalpy-resources</goal> </goals> </execution> </executions> </plugin> ``` 3. **然后就可以愉快的运行python代码了** ``` public void testForGraalPy() throws ScriptException { String CODE = """ import requests def http_get(url, timeout=5): try: response = requests.get(url, timeout=timeout) print(f"Status Code: {response.status_code}") print("Response Body:") print(response.text) except requests.exceptions.Timeout: print("请求超时") except requests.exceptions.ConnectionError: print("连接失败") except requests.exceptions.RequestException as e: print(f"请求异常: {e}") # 示例用法 if __name__ == "__main__": print("hello world") http_get("https://www.baidu.com") """; graalPyContext.eval(CODE); } ``` 最后修改:2025 年 07 月 14 日 © 允许规范转载 赞 别打赏,我怕忍不住购买辣条与续命水