Java模块化系统:引领代码革命与性能飞跃

JDK工程结构的问题

在说Java模块化系统之前,先来说说Java9之前的JDK在工程结构上的问题,从JDK本身的问题说起,Java从1996年发布第一版到2017年发布Java9,中间经历了近20年的时间,在这期间发布了无数个大大小小的版本用来支撑新的特性。

在Java新特性越来越丰富的同时,也带来了相应的问题。JDK8是一个广泛使用的版本,我们就以JDK8为例,先来看看目录结构

在JDK8以及之前的版本,我们安装的时候会安装两部分内容

  • JDK(Java Development Kit)主要用于开发者提供了开发工具和环境
  • JRE(Java Runtime Environment)主要提供Java运行时环境

JDK是开发Java应用的完整套装,而JRE则是为了支持已编译的Java程序在任何计算机上运行而设计的环境。JDK内部包含了JRE,以方便开发者在开发的同时也能直接运行和测试他们的代码

在jre/bin目录下有一个rt.jar文件,表示的是runtime,即运行时。JVM会加载这整个文件来支持Java运行时环境,而rt.jar文件的大小已经达到50-60M,也就是说在运行你的Java程序之前,就需要花这么多内存来加载Java运行时环境,我们来看看rt.jar中包含哪些内容

我们使用解压工具打开rt.jar可以清晰的看到,里面包括的内容很全,基本上包括了Java的方方面面,都给你加载进去了。就算你只写一个HelloWord,它也给你加载了Applet、awt等你根本不会用到的东西。现在的服务器和个人电脑随便都是8G、16G以上的内存,对于rt.jar占用的这点内存可能没什么感觉,但在一些对于内存很敏感的领域,Java这种方式就显得不太合理。Java官方可能也意识到了这个问题,所以在Java9的时候推出了Java平台模块系统(Java Platform Module System,JPMS)

Java平台模块系统(Java Platform Module System,JPMS)

JPMS是在Java9发布的,其实从Java7开始官方就在准备JPMS,本来准备在Java8中引入JPMS的,实在是改动太大,到Java9中才正式发布。其实做过开发的都会想的到,模块化相当于要从整体上重构整个系统,结构调整巨大,对于整个系统考验是很大的,这可能也是JPMS从Java7开始准备,直到Java9才发布的原因。

前面我们说过,在Java8及之前的版本中,其实是包括JDK和JRE两个部分的。但从Java9之后,就没有专门的JRE了,因为模块化之后,自己可以选择JVM加载哪些模块,相当于按需加载就行了,你写HelloWord可能只需要一个加载java.base就行了。 下面是JDK11的结构

在JDK安装目录下有一个jmods目录,在该目录下就定义了JDK中各个模块,以.jmod结尾的文件就是JDK中定义的各个模块,我们打开java.base.jmod文件看一下

可以看到在java.baseclass/java/目录中,包括了一些Java基础用到的lang、math、nio等基础包,没有包插applet、awt等不常用的包。 这样按模块化划分之后,一方面可以更好的管理JDK的各个模块,另外一方面对于使用者来说,也不用像旧版JDK那样一股脑把所有的内容加载到JVM中,这样更加合理,也更节省资源。

Java模块化系统以克服当前所存在的局限时,主要设定了两个目标

  • 对JDK本身进行模块化
  • 提供一个应用程序可以使用的模块系统

上面我们已经看到了JDK本身模块化的改造,下面我们就来看看应用程序是如何使用模块系统的

应用程序模块化实现

应用程序实现模块化只需要简单的三步就可以完成

  • 定义模块
  • 导出模块
  • 引用模块

先整体看一下,我们定义了三个模块userModule、OrderModule、GoodsModule,项目的结构如下:

module-info.java文件

module-info.java文件是用来定义模块的,在模块的src目录下定义一个module-info.java文件,内容如下

java 复制代码
module UserModule {
    
}

简单的定义了一个UserModule的模块,里面内容是空的 现在三个模块是独立的,假如在OrderModule中需要使用UserModuler的UserService,直接使用肯定是引用不到的,需要进行exports

exports

如果需要将模块中的内容对外,需要在module-info.java中把相应的包exports出去

java 复制代码
module UserModule {
    exports com.user;
}

如上所示,表示UserModule将com.user包对外提供服务

requires

如果需要引用其他模块的内容,需要先使用requires将模块引用进当前模块,如下

java 复制代码
module OrderModule {
    requires UserModule;
}

如上所示,表示OrderModule引用了UserModule,如此在OrderModule中就可以使用UserModule中exports出来的包

java 复制代码
    public static void main(String[] args) {
        UserService userService = new UserService();
        userService.register();
    }

如上所示,在OrderModule中就可以直接引入UserService了

如果你只想将UserModule开放给GoodsModule,可以这样写

java 复制代码
module UserModule {
    exports com.user to GoodsModule;
}

这样就算OrderModule引用了UserModel,也没办法使用UserService,因为UserModule只开放给GoodsModule了

以上就是一个使用模块化来实现模块之间相关调用的简单例子,当然实际的模块化系统不可能这么简单,此处只起到一个抛转引玉的作用,如果对模块化系统比较感兴趣可以去JDK官网了解详细的信息

模块化的好处

1、强封装性

类和包可以被模块化,只有模块之间声明的接口是对外可见的,提高了代码的封装性,减少了不必要的耦合

2、明确的依赖管理

块之间通过requires声明依赖,明确指出了哪些模块需要哪些其他模块,避免了隐式依赖和类路径冲突

3、运行时性

JVM可以仅加载运行应用程序所需的模块,减少了内存占用,提高了启动速度和运行时性能

4、安全性和隔离

模块边界强化了安全性,限制了代码的访问权限,降低了攻击面

通过模块化,Java开发者可以构建更加健壮、高效且易于维护的大型应用程序

你的项目有用到模块化吗?欢迎给我留言讨论!

相关推荐
怪兽源码22 分钟前
基于SpringBoot的选课调查系统
java·spring boot·后端·选课调查系统
恒悦sunsite29 分钟前
Redis之配置只读账号
java·redis·bootstrap
梦里小白龙34 分钟前
java 通过Minio上传文件
java·开发语言
人道领域35 分钟前
javaWeb从入门到进阶(SpringBoot事务管理及AOP)
java·数据库·mysql
sheji52611 小时前
JSP基于信息安全的读书网站79f9s--程序+源码+数据库+调试部署+开发环境
java·开发语言·数据库·算法
毕设源码-邱学长1 小时前
【开题答辩全过程】以 基于Java Web的电子商务网站的用户行为分析与个性化推荐系统为例,包含答辩的问题和答案
java·开发语言
摇滚侠1 小时前
Java项目教程《尚庭公寓》java项目从开发到部署,技术储备,MybatisPlus、MybatisX
java·开发语言
€8111 小时前
Java入门级教程24——Vert.x的学习
java·开发语言·学习·thymeleaf·数据库操作·vert.x的路由处理机制·datadex实战
Mr_star_galaxy2 小时前
【JAVA】经典图书管理系统的实现
java
昊坤说不出的梦2 小时前
【实战】监控上下文切换及其优化方案
java·后端