早在Java7的時候就被提出,但由於其複雜性,不斷跳票,直到Java9才有,那麼Java模塊化到底是什麼,在實際開發中又有什麼用呢? ...
圖:模塊化手機概念
一、什麼是Java模塊化
Java模塊化(module)是Java9及以後版本引入的新特性。
官方對模塊的定義為:一個被命名的,代碼和數據的自描述集合。( the module, which is a named, self-describing collection of code and data)。
早在Java7的時候就被提出,但由於其複雜性,不斷跳票,直到Java9才有,那麼Java模塊化到底是什麼,在實際開發中又有什麼用呢?
簡單來說,就是把jar進一步掰碎。
一個jar可以有多個module,一個module可以有多個package。
從代碼結構上看,jar > module > package > class/interface。
那麼怎麼掰碎Jar包呢?
Java從自身做了一個典範,把JDK裡面大部分Jar都掰成了一個個module
JDK1.8結構:
JDK17將其拆成一個一個jmod:
而且,官方提供了文檔對每一個模塊進行了介紹:
模塊 | 描述 |
---|---|
java.base | 定義 Java SE 平臺的基礎 API。 |
java.compiler | 定義語言模型、註釋處理和 Java 編譯器 API。 |
java.datatransfer | 定義用於在應用程式之間和應用程式內傳輸數據的 API。 |
java.desktop | 定義 AWT 和 Swing 用戶界面工具包,以及用於 輔助功能、音頻、成像、列印和 JavaBeans。 |
java.instrument | 定義允許代理 檢測在 JVM 上運行的程式。 |
java.logging | 定義 Java 日誌記錄 API。 |
java.management | 定義 Java 管理擴展 (JMX) API。 |
java.management.rmi | 定義 Java 管理擴展插件 (JMX) 遠程 API 的 RMI 連接器。 |
java.naming | 定義 Java 命名和目錄介面 (JNDI) API。 |
java.net.http | 定義 HTTP 客戶端和 WebSocket API。 |
java.prefs | 定義首選項 API。 |
java.rmi | 定義遠程方法調用 (RMI) API。 |
java.scripting | 定義腳本 API。 |
java.se | 定義 Java SE 平臺的 API。 |
java.security.jgss | 定義 IETF 通用安全服務 API (GSS-API) 的 Java 綁定。 |
java.security.sasl | 定義對 IETF 簡單身份驗證和安全層的 Java 支持 (薩斯爾)。 |
java.smartcardio | 定義 Java 智能卡 I/O API。 |
java.sql | 定義 JDBC API。 |
java.sql.rowset | 定義 JDBC 行集 API。 |
java.transaction.xa | 定義用於在 JDBC 中支持分散式事務的 API。 |
java.xml | 定義 Java API for XML Processing (JAXP)、Streaming API for XML (StAX), XML 的簡單 API (SAX) 和 W3C 文檔對象模型 (DOM) API。 |
java.xml.crypto | 定義 XML 加密的 API。 |
jdk.accessibility | 定義輔助技術實現者使用的 JDK 實用程式類。 |
jdk.attach | 定義附加 API。 |
jdk.charset | 提供字元集 不在(主要是雙位元組和 IBM 字元集)。java.base |
jdk.compiler | 定義系統 Java 編譯器及其命令行等效項 javac 的實現。 |
jdk.crypto.cryptoki | 提供 SunPKCS11 安全提供程式的實現。 |
jdk.crypto.ec | 提供 SunEC 安全提供程式的實現。 |
jdk.dynalink | 定義用於動態鏈接對象高級操作的 API。 |
jdk.editpad | 提供 jdk.jshell 使用的編輯板服務的實現。 |
jdk.hotspot.agent | 定義熱點功能配置代理的實現。 |
jdk.httpserver | 定義特定於 JDK 的 HTTP 伺服器 API。 |
jdk.jartool | 定義用於操作 Java 歸檔 (JAR) 文件的工具, 包括 jar 和 jarsigner 工具。 |
jdk.javadoc | 定義系統文檔工具及其命令行等效項 javadoc 的實現。 |
jdk.jcmd | 定義用於診斷和排除 JVM 故障診斷的工具 如JCMD,JPS,JSTAT工具。 |
jdk.jconsole | 定義 JMX 圖形工具,jconsole, 用於監視和管理正在運行的應用程式。 |
jdk.jdeps | 定義用於分析 Java 庫和程式中依賴關係的工具, 包括 JDEPS、JavaP 和 JDEPRSCAN 工具。 |
jdk.jdi | 定義 Java 調試介面。 |
jdk.jdwp.agent | 提供 Java 調試線路協議 (JDWP) 代理的實現。 |
jdk.jfr | 定義 JDK 飛行記錄器的 API。 |
jdk.jlink | 定義用於創建運行時的 jlink 工具 圖像,用於創建和操作的 JMod 工具 JMOD文件,以及用於檢查的jimage工具 類和資源的特定於 JDK 實現的容器文件。 |
jdk.jshell | 此模塊提供對 Java 編程語言“片段”評估工具,例如 讀取-評估-列印迴圈 (REPL),包括 jshell 工具。 |
jdk.jsobject | 定義 JavaScript 對象的 API。 |
jdk.jstatd | 定義用於啟動守護程式的 jstatd 工具 用於遠程監控 JVM 統計信息的 JSTAT 工具。 |
jdk.localedata | 提供美國區域設置以外的區域設置的區域設置數據。 |
jdk.management | 為 JVM 定義特定於 JDK 的管理介面。 |
jdk.management.agent | 定義 JMX 管理代理程式。 |
jdk.management.jfr | 定義 JDK 飛行記錄器的管理介面。 |
jdk.naming.dns | 提供 DNS Java 命名提供程式的實現。 |
jdk.naming.rmi | 提供 RMI Java 命名提供程式的實現。 |
jdk.net | 定義特定於 JDK 的網路 API。 |
jdk.pack | 定義用於將 JAR 文件轉換為壓縮包200 文件的工具 並將打包文件轉換為 JAR 文件,包括 pack200 和 unpack200 工具。 |
jdk.rmic | 定義用於生成存根的 rmic 編譯器和 對遠程對象使用 Java 遠程方法協議 (JRMP) 的框架。 |
jdk.scripting.nashorn | 提供 Nashorn 腳本引擎的實現和 用 ECMAScript 5.1 編寫的程式的運行時環境。 |
jdk.sctp | 為 SCTP 定義特定於 JDK 的 API。 |
jdk.security.auth | 提供介面和各種身份驗證模塊的實現。javax.security.auth.* |
jdk.security.jgss | 定義 GSS-API 的 JDK 擴展和 SASL 的實現 GSSAPI機制。 |
jdk.xml.dom | 定義不屬於一部分的 W3C 文檔對象模型 (DOM) API 的子集 的 Java SE API。 |
jdk.zipfs | 提供 zip 文件系統提供程式的實現。 |
以上是機器翻譯,原文:https://docs.oracle.com/en/java/javase/11/docs/api/index.html
二、模塊化有什麼好處
好處就是將jar的功能精細化,可以按需使用。
猜測是為瞭解決Java項目尤其是JVM一直被詬病比較臃腫的問題,怎麼解決臃腫呢?砍就完了!
-
進一步規範Java的依賴
-
按需使用,最小化載入,減少衝突,減小Java應用大小
-
可以對耦合性封裝性進一步約束
-
使調用許可權管理更清晰,提高系統的安全性
精簡JRE就是模塊化一個典型的應用:
1、maven編譯,打包項目,打包依賴jar到libs
2、使用新版JDK自帶的jdeps找出依賴的模塊
3、使用新版JDK自帶的jlink製作自定義JRE
三、如何創建模塊
1、創建一個Java項目或者module
2、在代碼根路徑下創建文件module-info.java
定義模塊名稱,依賴的模塊,以及導出的模塊
3、編譯Java項目
在編譯後的目錄中可以看到module-info.class文件
4、創建jmod文件
使用jmod create命令:
命令格式:
jmod create --class-path module-info.class文件對應的路徑 輸出的jmod文件名
四、如何啟動可執行模塊
上面咱們創建的模塊中是有Main入口的可執行模塊,
那麼能不能像java -jar一樣執行這個模塊呢?
答案是肯定的:
使用java --module命令:
命令格式:
java --module-path 模塊文件所在路徑 模塊名稱/包名.main類名
執行後,就可以把java程式給運行起來啦:
五、既然這麼好,我們常用的Spring有沒有支持?
看到這裡,同學們可能發現了,這需要整個Java生態開發者所有人按規範對自己的Jar進行模塊化才能達到最優效果,而且實際開發過程中定義和管理自己的模塊及模塊之間的依賴關係是比較複雜的事情。
這裡有一個關於Java模塊化算不算複雜以及有沒有必要的知乎問題,供大家參考:
https://www.zhihu.com/question/610866431?utm_id=0
那麼我們常用的Spring有沒有被模塊化打動,也按規範進行模塊化了呢?
至少到Spring5還沒有,但是這裡有一些答案:
1:Declare Spring modules with JDK 9 module metadata
SpringFramework官方的回答:
https://github.com/spring-projects/spring-framework/issues/18079
機器翻譯:JDK 9的Jigsaw計劃旨在允許將模塊元數據(module-info.java)添加到框架和庫jar中,同時保持它們與JDK 8的相容性。讓我們對Spring Framework 5.0的模塊儘可能地這樣做。然而,我們可能無法以這種方式表達我們的可選依賴安排,在這種情況下,我們可能不得不採用“自動模塊”方法來實現#18289中更溫和的目的。
2:Any plans for Java 9 Jigsaw (module) of Spring projects?
https://stackoverflow.com/questions/43685081/any-plans-for-java-9-jigsaw-module-of-spring-projects
作者:京東科技 周波
來源:京東雲開發者社區 轉載請註明來源