Java 模块化开发:module-info.java 配置与依赖管理

Java 9 引入的模块化系统(JPMS)通过module-info.java文件管理模块声明、依赖关系和访问控制。以下是核心配置要点:

1. 模块声明基础

每个模块需在根目录创建module-info.java,基本结构:

module com.example.mymodule {
    // 依赖声明和导出配置
}

  • 模块名:遵循反向域名规则(如com.example.app
  • 作用域:仅作用于编译时和运行时,不影响源码层级
2. 依赖管理
  • requires指令:声明对其他模块的依赖
    requires java.sql;          // 依赖JDK内置模块
    requires com.example.utils; // 依赖自定义模块
    

  • 限定依赖类型
    requires transitive com.example.core; // 传递依赖(依赖此模块的模块自动获得core)
    requires static lombok;                // 仅编译时依赖
    

3. 包导出与开放
  • exports指令:控制包对外暴露
    exports com.example.api;          // 完全公开
    exports com.example.internal to com.example.test; // 仅对特定模块开放
    

  • opens指令:允许反射访问(如框架需运行时注入)
    opens com.example.model;                 // 完全开放反射
    opens com.example.security to spring.core; // 限定反射范围
    

4. 服务加载机制
  • 服务提供provides + with
    provides com.example.spi.DataService 
        with com.example.service.MySQLService;
    

  • 服务消费uses
    uses com.example.spi.DataService;
    

5. 依赖冲突解决
  • 模块路径:优先于类路径(--module-path替代-classpath
  • 唯一模块原则:同一模块不可重复出现
  • 依赖检查:启动时验证requires是否满足(缺失则报错)

完整示例

模块A(提供工具类)
module-info.java

module com.example.utils {
    exports com.example.utils; // 导出工具包
}

模块B(主应用)
module-info.java

module com.example.app {
    requires transitive com.example.utils; // 传递依赖
    requires java.logging;                // JDK模块依赖
    opens com.example.model to hibernate.core; // 对Hibernate开放反射
}

编译与运行
# 编译模块
javac -d out --module-source-path src $(find src -name "*.java")

# 运行主模块
java --module-path out -m com.example.app/com.example.Main

关键优势

  • 强封装性:禁止意外访问内部API
  • 显式依赖:避免JAR地狱(JAR Hell)
  • 精简运行时:通过jlink生成定制化JRE
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