java 9 模块化最详细讲解

什么是模块化?

是一种软件设计方法,它将应用程序或库分解为独立的、可重用的部分(模块),这些部分可以独立开发、编译和部署。

模块化在包之上提供更高层次的聚合。关键的新语言元素是模块,它是一组专属命名、可重用的相关包、资源和一个模块描述。

模块化是 Jigsaw 项目 的成果,可帮助各级开发人员在构建、维护和改进软件系统(尤其是大型系统)时提高工作效率。

如何使用?

在模块的源代码根目录下新建 module-info.java 文件

module 声明

  • 定义模块的名称。
  • 示例:
module module.a  {
// 其他声明
}

exports...to 声明

  • 指定模块中的包可以被其他模块访问。
  • 可以选择性地指定给特定模块访问(为指定的模块无法使用)。
  • 示例:
module module.a  {
  // exports…to 开放包仅限哪些模块使用
  exports cn.hot.sauce.java.modulea.dog to module.b, module.c;
}

exports 声明

  • 指定模块中的包可以被其他模块访问。
  • 示例:
module module.a  {
 // 开放当前模块的 cat 包
 // 不能跟  exports…to 声明相同的包,否则会有编译报错提示
 exports cn.hot.sauce.java.modulea.cat;
}

opens 声明

  • 允许其他模块访问模块中的非公开 API。
  • 通常用于反射等高级用途,以确保模块的封装性不受破坏。
  • 示例:
module module.a  {
 opens cn.hot.sauce.java.modulea.dog;
}

opens...to 声明

  • 允许其他模块访问模块中的非公开 API。
  • 有选择地将包打开到预先批准的模块列表中。
  • 示例:
module module.a  {
  //开放 dog 包仅限 modulea、b 两个模块通过反射调用
  opens cn.hot.sauce.java.modulea.dog to module.b, module.c;
}

requires 声明

  • 指定模块依赖于其他模块。
  • 静态依赖表示在编译时必须可用的模块。如果一个模块被声明为 requires static,那么它必须在模块图中所有其他模块之前加载。
  • 动态依赖表示在运行时可能需要的模块。
  • 示例:
module module.c {
    //当一个模块被加载时,它依赖的所有模块(不带 static 的 requires 声明)将在运行时按需加载。
    //通途:通常用于声明那些在运行时才需要的模块依赖。
    requires module.a;
    
    //当一个模块被加载时,它依赖的所有静态模块(带有 static 的 requires 声明)将在编译时确定,并且在模块加载时一同加载。
    //用途:通常用于声明那些在编译时就需要的模块依赖,比如日志框架、配置框架等。
    requires static module.b;
}

uses 声明

  • 指定模块使用的服务提供者(SPI)接口。
  • 示例:
module module.a {
    uses cn.hot.sauce.java.modulea.dog.DogServiceI;
}

provides 声明

  • 指定模块提供的服务实现。
  • 通常与 uses 配合使用。
  • 示例:
module module.a {
    provides cn.hot.sauce.java.modulea.dog.DogServiceI with cn.hot.sauce.java.modulea.dog.DogServiceImpl;
}

read 声明

  • 从 Java 11 开始,允许模块读取另一个模块中未导出的包。
  • 未导出的包是指那些没有通过 exports 声明导出的包。
  • 这有助于向后兼容性,允许模块访问旧代码中的未导出包。
  • 假设你有一个模块 com.example.mylib,其中包含一个未导出的包 com.example.mylib.internal,并且有一个模块 com.example.myapp 需要访问这个未导出的包。在 com.example.myapp 的 module-info.java 文件中,可以添加以下声明:
module com.example.myapp {
    // reads 声明后面直接跟的是未导出包的名称。
    reads com.example.mylib.internal;
}

模块化跟Maven导入Jar有什么区别?

模块化 (Java 9+)

