iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >详解JDK9特性之JPMS模块化
  • 111
分享到

详解JDK9特性之JPMS模块化

2024-04-02 19:04:59 111人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录简介jdk9中模块的实现JDK中的module创建自己的module深入理解module-infotransitivestaticexports toopen pacakgepr

简介

在module中会有元数据来描述该模块的信息和该模块与其他模块之间的关系。这些模块组合起来,构成了最后的运行程序。

听起来是不是和gradle或者Maven中的模块很像?

通过组件化,我们可以根据功能来区分具体的模块,从而保持模块内的高聚合,模块之间的低耦合。

另外,我们可以通过模块化来隐藏接口的具体实现内容,从而不影响模块之间的调用。

最后,我们可以通过显示声明来描述模块之间的依赖关系。从而让开发者更好的理解系统的应用逻辑。

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.base

java.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的语法。

以上就是详解JDK9特性之JPMS模块化的详细内容,更多关于JDK9特性之JPMS模块化的资料请关注编程网其它相关文章!

--结束END--

本文标题: 详解JDK9特性之JPMS模块化

本文链接: https://www.lsjlt.com/news/127398.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 详解JDK9特性之JPMS模块化
    目录简介JDK9中模块的实现JDK中的module创建自己的module深入理解module-infotransitivestaticexports toopen pacakgepr...
    99+
    2024-04-02
  • JDK9新特性详解
    1、Java9新特性之目录结构      包含jdk8及以前的jdk版本,所有目录结构以及目录含义如图:        jdk9之后,目录结...
    99+
    2023-06-02
  • Java9新特性中的模块化详解
    目录模块化是什么?那么,模块化怎么用呢?为什么要用模块化显式管理依赖:强封装性:安全性:规范性:自定义最小运行时映像:孵化器模块的支持:Java9中的一个重大特性是增加了一种新型的程...
    99+
    2024-04-02
  • python自动化之re模块详解
    目录一、re是什么?二、re 模块的作用三、re模块的使用1、常用方法2、 元字符3、多字符匹配4、分组匹配5、match()方法的使用6、 search():在字符串中搜索,返回搜...
    99+
    2024-04-02
  • webpack5新特性Asset Modules资源模块详解
    目录正文图片打包(asset/resource)publicPathasset/inline 模块asset 模块asset/source 模块正文 webpack 可以将很多类型...
    99+
    2023-03-02
    webpack5特性Asset Modules webpack5 资源模块
  • Burpsuite模块之Burpsuite Intruder模块详解
    目录一、简介二、模块说明Burp Suite Intruder的4种攻击类型一 Sniper(狙击手模式)二Battering ram(攻城锤模式)三Pitchfork(草叉模式)四...
    99+
    2024-04-02
  • 详解NodeJS模块化
    目录一、前言二、正文2.1、什么是模块2.2、Resolving2.3、require.resolve2.4、模块间的父子依赖关系2.5、exports, module.export...
    99+
    2024-04-02
  • JavaScript 模块化详解
    目录前言:1.概念2.模块化的好处3.引入多个script标签后出现的问题一、CommonJS二、AMD三、CMD四、ES6模块化前言: 1.概念 将一个复杂的程序依据一...
    99+
    2024-04-02
  • Python序列化模块之pickle与json详解
    目录序列化模块序列化和反序列化使用场景dumps & loadsdump & loadJSON序列化模块使用场景支持的数据类型JSON和pickle的区别序列化函数j...
    99+
    2024-04-02
  • python之sys模块详解
    前言 sys模块是与python解释器交互的一个接口。sys 模块提供了许多函数和变量来处理 Python 运行时环境的不同部分。 处理命令行参数 在解释器启动后, argv 列表包含了传递给脚本的所...
    99+
    2023-09-15
    python 开发语言 pycharm
  • Python之re模块详解
    目录Python——re模块 简介预定义字符特殊字符反斜杠问题匹配方法总结Python——re模块  简介 定义:re模块称为正则表达式; 作用:创建一个"规则表...
    99+
    2024-04-02
  • Django模块学习之模块语言详解
    目录前言1、变量2、注释3、过滤器4、标签:include5、标签:for6、标签:if总结前言 Django模块引擎支持Django模块语言(简称DTL)。DTL包含变量、注释、过...
    99+
    2024-04-02
  • Go1.18 新特性之多模块Multi-Module工作区模式
    目录背景举例:未发布的 moduleGo1.18 新特性:多模块(Multi-Module)工作区模式Go1.18 工作区模式初始化一个新的工作区go.work 文件结构go.wor...
    99+
    2024-04-02
  • Python基础之模块详解
    目录一、模块1、模块的四种形式2、为什么要用模块?二、如何用模块1、import 模块名导入重命名:smt变量指向span模块的名称空间导入多个模块2、from 模块名 import...
    99+
    2024-04-02
  • 详解python代码模块化
    一、概念 1、模块化代码可以使代码易于维护和调试,并且提高代码的重用性; 2、函数可以用来减少冗余的代码并提高代码的可重用性。函数也可以用来模块化代码并提高程序的质量; 3、在pyt...
    99+
    2024-04-02
  • Java9新特性Module模块化编程的方法
    这篇文章主要讲解了“Java9新特性Module模块化编程的方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java9新特性Module模块化编程的方法”吧!在Java 9版本中Java ...
    99+
    2023-06-29
  • C++11新特性之变长参数模板详解
    目录C++11 变长参数模板变长函数参数包如何解参数包sizeof()获得函数参数个数递归模板函数变参模板展开结论C++11 变长参数模板 在C++11之前,无论是类模板 还是函数...
    99+
    2024-04-02
  • MySQL8新特性之全局参数持久化详解
    目录前言全局参数持久化写在最后总结参考文档:前言 自从 2018 年发布第一版 MySQL 8.0.11 正式版至今,MySQL 版本已经更新迭代到 8.0.26,相对于稳定的 5...
    99+
    2024-04-02
  • Spring之ORM模块代码详解
    Spring框架七大模块简单介绍Spring中MVC模块代码详解ORM模块对Hibernate、JDO、TopLinkiBatis等ORM框架提供支持ORM模块依赖于dom4j.jar、antlr.jar等包在Spring里,Hiberna...
    99+
    2023-05-30
    spring orm 框架
  • Python之re模块案例详解
    一、正则表达式      re模块是python独有的匹配字符串的模块,该模块中提供的很多功能是基于正则表达式实现的,而正则表达式是对字符串进行模糊匹配,提取自己需要的字符...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作