Java之動態(tài)編譯器Janino

前言:學(xué)習(xí)時,往往先理論后實踐;工作中,往往先上手后理論。


??說明:這里以Demo形式快速介紹Janino使用,個人感覺Janino相比其它動態(tài)編譯技術(shù)小巧、高效、易上手。官方介紹 Janino is a super-small, super-fast Java compiler.but also compile a Java expression, a block, a class body, one .java file or a set of .java files in memory, load the bytecode and execute it directly in the same JVM. Janino不僅支持源文件的動態(tài)編譯、而且還支持表達(dá)式、語句塊、腳 本、class body等動態(tài)編譯,這使工作中選擇有了更多的余地,本文以class body為例。相關(guān)參考鏈接http://janino-compiler.github.io/janino/#janino-as-a-code-manipulator


1、工程描述


QQ圖片20190817164927.png

??這里是基于spring boot寫的一個小demo,里面就三個核心的文件,EacProxy.java:定義核心接口,EacProxy.temp:定義了一個模板,Janio.java:模擬業(yè)務(wù)層(對外提供接口)。


2、代碼步驟


第一:配置依賴包

<dependency>
    <groupId>org.codehaus.janino</groupId>
    <artifactId>janino</artifactId>
    <version>3.0.6</version>
</dependency>

第二:定義接口

public interface EacProxy {
     public String query();  //可以返回復(fù)雜對象類型
}

第三:定義模板(所有關(guān)聯(lián)依賴的包,都要在模板中引用進(jìn)來)

import com.janino.dao.EacProxy ;
public static EacProxy createProxy() {
#replaced#
}

第四:模擬業(yè)務(wù)接口

private static Map<String, String> map = new HashMap<String, String>();
    static {
        //用map模擬存儲的腳本,腳本可以是很復(fù)雜,這里只作簡單測試
        map.put("0", "return new EacProxy(){    public String query(){      return \"xxx交通管理局子公司分部一\";  }};");
        map.put("1", "return new EacProxy(){    public String query(){      return \"sss交通管理局子公司分部二\";  }};");
        map.put("2", "return new EacProxy(){    public String query(){      return \"阿里杭州蕭山一公司\";   }};");
        map.put("3", "return new EacProxy(){    public String query(){      return \"菜鳥物流下沙分倉庫\";   }};");
    }

    @RequestMapping("/janino")
    public String sayHello() throws Exception { 
        ClassBodyEvaluator ce = new ClassBodyEvaluator();//class body
        String key = String.valueOf(new Random().nextInt(4));
        String source = generateProxySource(map.get(key));
        ce.cook(source);
        Object obj = ce.getClazz().getMethod("createProxy").invoke(null);
        EacProxy ep = (EacProxy) obj;
        return ep.query();
    }

    public static String generateProxySource(String source) throws IOException {
        String template = StreamUtils.copyToString(Janino.class.getResourceAsStream("/EacProxy.temp"),
                Charset.forName("utf-8"));
        return template.replaceAll("#replaced#", source);
    }

??這里static語句塊中的map對象是用來模擬需要動態(tài)執(zhí)行的class body代碼,實際開發(fā)中這部分代碼可能是放到數(shù)據(jù)庫、文本文件、nosql等可以動態(tài)編輯的地方,里面可以包含復(fù)雜的邏輯,這里只模擬最簡單的流程。

第五:查看執(zhí)行結(jié)果


QQ圖片20190817170641.png

可以多刷新幾次,會返回不同腳本的執(zhí)行結(jié)果。


3、打包下載


鏈接:https://pan.baidu.com/s/110_jGp5mzkyFfmqTIp6egw 
提取碼:sn8s 

??若鏈接莫名失效,可以留言聯(lián)系,也可以按照上述的方式自行配置。


更多可以關(guān)注
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容