【Janino】Janino介紹

在這裏插入圖片描述

1.概述

Janino 是一個超級小但又超級快的 Java™ 編譯器. 它不僅能像 javac 工具那樣將一組源文件編譯成字節碼文件,還可以對一些 Java 表達式,代碼塊,類中的文本(class body)或者內存中源文件進行編譯,並把編譯後的字節碼直接加載到同一個 JVM 中運行.

Janino 不是一個開發工具, 而是作爲運行時的嵌入式編譯器,比如作爲表達式求值的翻譯器或類似於 JSP 的服務端頁面引擎;

Janino 還被整合到 Apache Commons JCL 項目和 JBoss Rules/Drools 項目中;

Janino 可以被用於靜態代碼分析或者對代碼進行修改

2.產生原因

對使用過 JSP 的 Java 開發人員來說,Java 源代碼(內嵌於JSP 中的)動態編譯成類文件是很熟悉的技術。但卻未必知曉此技術的複雜性。

而造成它比較笨拙的原因在於需要安裝 JDK(非JRE)。由於 JDK 並非免費(被 Oracle 收購後尤其突出),於是又出現了 license 的問題。此外,對於不同的平臺,需進行不同的平臺配置並部署相應的類文件。對簡化版的程序也同樣需要複雜的操作。

儘管存在以上的問題,一些開源內庫如 Jasper 仍基於 JDK (即使有完全遵守 GPL 的 OpenJDK),且能提供很好的程序執行功能。

基於 Java 的構建工具 Ant 同樣面臨在編譯 Java 代碼時需克服過於複雜的問題。基於以上所述,動態編譯 Java 代碼通常被認爲是沒有辦法的辦法,且在實際應用中表現欠佳

3.運行方式

Janino 採用如下的方式來解決這些問題:

Janino 如同普通的應用程序一樣,運行在 JVM 上,而不是將編譯的工作間接轉交給 javac(或是等同的 Java 編譯器)來完成。同時也不需要額外的配置或安裝 JDK。

由於 Janino 直接從JVM獲得 classes 類文件,而不是通過應用程序獲取 class 文件和 .jar 文件。這意味着無需考慮權限問題或是構建路徑的配置。

Janino 提供一種簡單易用的方式來編譯表達、腳本和 classes 類文件。開發人員無需關心加載動態生成代碼的技術細節,因爲 Janino 自動實現了它。

在最簡單的層面,傳遞一個包含 Java 代碼的字符串即可返回一個對象

Janino 被更廣範的應用於那些比較複雜、雜亂且與平臺相關的 Java 應用程序的源碼編譯。Janino 通過動態編譯代碼,從而提高了程序的性能

4.結論

在平時的開發工作中,有很多情況可以用到動態編譯的技術。如下則列出了一些基本的參考意見:

使用動態編譯類來取代 Java 代理類,可避免所有的反射,因此可顯著的提高性能

對於用戶自定義功能等請求,可以像 Java 代碼一樣進行編譯與評價,而之前只能採用域定義語言(domain-specific language)來解析與評價。

如果數據記錄的字段固定,但不知道編譯所需時間,此時是 HashMaps 應用的典型場景。

利用 Janino,已知的字段可用於構建私有字段。再加上一些額外的工作,可通過 Map 接口將字段暴露出來。如果字段類型相對記錄數量來說很少時,內存的保存就顯得很重要了。

在程序的性能優化方面 Janino 還有更多的應用場合,對於想更好的提高 Java 代碼性能的開發人員,可以更加深入的研究Janino。

5.其他用途

最常見的應該是在日誌框架裏,當引用 slf4j + log4j/logback 的時候,常常會順帶引用 Janino 來提高日誌輸出的性能:

<dependencies>
  <!-- 日誌文件管理包 -->
  <!--  logback+slf4j -->
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${slf4j.version}</version>
  </dependency>
  <dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>${logback.version}</version>
  </dependency>
  <dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-access</artifactId>
    <version>${logback.version}</version>
  </dependency>
  <dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>${logback.version}</version>
  </dependency>
  <!-- 日誌文件管理包-提高性能log輸出性能 -->
  <!--  janino -->
  <dependency>
    <groupId>org.codehaus.janino</groupId>
    <artifactId>commons-compiler</artifactId>
    <version>${janino.version}</version>
  </dependency>
  <dependency>
    <groupId>org.codehaus.janino</groupId>
    <artifactId>janino</artifactId>
    <version>${janino.version}</version>
  </dependency>
