Java调用Lua,Lua调用Java
1.背景
在实际开发中,有时候我们需要修改了的代码可以马上生效,不需要打包、发布、启动等
使用Lua这种嵌入式语言作为策略实现,Java则是宿主语言,
Lua提供模板方法,其中需要的一些具体实现则有宿主语言Java提供。
可以完美的实现动态修改代码,动态生效!
2.实现原理
Luaj作为Java与Lua的桥梁
Luaj 是用纯Java实现,能够作为Java与Lua进行通信的桥梁。
官方文档:http://www.luaj.org/luaj/3.0/README.html
3.案例
3.1.引入luaj.jar包
<dependency> <groupId>org.luaj</groupId> <artifactId>luaj-jse</artifactId> <version>3.0.1</version> </dependency>
3.2.案例java代码
Demo01.java
import org.junit.Test; import org.luaj.vm2.Globals; import org.luaj.vm2.LuaValue; import org.luaj.vm2.lib.jse.JsePlatform; import java.io.FileInputStream; import java.io.InputStream; /** * @Copyright (C) XXXXXXXXXXX科技股份技有限公司 * @Date: 2021-09-08 11:05 * @Description: */ public class Demo01 { /** * 执行lua语句 */ @Test public void test01() { String luaStr = "print(\"你好世界\")"; Globals globals = JsePlatform.standardGlobals(); LuaValue chunk = globals.load(luaStr); chunk.call(); } /** * 执行lua循环语句 */ @Test public void test02() { String luaStr = "for i=10,1,-1 do\n" + " print(i)\n" + "end"; Globals globals = JsePlatform.standardGlobals(); LuaValue chunk = globals.load(luaStr); chunk.call(); } /** * 测试 * 读取外部文件执行lua */ @Test public void test03() throws Exception { // 读取文件 InputStream input = new FileInputStream("F:\\work\\demo01.lua"); byte[] by = new byte[input.available()]; input.read(by); String script = new String(by, "gbk"); System.out.println(script); // 执行脚本 Globals globals = JsePlatform.standardGlobals(); LuaValue chunk = globals.load(script); chunk.call(); } /** * 执行: lua脚本中的指定方法method01 * 无返回结果的lua方法 */ @Test public void test04() { LuaValue globals = JsePlatform.standardGlobals(); LuaValue dofile = globals.get("dofile"); dofile.call(LuaValue.valueOf("F:\\work\\demo02.lua")); globals.get("method01").call(); } /** * 执行: lua脚本中的指定方法method02 * 有返回结果的lua方法 */ @Test public void test05() { LuaValue globals = JsePlatform.standardGlobals(); LuaValue dofile = globals.get("dofile"); dofile.call(LuaValue.valueOf("F:\\work\\demo02.lua")); LuaValue luaValue = globals.get("method02").call(); int checkint = luaValue.checkint(); System.out.println("checkint=" + checkint); } /** * 执行 * 模拟执行http请求 */ @Test public void test06() { LuaValue globals = JsePlatform.standardGlobals(); LuaValue dofile = globals.get("dofile"); dofile.call(LuaValue.valueOf("F:\\work\\demo02.lua")); LuaValue luaValue = globals.get("method03").call(); String checkjstring = luaValue.checkjstring(); System.out.println("checkjstring=" + checkjstring); } }
HttpUtil.java
package lualib; import org.luaj.vm2.LuaValue; import org.luaj.vm2.lib.OneArgFunction; import org.luaj.vm2.lib.TwoArgFunction; import java.util.HashMap; import java.util.Map; /** * @Copyright (C) XXXXXXXXXXX科技股份技有限公司 * @Date: 2021-09-08 14:58 * @Description: */ public class HttpUtil extends OneArgFunction { @Override public LuaValue call(LuaValue luaValue) { LuaValue lib = tableOf(); // doPost在lua脚本调用是作为调用的方法名称 // lua中使用如下 // 1.引入java工具包 local http = require("lualib.HttpUtil") // 2.调用发放 local result = http.doPost('name=zs&age=18', 'POST') lib.set("doPost", new doPost()); return lib; } static class doPost extends TwoArgFunction { @Override public LuaValue call(LuaValue param, LuaValue method) { // TODO 执行post 实际开发中这里可以发起http请求 Mapmap = new HashMap (); map.put("name", "zs"); map.put("age", "lis"); map.put("param", param.checkjstring()); return LuaValue.valueOf(map.toString()); } } }
3.3.案例lua代码
demo01.lua
print("你好世界------------") -- 测试循环 for i = 10, 1, -1 do print('模拟执行:' .. i) end
demo02.lua
-- 引入java中和HttpUtil工具类 -- lualib.HttpUtil 是在java项目中的权限命名地址 local http = require("lualib.HttpUtil") function method01() print('------method01--------') end function method02() print('------method02--------') return 12 end -- 执行post请求 function method03() print('------method03--------') local result = http.doPost('name=zs&age=18', 'POST') return result end
3.4.测试
执行test方法即可看见lua中的代码已执行!
3.完美!