JDK的模块化之Overview
Posted 顧棟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK的模块化之Overview相关的知识,希望对你有一定的参考价值。
JDK的模块化一之Overview
文章目录
最近 Spring官宣 Spring Boot 3.0开始不再支持jdk1.8,最低要求JDK17,随打算对JDK之间的主要变化特性中的JDK的模块化,系统的学习一下。
Spring-Boot-3.0.0-M1-Release-Notes
背景
在JDK9开始发布的一个关键特性Java平台模块系统,代号为Project Jigsaw——为Java SE 9引入了一个全新的概念。
截止JDK9之前,JDK有以下的几个问题
-
源文件过大
对于一些小型设备来说,jdk中的jar文件太大了,比如
rt.jar
,还有src.zip
,tools.jar
等等。 -
JDK过大
JDK太大了,众多的功能都糅合在一起,就不利于这使得缩小到小型设备有点困难。
-
缺乏强封装性
在当前的Java系统中没有真正强大的封装,因为公共访问修饰符太开放了——每个人都可以访问它。因为公众太开放了,所以在访问一些像sun这样的内部关键api时没有任何限制。例如*,.internal.,因为用户也可以访问内部api。这使得安全性成为一个大问题。
-
难以支持最小耦合
众多的功能都糅合在一起,对于不使用的功能无法分离出去。
目标
为了解决上述的问题,为JPMS的设定了下列主要目标
-
Reliable configuration
通过配置更显式地声明模块之间的依赖关系,以便在编译代码和执行代码时都能识别它们。系统读取依赖项列表,以便决定应用程序需要哪些模块。
-
Strong encapsulation
强封装性可以提高安全性,显示导出的包才能被其他模块使用。只有当您的模块显式导出包时,其他模块才可以使用这些包。其他模块要使用原始模块的包,必须显式声明它需要原始模块的功能。
-
A scalable Java platform
采用模块化后,将平台拆分为多个模块,一些不使用的模块可以不引用,可以自定义构建需要的模块。
-
Greater platform integrity
更好的平台完整性。与Java 8及更早的版本不同,Java 9中的强封装使封装的内部api对使用该平台的应用程序隐藏。这很好,因为它增加了安全性,但它可能使将遗留代码迁移到Java 9成为一项困难的任务。
-
Improved performance
通过在特定模块中定位所需的类型并允许知道这一点,JVM优化技术可以更有效地提高应用程序的性能。更多查询官网说明:JSR 376: Java Platform Module System
JDK引入模块化方案
正如您所知,Java 8中的JDK系统太大了,因此语言开发人员决定将JDK划分为一组模块,这些模块可以在编译、构建或运行时组合成各种配置,包括但不限于:
- Java SE全平台、JRE、JDK对应的配置
- 配置的内容大致相当于Java SE 8中定义的每个紧凑概要文件
- 自定义配置,其中只包含一组指定的模块以及这些模块偶尔需要的模块
模块化结构的定义应该明确区分标准模块(其规范受Java Community Process控制)和特定于JDK的模块。它还应该将Java SE平台规范中包含的模块(因此在每个平台实现中都是强制性的)与所有其他模块区分开来。
设计原则
"java."
.标准模块的规范由JCP控制,其名称以字符串’ “java.” '开头。- 所有其他模块都只是JDK的一部分,名称以字符串
" JDK ."
开头。 - 如果一个模块导出的包包含一个类型,而该类型又包含一个公共或受保护成员,而这些成员又引用了来自其他模块的类型,那么第一个模块必须通过
requires transitive
向第二个模块授予隐含的可读性。(这确保了方法调用链接以明显的方式工作。) - 标准模块可以包含标准API包和非标准API包。如果一个标准模块导出一个标准API包,那么该导出可能是合格的;如果一个标准模块导出一个非标准API包,那么该导出必须是合格的。在任何一种情况下,如果一个标准模块导出一个带有限定的包,那么该导出必须是到JDK中模块的某个子集。如果一个标准模块是Java SE模块,即。,被包含在Java SE平台规范中,那么它必须不能导出任何非SE API包,至少不能没有资格。
- 一个标准模块可能依赖于一个或多个非标准模块。它不能赋予任何非标准模块隐含的可读性。如果它是一个Java SE模块,那么它不能授予任何非SE模块隐含的可读性。
- 非标模块不能导出任何标准API包。非标准模块可以赋予标准模块隐含的可读性。
- 原则4和5的一个重要结果是代码,只依赖于Java SE模块将只取决于标准Java SE类型,从而可以移植到所有Java SE平台的实现。
模块化源代码
JEP 201: Modular Source Code:为JDK提出了一种新的源代码布局,在这种布局中,运行时被重新组织为模块,这些模块将增强构建系统,以编译模块并在构建时强制执行模块边界。
模块化运行时映像
JEP 220: Modular Run-Time Images:该特性的主要目标是“重构JDK和JRE运行时映像,以适应模块,并提高性能、安全性和可维护性。
- 为存储的类和资源文件采用以下运行时格式:
- 比传统的JAR格式更节省时间和空间,而传统的JAR格式基于古老的ZIP格式;
- 可以在每个模块的基础上定位和加载类和资源文件;
- 可以存储来自存储来自JDK、库和应用程序模块的类/资源文件;
- 可以进行扩展以适应新的数据类型,例如预计算的JVM数据结构和预编译的Java本地类代码(native classes)。
- 重新构造JDK和JRE运行时映像,明确区分开发人员、部署人员和最终用户可以依赖和在适当时修改的文件,而不是实现内部的文件,这些文件可以在不通知的情况下进行更改。
- 提供受支持的方法来执行常见操作,例如枚举映像中出现的所有类,这些操作目前需要检查运行时映像的内部结构。
- 启用JDK类的选择性“去特权化”,这些类目前被授予了所有的安全权限,但实际上并不需要这些权限。
- 保留行为良好的应用程序的现有行为,即不依赖于JRE和JDK运行时映像的内部方面的应用程序。
封装大多数内部api
JEP 260: Encapsulate Most Internal APIs:该特性的目标是使大多数JDK内部api在默认情况下不可访问,但保留一些关键的、广泛使用的内部api,直到它们的所有或大部分功能都有支持的替换存在为止。
默认情况下封装大多数JDK内部api,使它们在编译时不可访问,并为将来的发行版做好准备,在将来的发行版中,它们在运行时不可访问。确保关键的、广泛使用的内部api没有被封装,这样在它们的所有或大部分功能存在支持的替换之前,它们都是可访问的。
Java平台模块系统
JEP 261: Module System:该特性允许用户创建自己的模块来开发应用程序。
jlink: The Java Linker JAVA链接器
JEP 282: Jlink: The Java Linker:该特性的主要目标是创建一个工具,该工具可以将一组模块及其依赖项组装和优化到JEP 220中定义的自定义运行时映像中;换句话说,构建一个允许用户生成定制的、模块化的运行时映像的工具。
JDK 9 文件夹结构变化
安装JDK 8软件后,您会在Java Home文件夹中看到几个目录,如bin、jre、lib、db等,以及像src.zip和javafx-src.zip这样的文件。
首先要注意的是,JDK 9中的文件夹结构发生了一些变化。
JDK 9文件夹中不包含JRE。在JDK 9中,JRE被集中到一个单独的分发文件夹中,这是多余的,并且包含bin文件夹中已经存在的相同工具;这不必要地增加了JDK的大小。
其他文件和文件夹已被删除并转换为模块。JDK 9软件包含一个名为jmods的新文件夹。此文件夹包含一组Java 9编译模块定义。
根据JEP 261,新的JMOD格式超越了JAR文件,还包括本机代码、配置文件和其他类型的数据,这些数据不自然地(如果根本不适合的话)适合JAR文件。JMOD文件的最终格式是一个悬而未决的问题,但目前它是基于zip文件的。
JDK 模块列表以及版本变化
正如您在前面的图片中看到的,整个JDK被划分为一组模块。因此,您可以在编译、构建或运行时期间根据您的需求将一个集合组装到各种配置中。以下资源提供了模块的完整列表及其描述:
- Java SE 9 modules
- Java SE 10 modules
- Java SE 11 modules LTS
- Java SE 12 modules
- Java SE 13 modules
- Java SE 14 modules
- Java SE 15 modules
- Java SE 16 modules
- Java SE 17 modules LTS
- Java SE 18 modules
- Java SE 19 modules
随着Java的发展,您会注意到不同版本之间模块的变化;一些新模块将被添加,一些已弃用以备将来删除,而另一些模块将被完全删除。
总结
在本文中,您了解了JPMS是什么,包括将模块系统引入Java背后的动机。我已经解释了Java 8和以前版本中设计模块化来解决的问题,并向您展示了可以解决这些问题的工具和特性。最后,强调了Java 8的JDK结构与早期JDK和新的JDK 9配置之间的区别。
附录
Java modularity JEPs and JSRs
Java生态系统中JPMS和模块化的发展,以下是处理Java中该技术开发的jep和jsr:
- JSR 232: Mobile Operational Management
- JSR 277: Java Module System (withdrawn)
- JSR 291: Dynamic Component Support for Java SE
- JSR 294: Improved Modularity Support in the Java Programming Language (withdrawn)
- JEP 200: The Modular JDK
- JEP 201: Modular Source Code
- JEP 220: Modular Run-Time Images
- JEP 260: Encapsulate Most Internal APIs
- JEP 261: Module System
- JEP 275: Modular Java Application Packaging
- JEP 282: Jlink: The Java Linker
- JSR 376: Java Platform Module System
- JSR 379: Java SE 9
以上是关于JDK的模块化之Overview的主要内容,如果未能解决你的问题,请参考以下文章