JDK的模塊化
在Java模塊化系統引入之前,JDK的運行時庫包括了重量級的rt.jar,該jar文件的總大小超過60M,包含了大量的運行時類。為了重構整個Java平台,也為了Java能夠在輕量級語言解決方案越來越佔主導地位的情況下讓Java語言繼續旺盛的生命力,JDK團隊引入了JDK的模塊化設計,這個決定可能是關鍵性的。
在過去的20年中,JDK的若干次發布,每一次都會包含許多新的特性,因此也增加了大量的類。以CORBA為例,它在上世紀90年代的時候被認為是企業級計算的未來,當然現在幾乎沒有人記得它了,然而用於支持CORBA的類仍然被包含在rt.jar包裡面,也就是說,無論你有沒有用到這些類,只要你的應用程序是分散式的,你都不得不帶著它們一起運行。這樣做的直接後果是浪費了磁碟空間、內存空間,以及CPU資源(需要增大CPU運行耗時)。對於資源受限的硬體載體,或者雲端的資源,這樣就產生了浪費,也增加了成本(雲端資源是按需申請的,能省就省)。
那麼我們可不可以直接移除這些不需要的類呢?不能這麼簡單執行,因為我們需要考慮每次發布之後的向前兼容,直接刪除API會導致JDK升級後一些老的應用程序不可用。JDK引入模塊化管理方式後,我們只需要忽略包含CORBA的模塊就可以了。
當然,分解單體型(monolithic)的JDK並不僅僅是移除過時(例如CORBA)的類。JDK包含的很多技術都是這樣的,對於一些人有用,對於另一些人則是無用的,但是並不是說它們過時了,僅僅是應用程序不需要使用。Java語言一直以來就存在安全性漏洞,通過模塊化設計可以減少類的應用,自然也就降低了漏洞發生的幾率。
截止目前,JDK9大約有超過90個平台模塊,這種方式取代了以往的單一型大庫形態。平台模塊是JDK的一部分,它和應用程序模塊是不一樣的,應用程序模塊是由程序員自己創建的。但是從技術層面來看,平台模塊和應用程序模塊又沒有什麼區別。每一個平台模塊構造了一個JDK功能,從日誌到XML的支持,等等,覆蓋了原有單一型JDK的功能。在JDK9里,所有的模塊都需要在外部顯示地定義與其他模塊之間的依賴關係,這就好比我們買可拆裝傢具時的各模塊之間的榫頭,你一看就知道需要和哪些其他模塊進行拼接,而一些其他模塊都可以拿來公用的模塊,比如java.logging,你就會發現很多模塊都會應用它。也正是由於引入了模塊化,JDK內部終於在各個模塊之間有了清晰的界限,互相的引用關係終於清晰了。
注意,按照JDK9目前的模塊化設計理念,所有的依賴關係都是指向向下方向的,不會出現編譯時的各模塊間環形依賴情況,你自己編寫的應用程序模塊也需要避免這種情況發生。
模塊資源介紹
一個模塊包含模塊名稱、相關的代碼和資源,這些都被保存在稱為module-info.java的模塊描述文件里,以下面這個文件為例,描述java.prefs平台模塊。
代碼清單1內包含了requires和exports兩個關鍵字,逐一解釋:
?requires關鍵字表示了依賴關係,這裡明確模塊需要依賴java.xml模塊,如果沒有依賴生命,java.prefs模塊在編譯時會拒絕執行編譯命令。這一點是向Maven借鑒的,使用前必須聲明才能使用。
注意,模塊名由於是全局變數,所以需要是全局唯一的。
HelloWorld案例
接下來簡單介紹一個HelloWorld示例。如清單2所示,HelloModularWorld類的main函數負責列印字元串「Hello World, new modular World!」。
為了實現模塊化,需要在工程的根目錄下創建一個名為module-info.Java的類,內容如清單3所示:
清單3 module-info.Java源碼
module org. michael.demo.jpms_hello_world {
// this module only needs types from the base module "Java.base";
// because every Java module needs "Java.base", it is not necessary
// to explicitly require it - I do it nonetheless for demo purposes
requires Java.base;
// this export makes little sense for the application,
// but once again, I do this for demo purposes
exports org.michael.demo.jpms;
}
清單4 編譯模塊化系統
$ Javac
-d target/classes
$
$ jar --create
--file target/jpms-hello-world.jar
--main-class org.michael.demo.jpms.HelloModularWorld
-C target/classes .
$ Java
--module-path target/jpms-hello-world.jar
--module org. michael.demo.jpms_hello_world
就這個簡單的示例來看,除了增加了一個文件、編譯時的差別替換為使用模塊路徑方式(module path),以及工程沒有了manifest文件以外,其他和Java9之前的編程/編譯方式是一樣。
發個小廣告!!!走過路過,不要錯過!新書來啦!!!
註:本公眾號與噹噹店鋪並無從屬關係,僅為大家提供一個便捷購物地址。若有所衝突,純屬巧合,立刪。
麥克叔叔每晚十點說


TAG:麥克叔叔每晚10點說 |