Java调用Lua,Lua调用Java

作者: adm 分类: java 发布时间: 2022-10-09

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请求
            Map map = 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.完美!

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!