java9系列(三)模塊系統精要

本文主要講述下java9的模塊系統的必知必會的知識點。java

1.module及modules

module

module主要分以下兩種:
  • main module

包含main方法的module,經過--module或者-m指定api

  • root module

指定模塊系統解析的根模塊,從根模塊解析模塊依賴,能夠經過--add-modules mod1,mod2來指定框架

modules

  • unnamed modules
java9經過unnamed modules來支持非java9編寫的代碼,所以遺留代碼就能夠不用升級使用模塊系統,固然最好的方式是升級到支持模塊系統。

當模塊系統須要加載在其餘模塊定義的類型時,會嘗試從類路徑加載,若是加載成功,則會納入unnamed modules。unnamed modules會聲明依賴全部的named module,且exports本身的全部包,可是一個named module不能聲明依賴unnamed module。若是一個package在named和unnamed模塊中都有定義,則使用named中的package。ide

  • automatic modules
它是顯式聲明的named module與類路徑下jar包的橋接,它從一個沒有模塊聲明的jar包中隱式建立,模塊名取自MANIFEST.MF文件中的Automatic-Module-Name屬性或者jar包名字( 按必定規則從jar包名稱提取)。這樣named modules就可使用它來聲明依賴。( 須要在javac編譯時使用--module-path指定這些jar的路徑)

一個automatic modules會聲明依賴全部named和unnamed module,而後導出全部package,另外對其餘automatic module支持傳遞依賴ui

2.requires

聲明依賴

transitive

若是A依賴B,B依賴C,B方法返回的類型是C中的類型,那麼須要A也可使用C,則須要在A中聲明依賴C。不過這樣子很是費勁,因此java9內置了個transitive關鍵字。
在B聲明依賴的時候,指定傳遞依賴.net

module B {
    requires transitive C;
    exports func.b;
}
這樣A無需顯示requires模塊C就可使用C的類型了

static

聲明這個依賴是編譯時須要,運行時optional。比較適用於框架或類庫,好比jdbc驅動,編譯時僅僅須要api,運行時添加所需的指定類庫,若是不用static,則編譯時就須要把全部支持的jdbc驅動都聲明依賴,這樣比較費勁。code

3.exports

導出依賴接口

指定可見模塊

module A {
    exports modulea.funcB to B;
    exports modulea.funcC to C,D,E;
}
指定導出的modulea.funcB僅對B模塊可見
指定導出的modulea.funcC僅對C,D,E這三個模塊可見

4.open

open package

module demo {
    opens func1;
    opens func2 to func3;
}
在模塊聲明中容許(指定模塊)在運行時使用反射訪問

open module

open module編譯時僅限於指定的導出模塊可用,可是在runtime時容許全部包反射使用( 包括private類型和成員)。

open語法主要用於向後兼容,不少遺留代碼都使用反射get

5.service loader

主要在module-info.java描述本模塊是要使用哪一個service接口或者提供了哪一個service的實現。

use

用於聲明須要的service的接口,這樣就可使用ServiceLoader.load方法去加載依賴中的service providerit

module com.demo.consumer {
    requires com.example.data;
    uses com.example.data.SortService;
}
這裏的uses代表該模塊須要使用/消費SortService這個接口

provides with

module service.sort.bubble {
    requires service.sort;
    provides com.example.data.SortService with sort.impl.bubble.BubbleSort;
}
這個module使用provides和with聲明瞭是SortService的服務提供方,好讓模塊系統知道這個模塊提供了該接口的實現。

注意這裏不須要exports這個實現類

查看模塊描述

➜  ~ java -d java.logging
java.logging@9
exports java.util.logging
requires java.base mandated
provides jdk.internal.logger.DefaultLoggerFinder with sun.util.logging.internal.LoggingProviderImpl
contains sun.net.www.protocol.http.logging
contains sun.util.logging.internal
contains sun.util.logging.resources
contains:這部分是模塊中包含的但沒有導出的部分( internal)

mandated:java.lang,java.io,java.util等都在這個java.base模塊裏頭,它是其餘模塊的基礎,不用特殊聲明對它的依賴,默認全部模塊都依賴它。所以這裏查看模塊描述時,能夠看到java.base後面跟着一個mandated,表示這個是默認依賴

小結

java9的模塊系統聲明模塊主要有module,requires(transitive\static),exports,open(package\module)及service(uses\provides with)等幾個概念。

doc

相關文章
相關標籤/搜索