</dependencies>

附:提高性能的傳統方法

Java 程序的慢速構建已經影響了系統可見的性能。它會影響程序開發者的效率、開發成本及程序的可擴展性。那麼,對於採用 Java 作爲開發語言的公司,又將如何提到程序的性能呢?下面是幾種常用的性能優化方法:

優化算法

在本文的實例中,將採用最安全且原始的方法來提到程序性能。僅通過改變本地代碼而實現提高性能的目標,並且能簡易地測試程序的可擴展性。

優化硬件

此種方法可以比較原始的提高程序的性能。相比開發者花費數小時去優化軟件而言,通過改變單個服務器的機器性能更合算些。但是這種優化硬件的方法並沒有考慮到如下一些較複雜的因素:開發人員的需要、應用程序被多次部署的可能性以及硬件能能被更新的空間。

優化軟件

通常而言,Java代碼(Java庫、應用服務器、數據庫驅動程序等)的運行效率較其它語言會更高些。儘量保證程序代碼的高效性,是提高應用程序性能的不二選擇。但遺憾的是,這往往很難預先決定,因爲類庫的性能特性取決於操作環境,而操作環境不到開發的最後階段是不確定的。

優化程序架構

由於對人員素質要求較高,優化程序架構是最後的方法。通常而言,對程序的每一次架構上的變動,代碼都需部分的重寫並重新的評估。對於特大型的項目,局部的架構變動是很有可能的,而這種情況下優化程序架構的風險就相當的高。

如果爲了提高程序的性能而窮盡以上的方法,那將是一件令人十分痛苦的事情,特別對一些複雜且難以理順的大項目更是如此。

附2:JDK和JRE

Java Development Kit(JDK)是 Sun 針對 Java 開發人員發佈的免費軟件開發工具包(SDK,Software development kit)。自從 Java 推出以來,JDK 已經成爲使用最廣泛的 Java SDK。

由於 JDK 的一部分特性採用商業許可證,而非開源。因此,2006 年 Sun 宣佈將發佈基於 GPL 的開源 JDK,使 JDK 成爲自由軟件。在去掉了少量閉源特性之後,昇陽電腦最終促成了 GPL 的 OpenJDK 的發佈。

作爲Java語言的SDK,普通用戶並不需要安裝JDK來運行Java程序,而只需要安裝JRE(Java Runtime Environment)。而程序開發者必須安裝JDK來編譯、調試程序。

JDK中還包括完整的JRE(Java Runtime Environment),Java運行環境,也被稱爲private runtime。包括了用於產品環境的各種庫類,如基礎類庫rt.jar,以及給開發人員使用的補充庫,如國際化與本地化的類庫、IDL庫等等。

https://zh.wikipedia.org/zh-hans/JDK

Java運行環境(Java Runtime Environment,簡稱JRE)是一個軟件,由太陽微系統所研發,JRE 可以讓電腦系統運行 Java應用程序(Java Application)。

JRE的內部有一個Java虛擬機(Java Virtual Machine,JVM)以及一些標準的類別函數庫(Class Library)。

許可協議大部分是基於 GPL 的

Oracle 提供的 Java SE 在“通用計算”使用範圍內仍然是完全免費的,Oracle提供的Java SE Advanced系列的產品是收費的 ;

但其實很簡單的判斷方式就是:使用了 -XX:+UnlockCommercialVMOptions 的功能都是收費的。

一臺臺式機,裝着普通的 Windows 或者 Linux,在上面跑 Java SE 是屬於通用計算的範圍內。

但如果這樣一臺臺式機被包裝到一個像 ATM 那樣的櫃子中,平時只運行某些特定的 Java 程序給客戶提供服務的話,那就有可能要被歸類到“嵌入式領域”。

Google 好像是在 Android 6.0 的某個版本使用了 OpenJDK,來徹底解決 JDK 的版權問題

毒瘤 Oracle,坑完 MySQL 坑 openOffice,坑完了 Solaris 坑 JAVA,據說跟甲骨文有關的新聞就瘋狂的噴甲骨文就對了

參考
http://tech.it168.com/oldarticle/2007-06-08/200706080812093_all.shtml

https://www.zhihu.com/question/53791269

轉載於:https://www.cnblogs.com/bfchengnuo/articles/8146634.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章