日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JDK9的新特性:JPMS模块化

發布時間:2024/2/28 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JDK9的新特性:JPMS模块化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 簡介
  • JDK9中模塊的實現
  • JDK中的module
  • 創建自己的module
  • 深入理解module-info
    • transitive
    • static
    • exports to
    • open pacakge
    • provides with
  • 總結

簡介


JDK9引入了一個新的特性叫做JPMS(Java Platform Module System),也可以叫做Project Jigsaw。模塊化的本質就是將一個大型的項目拆分成為一個一個的模塊,每個模塊都是獨立的單元,并且不同的模塊之間可以互相引用和調用。

在module中會有元數據來描述該模塊的信息和該模塊與其他模塊之間的關系。這些模塊組合起來,構成了最后的運行程序。

聽起來是不是和gradle或者maven中的模塊很像?

通過組件化,我們可以根據功能來區分具體的模塊,從而保持模塊內的高聚合,模塊之間的低耦合。

另外,我們可以通過模塊化來隱藏接口的具體實現內容,從而不影響模塊之間的調用。

更多精彩內容:
區塊鏈從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特幣等持續更新
Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續更新
Spring 5.X系列教程:滿足你對Spring5的一切想象-持續更新
java程序員從小工到專家成神之路(2020版)-持續更新中,附詳細文章教程

最后,我們可以通過顯示聲明來描述模塊之間的依賴關系。從而讓開發者更好的理解系統的應用邏輯。

JDK9中模塊的實現

在JDK9之前,java是通過不同的package和jar來做功能的區分和隔離的。

但在JDK9中,一切都發送了變化。

首先是JDK9本身的變化,JDK現在是以不同的模塊來區分的,如果你展開IDE中JDK的依賴,會看到java.base,java.compiler等模塊。

其中java.base模塊比較特殊,它是獨立的模塊,這就意味著它并不依賴于其他任何模塊,并且java.base是其他模塊的基礎,所以在其他模塊中并不需要顯式引用java.base。

我們再總結一下:

class是字段和方法的集合,package是class的集合,而module是package的集合。

一般來說使用模塊和不使用模塊對用戶來說基本上是感覺不到的,因為你可以將模塊的jar包當成普通的jar包來使用,也可以將普通的jar包當成模塊的jar包來使用。

當使用普通的jar包時,JDK將會采用一種Automatic modules的策略將普通jar包當成module jar包來看待。