模块化是 Java 9 及更高版本引入的一个重要特性,它改变了 Java 应用程序的组织方式,提供了一种更加强大和精细的依赖管理和封装机制。

  1. 模块定义:
    1. 模块由 module-info.java 文件定义,其中声明了模块的名称、导出的包、依赖的其他模块等信息。
    2. 模块可以控制其包的可见性,只允许特定的模块访问它们。
  2. 模块路径:
    1. 类路径的概念被模块路径取代。
    2. 开发者可以通过 -p 或 --module-path 参数指定模块路径。
  3. 模块间依赖:
    1. 模块可以声明对其他模块的依赖关系。
    2. 依赖关系明确后,模块系统会自动处理模块间的依赖加载顺序。
  4. 封装性:
    1. 模块可以显式地导出它们的包给其他特定模块,而不是默认所有包都对外可见。
    2. 这提供了更好的封装性和安全性。
  5. 标准库模块化:
    1. Java 9 的标准库已经被重构为一组模块,每个模块对应一组相关的功能。
  6. 工具支持:
    1. IDEs 如 IntelliJ IDEA 和 Eclipse 提供了对 Java 9 模块系统的支持。

Maven 导入 Jar 包

Maven 是一个流行的 Java 项目管理和构建工具,它提供了一种标准化的方式来管理项目依赖、构建过程和生命周期。

  1. 依赖管理:
    1. Maven 使用 POM (Project Object Model) 文件来管理项目的依赖关系。
    2. 依赖可以通过 Maven 的仓库系统自动下载。
  2. 构建过程:
    1. Maven 定义了一系列的构建生命周期和插件,可以自动化构建过程。
    2. Maven 插件可以执行各种任务,如编译源代码、运行测试、打包项目等。
  3. 项目结构:
    1. Maven 项目遵循标准的目录结构,这有助于统一项目布局和简化构建过程。
  4. 构建产物:
    1. Maven 可以生成各种类型的构建产物,如 JAR 包、WAR 包等。
    2. Maven 还支持多模块项目,可以将大型项目拆分成多个子模块进行管理。
  5. 版本控制:
    1. Maven 使用版本号来管理依赖,可以确保项目使用特定版本的库。

模块化与 Maven 的关系

尽管模块化和 Maven 解决的问题不同,但它们可以很好地协同工作:

  1. Maven 与模块化:
    1. Maven 可以生成符合模块化规范的 JAR 文件。
    2. Maven 的插件(如 maven-jar-plugin)支持生成包含 module-info.class 文件的 JAR 包,该文件是从 module-info.java 编译而来。
  2. 依赖管理:
    1. Maven 可以管理模块间的依赖关系,并自动下载所需的模块。
    2. Maven 生成的 JAR 包可以作为模块使用,通过 requires 声明来指定依赖。
  3. 构建过程:
    1. Maven 可以配置构建过程以生成模块化的 JAR 包。
    2. Maven 插件可以生成符合模块化要求的构建产物。

总结

  • 模块化 是 Java 9 及以后版本提供的特性,它提供了一种更高级别的封装和依赖管理机制。
  • Maven 是一个构建工具,它帮助管理项目的依赖、构建过程和生命周期。
  • 两者结合 可以利用 Maven 自动化构建模块化的 Java 应用程序,同时利用模块化提供的封装性和依赖管理优势。
  • Maven依赖包有传递性,例如:a-->b-->c a引用了日志组件后,b、c模块都无需再引入日志组件可以直接使用
  • 模块化不具备传递性,例如:a-->b-->c
    • 模块 c 不能直接访问模块 a 的内容,因为它只引用了模块 b。
    • 如果模块 b 导出了模块 a 的包或打开了模块 a 的包给模块 c,那么模块 c 可以间接访问这些包中的内容。
    • 模块化设计的核心原则之一就是封装性,因此默认情况下模块 c 无法访问模块 a 的未导出内容。

通过这种方式,模块化和 Maven 在 Java 开发中各自发挥着重要作用,并且可以相互补充,帮助开发者构建高质量的 Java 应用程序。

  • 21
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值