实战演练JDK的模块化机制

实战演练JDK的模块化机制

--楼兰

带你聊最纯粹的Java

​ 你发任你发,我用Java8。你用的JDK到什么版本了?很多开源框架都已经开始陆续升级JDK版本了。你对于JDK8往后陆陆续续更新的这些版本有什么感觉吗?

​ 很多人会说其实并没有太多的感觉。JDK的新版本不断推出一些不痛不痒的新特性,但是基于JDK向下兼容的设计,只要我不关注这些花里胡哨的新特性,那么不管哪个版本的JDK,我都可以当做JDK8来用。

​ 但是,其实,从JDK8往后,有一个机制,你是不得不了解的。因为这个机制,如果在你的项目中不启用还好。一旦启用了,会让你所有的业务代码必须进行一次脱胎换骨的变化。这个机制,就是自JDK9之后的模块化机制JPMS。


一、什么是模块化?


​ 我们写的Java应用,都是以Jar包的形式发布的,所以对于Jar包,你一定习以为常。但是,如果你有一天打开一下JDK9以后的版本在你本地的安装目录,你会发现,JDK中那些熟悉的jar包,完全不见了。取而代之的是一些jmod文件。

在这里插入图片描述

​ 甚至在熟悉的IDEA里,JDK的包下也不再是一个个Jar包,而变成了一个个与这些jmod文件对应的模块。

在这里插入图片描述

​ 这些jmod文件是什么呢?

​ 其实这些jmod文件可以认为是一种特殊的jar包。JMOD设计为在编译时间和链接时间使用,但不在运行时使用。你可以简单的理解为,这些jmod文件像jar包一样打包了class文件。但是你不能用java -cp或者java -m等机制使用这些jmod文件。

​ 这就是Java的模块化机制的根基。从JDK8之后,整个JDK就已经用模块化的方式进行了重组。例如,安装JDK 17后,可以使用java --list-modules查看所有的系统模块。

在这里插入图片描述

​ 甚至,JDK和JRE的关系,也已经发生了变化。在新版本的JDK中,应用程序可以只选择自己所需要的模块,打造一个自己定制的JRE,而不再需要引入JDK庞大的后台功能。

​ 比如,我们如果只需要使用java.base模块中的一些基本功能,那么随时可以用以下指令打包出一个可以在服务器上运行的JRE:

jlink -p $JAVA_HOME/jmods --add-modules java.base --output basejre

​ 这个basejre就可以像安装JDK一样,部署到服务器上运行。也可以基于这个JRE,运行Java程序。只不过,这个JRE中只包含了java.base模块中的这些类。像JDBC这样的其他模块的功能,就没法使用。


二、实战理解jmod


​ 这种模块化机制既然是从JDK底层开始推出的,那么自然也可以运用到开发过程中。只不过,这种模块化机制对于很多传统的项目来说,还是有很多问题。因此,在应用中并没有严格铺开。

​ 例如,你可以找一个现有的项目,将JDK版本升级到17后,就可以在项目中某个模块的classpath下添加个module-info.java文件。

在这里插入图片描述

​ 但是,只要你在一个模块中添加了这个module-info.java文件。那么很多代码的编译过程,大概率就会出问题。这就是因为一旦启用了模块化机制,那么就需要对模块进行一些完整声明,保证所有应用都是一些独立,且边界明显的模块,而不再是一些零散的jar包了。

​ 这个模块化机制怎么玩呢?接下来楼兰就带你简单玩一玩。

1、声明一个module

​ 引入模块化机制后,应用㤇在每个模块的根目录下创建一个module-info.java文件,用来声明一个模块。在这个文件中,用module关键字,声明了一个模块。例如:

module roy.demomodule{
   
}

​ 这样,当前目录下的所有package下 de代码,都将属于同一个module。module的名字必须全局唯一。至于具体的格式,没有强制要求。不过通常的惯例是类似于包结构,全部用小写,多个单词用.连接。

​ 接下来就需要再roy.module中声明module的一些补充信息。这些补充信息主要包括:

  • 对其他module的依赖关系
  • 当前module对外开放的API
  • 使用和提供的服务

2、require 声明module依赖

​ 在module-info.java中首先要声明当前module需要依赖哪些外部模块。比如,如果你要使用junit,那么除了要在pom.xml中引入junit对应的依赖外,还需要在module-info.java中添加配置,否则项目编译就会报错。

requires requires junit;

​ 这里要注意,对于显式声明了module-info.java的模块来说,模块名是显而易见的。但是对于没有声明module-info.java的非模块化jar包来说,默认就会创建具有jar包名称的模块。而这个名称还去掉版本号之后的标准包名。

​ 比如,在demoModule1中,我引入了如下的junit依赖

				<dependency>
       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

roykingw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值