ava 模块化系统深度解析——从混乱的Classpath到清晰的模块边界

简介: Java9引入的模块化系统(ProjectJigsaw)是Java平台历史上最重大的结构性变更之一。

Java9引入的模块化系统(ProjectJigsaw)是Java平台历史上最重大的结构性变更之一。它解决了长期困扰Java开发者的两个核心问题:JDK本身的过度膨胀,以及类路径(Classpath)上的JAR地狱。模块化不仅改变了JDK的组织方式,也为大型应用提供了更强的封装性和可伸缩性。
参考:https://oqmyh.cn/category/meirong-zhishi.html

在Java9之前,JDK的运行时镜像(rt.jar)超过60MB,包含数千个类,即使只使用其中一小部分,整个运行时也必须完整加载。模块化将JDK拆分为大约100个模块,应用只需要包含实际使用的模块。jlink工具可以创建自定义运行时镜像,大幅减少内存占用和启动时间,这对容器化部署和云原生应用意义重大。

模块化的核心是module-info.java文件,它声明模块的名称、依赖(requires)、导出包(exports)、开放包(opens,用于反射)、提供服务(provides)和使用服务(uses)。模块系统在编译期和运行期强制执行这些声明,防止意外访问内部API。

强封装是模块化最重要的特性。在传统Java中,public意味着完全公开,模块化引入了“可访问性”的新层次:一个包即使被声明为public,如果模块没有导出该包,其他模块也无法访问。这使API设计者可以真正隐藏实现细节,防止用户依赖内部类。

服务加载机制(ServiceLoader)在模块化时代得到了增强。模块可以使用provides...with...声明服务提供者,使用uses声明服务消费者。模块系统自动将消费者绑定到提供者,无需配置文件。这种松耦合的依赖注入是模块化的最佳实践。
参考:https://npqev.cn/category/xianhua-pinzhong.html

JDK内部API的封装是模块化的直接影响。Java9之前,许多应用依赖sun.misc.Unsafe、sun.reflect等内部API。模块化将这些API封装在非导出包中,访问它们会抛出IllegalAccessError。开发者必须迁移到标准API(如VarHandle、MethodHandles),或使用--add-exports命令行参数临时解封。

模块路径vs类路径:传统类路径是扁平的JAR列表,JVM按顺序搜索。模块路径上的模块支持强封装、可靠配置和服务绑定。传统JAR放在类路径上时,成为“未命名模块”,可以访问所有模块(因为未命名模块读取所有模块),但不能被其他模块访问(除非使用--add-reads)。这种设计允许增量迁移。

自动模块:将传统JAR放在模块路径上但不包含module-info.class,就成为自动模块。自动模块的名称从JAR文件名推断,它导出所有包,并依赖所有其他模块。自动模块是迁移过程中的过渡机制,最终应该为每个JAR添加module-info.java。

多版本JAR:允许同一个JAR包含针对不同Java版本的类。例如,META-INF/versions/9/下的类在Java9+上使用,其他版本使用根目录的类。这使库可以支持模块化,同时保持对旧Java版本的兼容性。

模块化迁移策略:对于大型代码库,一次性迁移是不现实的。推荐的自底向上策略:首先将最底层的库模块化,然后逐步向上迁移。在迁移完成前,可以使用--class-path保留非模块化代码,使用--add-exports和--add-reads解决临时依赖。
参考:https://vrhyh.cn/category/yinshi.html

模块化与依赖注入框架:Spring、Guice等框架大量使用反射。模块化要求被反射访问的包必须被opens(或open整个模块)。框架需要适配模块化,或使用--add-opens参数。Spring从5.1版本开始完全支持模块化。

模块化与测试:测试代码通常与被测代码在不同模块。测试模块需要requires被测模块,并使用opens允许测试框架访问私有成员。JUnit5等测试框架需要对应的模块化适配。

模块化的性能影响:模块解析在启动时执行,开销微乎其微。自定义运行时镜像(jlink)可以显著减少启动时间和内存占用。模块化带来的封装性使JIT编译器可以做更多优化(如内联跨越模块边界的调用),但实际效果取决于应用结构。

模块化的工具支持:Maven从3.5开始支持模块化项目,需要配置maven-compiler-plugin启用模块路径。Gradle从4.6开始支持。IDE(IntelliJ、Eclipse)提供模块描述符编辑器和模块图可视化。

模块化的最大受益者是大型应用和框架。对于小型应用,模块化的收益可能不明显,但值得为了未来可维护性而采用。Java平台本身已经模块化,开发者应尽快适配,避免未来升级受阻。
参考:https://oqmyh.cn

目录
相关文章
|
4月前
|
Web App开发 存储 开发框架
浏览器实际大文件下载解决方案
针对电商短视频业务中高频、大文件下载痛点,本文探讨四种解决方案:浏览器插件批量下载(推荐)、Electron套壳客户端、Web流式压缩打包及传统Blob内存合并。重点分析各方案优劣,推荐插件方案兼顾性能与体验,兼顾兼容性与资源消耗,适用于素材频繁交付场景。
360 0
|
安全 Java
jdk9模块化
本文介绍了JDK 9引入的模块化系统,解释了模块化的概念、好处,包括提高安全性、可维护性和减少冲突及加快启动时间,并举例说明了如何使用module-info.java文件来定义模块依赖和暴露的包。
529 2
|
9月前
|
机器学习/深度学习 人工智能 搜索推荐
文生图关键问题探索
文生图(Text-to-Image Generation)是AIGC的重要方向,近年来模型效果显著提升,受到投资界与研究界高度关注。本文从评测体系、可控生成、个性化模型及高质量数据集四个角度探讨该领域面临的关键问题与研究进展。尽管生成模型如Diffusion Model和Stable Diffusion在效果与效率上突破显著,但在文本理解、生成控制、模型定制及数据质量等方面仍存在挑战。如何建立统一的评价标准、提升生成与文本的一致性、实现个性化定制及构建高质量多语言数据集,是未来研究与应用的关键方向。文生图的发展有望推动人机交互方式变革,成为人工智能迈向“人性化”的重要一步。
|
存储 关系型数据库 数据库
华为数据库openGauss与PostgreSQL使用对比
华为openGauss数据库基于PostgreSQL内核演进,进行了多项增强。密码认证从MD5升级为SHA256;字符串存储中,char(n)、varchar(n)的n由字符改为字节,新增nvarchar2(n)表示字符,最大存储100MB;且将空字符''统一转换为null,提升了数据处理的一致性和安全性。
1226 12
|
前端开发
视觉充电:CSS动画特效,为网站带来动力与活力!(一键复制)
视觉充电:CSS动画特效,为网站带来动力与活力!(一键复制)
|
调度 数据中心 网络架构
PON系统“被动光网络”
PON(Passive Optical Network)是一种光纤接入网架构,由光线路终端(OLT)、光分配网络(ODN)和光网络单元(ONU)组成。OLT位于中心办公室,管理并调度数据传输;ODN是连接OLT和ONU的光纤网络,通过光分配器被动分发信号;ONU位于用户端,接收和转发数据,维护与OLT的同步。
1037 2
|
分布式计算 Java 大数据
java常见的应用场景
java常见的应用场景
1373 2
|
C++
22 C++ - 深拷贝和浅拷贝
22 C++ - 深拷贝和浅拷贝
296 0
解决 kali换源之后签名无效
解决 kali换源之后签名无效
1775 0

热门文章

最新文章