那么module和普通的jar包有什么區別呢?

  • module中包含有一個module-info.class文件,這個文件定義了module本身的信息和跟外部module之間的關系。

  • 要使用module jar包,需要將該jar包放入modulepath而不是classpath。

  • 下面我們在具體的例子中詳細探索一下module的使用。

    JDK中的module

    剛剛講到了JDK也是以模塊來區分的,并且所有模塊的基礎都是java.base。我們可以使用java --list-modules 來列出現有的所有module:

    java --list-modules java.base@14.0.1 java.compiler@14.0.1 java.datatransfer@14.0.1 java.desktop@14.0.1 java.instrument@14.0.1 java.logging@14.0.1 java.management@14.0.1 java.management.rmi@14.0.1 ....

    也可以使用java --describe-module 來查看具體module的信息:

    java --describe-module java.basejava.base@14.0.1 exports java.io exports java.lang exports java.lang.annotation exports java.lang.constant exports java.lang.invoke exports java.lang.module exports java.lang.ref exports java.lang.reflect exports java.lang.runtime ...

    我們再具體看一下module-info.class文件中的內容:

    module java.base {exports java.io;exports java.lang;exports java.lang.annotation;...

    文件很長,具體就不一一列舉了,有興趣的朋友可以自行參閱。

    看到了JDK自帶的module,接下來我們創建幾個自己的module來看看。

    創建自己的module

    假如我們有一個controller,一個service的接口,和兩個service的實現。

    為了簡單起見,我們將這四個類分在不同的module中。

    在IDEA中創建一個module很簡單,只需要在java文件夾中添加module-info.java文件就可以了。如下圖所示:

    代碼其實很簡單,Controller引用了Service接口,而兩個Service的實現又實現了Service接口。

    看下controller和service兩個模塊的的module-info文件:

    module com.flydean.controller {requires com.flydean.service;requires lombok; } module com.flydean.service {exports com.flydean.service; }

    requires表示該模塊所要用到的模塊名字。exports表示該模塊暴露的模塊中的包名。如果模塊不暴露出去,其他模塊是無法引用這些包的。

    看下在命令行怎么編譯,打包和運行module:

    $ javac--module-path mods-d classes/com.flydean.controller${source-files} $ jar --create--file mods/com.flydean.controller.jar--main-class com.flydean.controller.ModuleController.Main-C classes/com.flydean.controller . $ java--module-path mods--module com.flydean.controller

    深入理解module-info

    上一節我們將了module-info中的requires和exports。這一節我們來更多的講解module-info中的其他用法。

    transitive

    先看下modulea的代碼:

    public ModuleService getModuleService(){return new ModuleServiceA();}

    getModuleService方法返回了一個ModuleService,這個ModuleService屬于模塊com.flydean.service,我們看下module-info的定義:

    module com.flydean.servicea {requires com.flydean.service;exports com.flydean.servicea; }

    看起來好像沒什么問題,但是如果有其他的模塊來使用servicea的getModuleService方法就會有問題,因為該方法返回了模塊com.flydean.service中定義的類。所以這里我們需要用到transitive。

    module com.flydean.servicea {requires transitive com.flydean.service;exports com.flydean.servicea; }

    transitive意味著所有讀取com.flydean.servicea的模塊也可以讀取 com.flydean.service。

    static

    有時候,我們在代碼中使用到了某些類,那么編譯的時候必須要包含這些類的jar包才能夠編譯通過。但是在運行的時候我們可能不會用到這些類,這樣我們可以使用static來表示,該module是可選的。

    比如下面的module-info:

    module com.flydean.controller {requires com.flydean.service;requires static com.flydean.serviceb; }

    exports to

    在module info中,如果我們只想將包export暴露給具體的某個或者某些模塊,則可以使用exports to:

    module com.flydean.service {exports com.flydean.service to com.flydean.controller; }

    上面我們將com.flydean.service只暴露給了com.flydean.controller。

    open pacakge

    使用static我們可以在運行時屏蔽模塊,而使用open我們可以將某些package編譯時不可以,但是運行時可用。

    module com.flydean.service {opens com.flydean.service.subservice;exports com.flydean.service to com.flydean.controller, com.flydean.servicea, com.flydean.serviceb; }

    上面的例子中com.flydean.service.subservice是在編譯時不可用的,但是在運行時可用。一般來說在用到反射的情況下會需要這樣的定義。

    provides with

    假如我們要在Controller中使用service的具體實現,比如servicea和serviceb。一種方法是我們直接在controller模塊中使用servicea和serviceb,這樣就高度耦合了。

    在模塊中,我們可以使用provides with來對模塊之間的耦合進行解耦。

    我們看下代碼:

    module com.flydean.controller {uses com.flydean.service.ModuleService;requires com.flydean.service;requires lombok;requires slf4j.api; } module com.flydean.servicea {requires transitive com.flydean.service;provides com.flydean.service.ModuleService with com.flydean.servicea.ModuleServiceA;exports com.flydean.servicea; } module com.flydean.serviceb {requires transitive com.flydean.service;provides com.flydean.service.ModuleService with com.flydean.serviceb.ModuleServiceB;exports com.flydean.serviceb; }

    在controller中,我們使用uses來暴露要實現的接口。而在具體的實現模塊中使用provides with來暴露具體的實現。

    怎么使用呢?我們在controller中:

    public static void main(String[] args) {List<ModuleService> moduleServices = ServiceLoader.load(ModuleService.class).stream().map(ServiceLoader.Provider::get).collect(toList());log.info("{}",moduleServices);}

    這里我們使用了ServiceLoader來加載接口的實現。這是一種很好的解耦方式,這樣我可以將具體需要使用的模塊放在modulepath中,實現動態的修改實現。

    要想在maven環境中順利完成編譯,maven-compiler-plugin的版本必須要在3.8.1以上。

    總結

    本文介紹了JDK9中module的使用,并在具體的中介紹了更多的module-info的語法。

    本文的例子https://github.com/ddean2009/
    learn-java-base-9-to-20

    本文作者:flydean程序那些事

    本文鏈接:http://www.flydean.com/jdk9-java-module-jpms/

    本文來源:flydean的博客

    歡迎關注我的公眾號:程序那些事,更多精彩等著您!

    超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

    總結

    以上是生活随笔為你收集整理的JDK9的新特性:JPMS模块化的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。