java9第一個模組化應用
本篇文章簡單的介紹了模組應用的開發,在這個過程中理解模組的概念以及模組的使用。
對於模組化的更強的封裝性以及更簡單的依賴的特性,當你把理解了模組時什麼東西之後自然而然就理解了。
需要宣告的是,為了更好的理解模組,本篇不使用任何IDE,直接使用命令列操作,廢話不多說,直接開始。
安裝JDK9
首先第一步就是要安裝JDK9了,怎麼安裝?大家都是老司機了。安裝完成後配置環境變數。然後開啟命令列,輸入下面命令,說明安裝成功:
F:\workspace\workspace-for-java9>java -version
java version "9"
Java(TM) SE Runtime Environment (build 9 +181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)
java9的安裝目錄和之前版本有明顯區別,有興趣的可以看一下。重要的就是jmods資料夾,其中包括了很多java自帶的模組。
建立專案工程java9test
很簡單。在工作空間中目錄中建立一個資料夾命名為java9test,這樣我們的專案工程就建好了。當前的目錄結構如下:
-workspace //工作空間
--java9test //專案工程
第一個模組moduleone
進入專案工程(java9test)目錄中,建立一個名稱為moduleone的目錄,在這個目錄中我們要開發我們的第一個模組。然後進入moduleone目錄,建立一個重要的檔案,名稱為module-info.java。從名稱上我們也可以看出來這個檔案是記錄模組資訊的,對於模組來說至關重要。檔案內容如下:
module moduleone { //指定了模組的名稱是moduleone
}
現在一個空的模組moduleone就完成了,下面我們在模組中新增一些程式碼。建立一個包,包名為com,com包下包含一個HelloModule.java檔案,檔案內容如下:
package com;
public class HelloModule{
public static void main(String [] args){
System.out.println("hello module");
}
}
當前目錄結構如下:
-workspace //工作空間
--java9test //專案工程
----moduleone
------module-info.java
------com
--------HelloModule.java
編譯
開啟命令列,進入工程java9test目錄中。執行下面命令:
javac -d mods --module-source-path . moduleone/module-info.java moduleone/com/HelloModule.java
沒有任何輸出就是最好的輸出。
說明一下:
- [-d mods]:表示編譯後的.class檔案位置。
- [–module-source-path .]:表示模組的原路徑,也就是當前路徑。
執行成功後,java9test目錄中會多出一個mods的檔案,裡面會包含編譯後的.class檔案。
執行
繼續執行如下命令:
java --module-path mods -m moduleone/com.HelloModule
這個命令的意思是執行模組路徑mods下的模組moduleone中的HelloModule類。
列印結果輸出如下:
hello module
到現在為止,我們的第一個模組就建立完成了。但是到目前為止,什麼依賴、封裝、更小的JRE我們還都沒有看到,我們繼續往下看。
第二個模組moduletwo
和第一個模組類似,在相同的目錄下建立moduletwo資料夾,當做第二個模組,在moduletwo中建立module-info.java檔案,內容如下:
module moduletwo { //指定了模組的名稱是moduletwo
}
然後建立包名log,包下建立類MyLog.java,內容如下:
package log;
public class MyLog{
public void info(String info){
System.out.println("[info]:"+info);
}
}
當前目錄結構如下:
-workspace //工作空間
--java9test //專案工程
----moduleone
------module-info.java
------com
--------HelloModule.java
----moduletwo
------log
--------MyLog.java
編譯moduletwo
開啟命令列,進入工程java9test目錄中。執行下面命令:
javac -d mods --module-source-path . moduletwo/module-info.java moduletwo/log/MyLog.java
在mods中也會出現moduletwo編譯後的.class檔案。
在moduleone中使用moduletwo
當前moduleone和moduletwo都在同一個專案工程中。怎麼在moduleone中使用moduletwo中的MyLog類呢?按照之前java版本的邏輯就是這樣的:MyLog類是public修飾的,並且有預設的構造方法,那也就是說這個類在任何地方都是可訪問的,那麼在moduleone中直接import log.MyLog;就可以了麼吧。答案是否定的,這還不夠。
java9中引入了模組,同時也就引入了一個概念,叫做模組可見性。預設模組之間是不可見的,這就是更強的封裝性,public不在是任何地方可訪問的了,被模組這層牆擋在了外面,這可能顛覆了你對java的認知。可以這麼說,更強的封裝性就會間接導致更簡單的依賴性。
那麼怎麼讓模組之間可見呢?這就需要匯出模組和匯入模組,具體操作如下:
開啟moduletwo中的module-info.java檔案,修改如下:
module moduletwo {
exports log; //匯出log包
}
exports log;的意思是匯出log包,讓其他模組可見。
開啟moduleone中的module-info.java,修改如下:
module moduleone {
requires moduletwo;//匯入模組moduletwo
}
requires moduletwo;表示匯入moduletwo模組,moduletwo模組中已經exports log;所以moduleone中就可以看到MyLog類了。
開啟HelloModule.java檔案,修改如下:
package com;
import log.MyLog;
public class HelloModule{
public static void main(String [] args){
MyLog log = new MyLog();
log.info("hello module");
}
}
編譯
重新編譯moduleone和moduletwo,命令如下:
javac -d mods --module-source-path . moduletwo/module-info.java moduletwo/log/MyLog.java moduleone/module-info.java moduleone/com/HelloModule.java
執行
命令如下:
java --module-path mods -m moduleone/com.HelloModule
輸出結構如下:
[info]:hello module
可以看到,執行成功。到現在為止,你或許已經對模組的強封裝和簡單依賴有那麼一絲絲的瞭解了。
模組打包執行
模組開發完成後,你就需要把模組打成jar包,供其他程式使用。首先我們在java9test中新建一個資料夾,來存放我們的jar包,檔名為mlib。這個檔案一定要手動建立,否則會報錯的。
然後執行jar命令,如下所示:
moduleone.jar
jar --create --file mlib/moduleone1.0.jar --module-version 1.0 --main-class com.HelloModule -C mods/moduleone .
注意一定不要忘記命令最後那個點。
moduletwo.jar
jar --create --file mlib/moduletwo1.0.jar --module-version 1.0 -C mods/moduletwo .
注意一定不要忘記命令最後那個點。
執行jar
命令如下:
java -p mlib -m moduleone
輸出結果如下:
[info]:hello module
OK!jar包執行也成功。
更小的JRE
之前的java版本中,有一個巨大的jar包,那就是rt.jar。這個jar包在java8中有61M。也就是說不管你的應用有多大,執行時環境最小也得包含這個61M的rt.jar,然後再包含其他的檔案就更大了,在本機上我看了一下jre8的大小為170多M。這就限制了java在更小的裝置中執行的能力。java9可以實現更小的執行時環境,並提供了一個工具jlink。下面我們就用使用jlink打造一個更小的執行時環境:
在java9test目錄下,開啟命令列,執行下面命令:
jlink --module-path "mlib;%JAVA_HOME%\jmods" --add-modules moduleone,moduletwo --output deploy --launcher launch=moduleone/com.HelloModule
這個命令會在java9test中生成一個deploy目錄,進入deploy目錄,會看到一個完整的執行時環境,這個環境只有三十幾兆,值得一提的是,我們的兩個模組已經存在於這個環境中。進入deploy/bin目錄,可以使用下面的命令直接執行專案:
F:\workspace\java9test\deploy\bin>launch.bat
輸出結果如下:
[info]:hello module
結束!!!!!!!!