Java 9 模塊化(Modular)介紹

前言

今年,2017年,我們將迎來 Java 語言的 22 歲生日,22歲,對於一個人而言,正是開始大展鴻圖的年紀,可是對於日新月異的科技圈中的一門開發語言而言,卻是一個傲視羣雄的老態龍鍾的年紀。


JVM 語言發展史

JVM 家族也是在這22年中茁壯發展,並且都秉承着 Java 的革命口號:一處編譯,隨處運行。
那麼,JVM 的帶頭人 Java 在 9.0 的版本中帶來了什麼變化呢?

模塊化

今天介紹一個Java 9的功能,模塊化(Modular);這可能使Java有史以來最大的Feature,它將自己長期依賴JRE的結構,轉變成以Module爲基礎的組件,這感覺就像一個壯士,需要把自己的胳膊,腿等,一個個拆下來,並且還能夠正常運行工作,難度可想而知。雖然,Java 9尚未發佈,但這個功能讓人期盼和煎熬了好多年了。
從1995年的第一天起,Java帶着一個口號,“Write once , Run anywhere” ,一路走來,從學院派的實驗語言,變成開發者最青睞的語言,然後成爲企業開發的統一語言,二十弱冠。時光如斯,Java也從一個創新的語言,慢慢變成一種“傳統”,“老舊”,“經典”語言,同時也接受很多新鮮語言的挑戰,例如Go,Scalar等。
Java從來就不是一種完美的語言:GC的效率總是給高併發程序員帶來不少痛苦和調整,Classpath地獄總是讓很多錯誤詭異的發生,高級語言特性總是在JCP(Java Community Process)裏面踢皮球而無法落地,異步模式的多線程編程總是有陡峭的學習曲線,Oracle JDK和OpenSDK總是有扯不清楚的關係,孤芳自傲且讓人崩潰的J2EE框架。
但是,我還是最喜歡Java編程語言,不僅因爲使用了20年,更有兩個原因:

  1. Java的生態:幾乎所有開發庫都支持Java語言,Java是打開程序世界的鑰匙。
  2. Java語言的開源:Java源代碼設計流暢,可以學到很多設計技能。

模塊化從Java 7就開始計劃推出 ,但由於其過於複雜,不斷跳票 Java 7和Java 8,終於計劃在Java 9中推出,我們一起拭目以待吧! 目前,Java 9的功能基本開發完畢,剩下半年的時間,解決各種Bug。下面是Java 9的時間表!


Java 9的時間表

Java 9中最重要的功能,毫無疑問就是模塊化(Module),代碼名字叫做Jigsaw(拉鋸),這個拉鋸項目拉了幾年,終於要把龐大冗餘的Java鋸成一個個的Module,方便開發和部署。熟悉Java的同學,都知道JRE有一個超級大rt.jar(例如,Java 8的rt.jar中有65M),運行一個hello world,你也需要一個數百兆的JRE環境,如果在J2EE環境,情況將變得複雜無比。另外,如果你沒有深受Classpath Hell所害,說明你還不是一個深度Java程序員。


Java 9 模塊化優勢對比圖

模塊化的功能有幾個目的:

  1. 讓Java的SE程序更加容易輕量級部署
  2. 改進組件間的依賴管理,引入比Jar粒度更大的Module
  3. 改進性能和安全性

如果用更加簡單解釋,那就是“解決Classpath地獄問題,改進部署能力”。Module的內容比較多,爲了由淺入深,我按照一些問題和我的理解來介紹模塊化。

1.什麼是Java Module(模塊)

模塊就是代碼和數據的封裝體,代碼是指一些包括類型的Packages。Package是一些類路徑名字的約定,而模塊是一個或多個Packages組成的一個封裝體。


什麼是模塊化

2. 模塊的代碼例子

模塊的是通過module-info.java進行定義,編譯後打包後,就成爲一個模塊的實體;在模塊的定義文件中,我們需要指定模塊之間的依賴靠關係,可以exports給那些模塊用,需要使用那些模塊(requires) 。下面是一個例子:

module com.foo.bar {
requires org.baz.qux;
exportscom.foo.bar.alpha;
exportscom.foo.bar.beta;
}
META-INF/
META-INF/MANIFEST.MF
module-info.class
com/foo/bar/alpha/AlphaFactory.class
com/foo/bar/alpha/Alpha.class
...

3.JDK8 和JDK9有什麼不一樣?

JDK8的JRE的部署是一個單體模式,一個超大的rt.jar(大約60多兆),tools.jar也有幾十兆,即使使用一個Hello Worlds,你也需要一整套上百兆的JRE環境。
JAVA 9 引入模塊後,將所有的類組織成模塊形式,模塊之間有着優美的依賴關係(至少現在很整齊,不知道過幾個版本會不會繼續保持優雅)。


Java 8的包之間的依賴關係


Java9的依賴關係(模塊之間依賴關係)

4. public關鍵字不再意味着Accessible(可訪問了)

模塊之間的關係被稱作readability(可讀性),代表一個模塊是否可以找到這個模塊文件,並且讀入系統中(注意:並非代表可以訪問其中的類型)。在實際的代碼,一個類型對於另外一個類型的調用,我們稱之爲可訪問性(Accessible),這意味着可以使用這個類型; 可訪問性的前提是可讀性,換句話說,現有模塊可讀,然後再進一步檢測可訪問性(安全)。
在Java 9中, Public不再意味着任意的可訪問性!


public關鍵字不再意味着任意的可訪問性

模塊之間的關聯關係

5.什麼是模塊的Transitive 引用(間接引用)

舉個例子:


我是栗子

因此標記了transitive可以可以提供一個間接可讀性。在myapp中,可以直接引用Logger類了。


可讀性示意圖

6. Module 和Maven是什麼關係

看完Module,這麼詳細的表達依賴關係,是不是和什麼軟件很相似?是不是想起了Maven還是Gradle? 仔細想象,Modular和它們還是不一樣的。

Modular是系統內置用於表述組件之間的關係,對於版本的管理還是處於最原始的狀體。它管理一種強制的依賴關係。
Maven有兩個核心功能 a) 組件的依賴管理,特別是版本的管理,這種依賴是邏輯上的,並非強制的 b)管理開發過程中的各種任務,初始化,測試等等。

7. JLink介紹

JLink是將Module進行打包的工具,幫助目標機器的部署。打包後的文件將非常精簡。


jLink工作示意圖

jLink工作指令示範

8 Module的原理和實現

在內部實現中,整個過程非常繁瑣複雜,大概有幾件事情;

a)將系統內部類進行模塊化

這樣不用在區分太多J2ME, J2SE,J2EE了,大家都是用模塊作爲溝通語言。這需要整理所有的類和它們調用關係,調用頻次等,把系統類模塊化,這可能最複雜的一部分,不過結果是完美的。

b) 將ClassLoader分級

將ClassLoader分爲三個級別,Bootstrap Loader具有最高優先級和權限,主要是核心的系統類;Platform Loader用於擴展的一些系統類,例如SQL,XML等;Application Loader主要用於應用程序的Loader。在這三個級別的Loader下面有一個統一Module 管理,用於控制和管理模塊間的依賴關係,可讀性,可訪問性等。 注意,ClassLoader在Java 9中的類裝載邏輯和之前一樣,但是,通過模塊管理系統,ClassLoader.FindClass的能力,將被限制在readable&accessible的條件下,而不是之前的簡單的Public條件。


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