Ant時代
相信你們對Ant都不陌生,Ant是任務型的,定義了一系列的任務dir/compile/jar等等,缺點是操做文件 Maven時代
Maven/Gradle相對於Ant,增長了groupId/artifactId,版本管理,依賴管理 OSGI時代
OSGI用的比較少,估計你們比較陌生,其實咱們用的Eclipse及插件都是OSGI編譯的java
那麼問題來了:當代碼庫愈來愈大,怎麼管理類庫交叉依賴,以及類重複的問題呢?安全
談到Java9你們每每第一個想到的就是Jigsaw項目。衆所周知,Java已經發展超過20年(95年最初發布),Java和相關生態在不斷豐富的同時也愈來愈暴露出一些問題:微信
Java運行環境的膨脹和臃腫
。每次JVM啓動的時候,至少會有30~60MB的內存加載,主要緣由是JVM須要加載rt.jar,無論其中的類是否被classloader加載,第一步整個jar都會被JVM加載到內存當中去(而模塊化能夠根據模塊的須要加載程序運行須要的class)當代碼庫愈來愈大,建立複雜,盤根錯節的「意大利麪條式代碼」的概率呈指數級的增加
。不一樣版本的類庫交叉依賴致使讓人頭疼的問題,這些都阻礙了Java開發和運行效率的提高很難真正地對代碼進行封裝, 而系統並無對不一樣部分(也就是JAR文件)之間的依賴關係有個明確的概念
。每個公共類均可以被類路徑之下任何其它的公共類所訪問到,這樣就會致使無心中使用了並不想被公開訪問的API。類路徑自己也存在問題
: 你怎麼知曉全部須要的JAR都已經有了, 或者是否是會有重複的項呢?同時,因爲兼容性等各方面的掣肘,對Java進行大刀闊斧的革新愈來愈困難,Jigsaw從Java7階段就開始籌備,Java8階段進行了大量工做,終於在Java9裏落地,一種千呼萬喚始出來的意味
。app
Jigsaw項目(後期改名爲Modularity)的工做量和難度大大超出了初始規劃。JSR376 Java平臺模塊化系統(JPMS,Java Platform Module System)做爲Jigsaw項目的核心, 其主體部分被分解成6個JEP(JDK Enhancement Proposals)。模塊化
做爲Java9平臺最大的一個特性,隨着Java平臺模塊化系統的落地,開發人員無需再爲不斷膨脹的 Java平臺苦惱,例如,您可使用jlink
工具,根據須要定製運行時環境。這對於擁有大量鏡像的容器應用場景或複雜依賴關係的大型應用等,都具備很是重要的意義。工具
本質上講,模塊(module)的概念,其實就是package外再裹一層,也就是說,用模塊來管理各個package,經過聲明某個package暴露,不聲明默認就是隱藏。所以,模塊化使得代碼組織上更安全,由於它能夠指定哪些部分能夠暴露,哪些部分隱藏
。性能
模塊獨立,化繁爲簡
模塊化(以 Java 平臺模塊系統的形式)將JDK分紅一組模塊,能夠在編譯時,運行時或者構建時進行組合。ui
模塊將由一般的類和新的模塊聲明文件(module-info.java)組成。 該文件是位於 java 代碼結構的頂層,該模塊描述符明確地定義了咱們 的模塊須要什麼依賴關係,以及哪些模塊被外部使用。在 exports 子 句中未說起的全部包默認狀況下將封裝在模塊中,不能在外部使用。 工程目錄結構: this
分兩個module:dog-module中類以下:spa
package net.hellomypastor.java9.entity;
public class Dog {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
複製代碼
在src目錄下新建module-info.java:
module dog_module {
exports net.hellomypastor.java9.entity;
}
複製代碼
exports
:控制着哪些包能夠被其它模塊訪問到。全部不被導出的包 默認都被封裝在模塊裏面
main-module中類以下:
package net.hellomypastor.java9;
import net.hellomypastor.java9.entity.Dog;
public class MyModule {
public static void main(String[] args) {
Dog dog = new Dog();
dog.setName("dog2018");
dog.setAge(1);
System.out.println("happy new year 2018");
System.out.println(dog.getName());
System.out.println(dog.getAge());
}
}
複製代碼
在src目錄下新建module-info.java:
module main_module {
requires dog_module;
}
複製代碼
requires
:指明對其它模塊的依賴