背景

本文是《Java 后端从小白到大神》修仙系列第十九篇,正式进入Java后端世界,本篇文章主要聊Java基础。若想详细学习请点击 首篇博文,开始学习。

一、模块化是什么?

Java 9 推出的「代码隔离系统」,
用来解决:包访问权限太松、依赖混乱、Jar 冲突、JDK 太臃肿。

核心就两件事:

  1. 我要依赖谁(requires)
  2. 我开放给谁(exports)

二、为什么需要模块化?

Java 以前的问题:

  • 只要同包就能访问,封装不安全
  • 依赖 Jar 全靠猜,容易冲突
  • 大型项目结构混乱

模块化解决:

  • 强封装:不对外开放的包,谁也访问不到
  • 显式依赖:必须声明依赖,不能随便用
  • 清晰边界:模块 = 独立的功能单元

三、核心关键字

1
2
3
4
5
requires      我依赖谁
exports       我开放哪个包
opens         开放反射给框架用
uses          使用服务
provides      提供服务

四、示例代码

Java 9 模块化项目结构。

目录结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
modular-demo/
├── com.a/
│   ├── pom.xml                  # 可选(Maven 项目)
│   └── src/main/java/           # 【必须有】标准源码目录
│       ├── module-info.java     # 模块描述文件
│       └── com/a/service/
│           └── AService.java
└── com.b/
    ├── pom.xml                  # 可选
    └── src/main/java/           # 【必须有】
        ├── module-info.java     # 模块描述文件
        └── com/b/
            └── Main.java

模块 A(提供服务)

  1. module-info.java
1
2
3
module com.a {
    exports com.a.service;  // 对外开放的包
}
  1. com.a.service.AService
1
2
3
4
5
6
7
package com.a.service;

public class AService {
    public void test() {
        System.out.println("我是A模块");
    }
}

模块 B(依赖模块 A)

  1. module-info.java
1
2
3
module com.b {
    requires com.a;  // 依赖A模块
}
  1. com.b.Main
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package com.b;

import com.a.service.AService;

public class Main {
    public static void main(String[] args) {
        AService as = new AService();
        as.test();
    }
}

五、模块化 vs Maven 多模块

5.1 一句话区别

  • Java 9 模块化(JPMS)语言级别,控制代码访问权限、强封装、显式依赖。
  • Maven 多模块构建级别,拆分项目、管理依赖、统一打包、工程化管理。

5.2 核心对比表

维度 Java 9 模块化 (JPMS) Maven 多模块
级别 语言/运行时 项目构建工具
作用 强封装、访问控制、依赖安全 项目拆分、依赖管理、编译打包
生效时机 编译、运行时 构建时
核心文件 module-info.java pom.xml
解决问题 JAR 冲突、封装不安全、类路径混乱 项目庞大、代码混乱、复用困难
企业使用 较少(了解即可) 非常多(必须掌握)

六、Maven 多模块 + Java 模块化 整合示例

一般教真实结构
Maven 多模块(工程拆分) + Java 模块化(权限控制)

6.1 最终目录结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
my-modular-project/
├── pom.xml                   <-- 父pom(pom 打包)
├── com.example.greeting/     <-- 子模块A
│   ├── pom.xml
│   └── src/main/java
│       ├── module-info.java
│       └── com/example/greeting/GreetingService.java
└── com.example.app/          <-- 子模块B
    ├── pom.xml
    └── src/main/java
        ├── module-info.java
        └── com/example/app/Main.java

6.2 父项目 pom.xml

1
2
3
4
5
<packaging>pom</packaging>
<modules>
    <module>com.example.greeting</module>
    <module>com.example.app</module>
</modules>

6.3 模块 A:com.example.greeting

module-info.java

1
2
3
module com.example.greeting {
    exports com.example.greeting;
}

GreetingService.java

1
2
3
4
5
6
package com.example.greeting;
public class GreetingService {
    public String getGreeting() {
        return "Hello, Maven Modules!";
    }
}

6.4 模块 B:com.example.app

module-info.java

1
2
3
module com.example.app {
    requires com.example.greeting;
}

Main.java

1
2
3
4
5
6
7
8
9
package com.example.app;
import com.example.greeting.GreetingService;

public class Main {
    public static void main(String[] args) {
        GreetingService service = new GreetingService();
        System.out.println(service.getGreeting());
    }
}

6.5 运行结果

1
Hello, Maven Modules!

七、总结

  • Java 9 模块化:语言级别的封装与权限隔离
  • Maven 多模块:工程级别的项目拆分与构建管理

实际开发:Maven 多模块为主,Java 模块化了解即可。