关于 java:11. 项目结构、Maven、Gradle 构建系统
一、Java 项目目录结构标准
1.1 Java 项目标准目录结构总览
标准 Java 项目目录结构(以 Maven / Gradle 通用结构为基础):
project-root/
├── src/
│ ├── main/
│ │ ├── java/ # 主业务逻辑代码(核心 Java 类)
│ │ ├── resources/ # 配置资源文件(不包含 Java 类)
│ └── test/
│ ├── java/ # 测试代码(JUnit 单元测试)
│ └── resources/ # 测试时需要用到的资源文件
├── pom.xml # Maven 项目构建文件(Maven 项目)
├── build.gradle # Gradle 项目构建文件(Gradle 项目)
├── README.md # 项目说明文件
├── target/ 或 build/ # 编译输出目录(自动生成)
1.2 各目录详细解释
>1. src/main/java
-
存放 主程序代码(Java 源文件
.java)。 -
按照包结构组织代码,如
com.example.app⇒src/main/java/com/example/app/
示例结构:
src/main/java/
└── com/
└── example/
├── MainApp.java // 启动类
├── service/
│ └── UserService.java
└── model/
└── User.java
>2. src/main/resources
-
存放非代码类资源,如:
-
application.properties/application.yml(Spring Boot 配置) -
日志配置
log4j.xml -
数据库连接配置
jdbc.properties -
模板文件(HTML、freemarker、thymeleaf)
-
示例结构:
src/main/resources/
├── application.yml
├── logback.xml
└── static/
└── index.html
注意:resources 下的文件在构建时会自动加入到 classpath,程序中可以通过ClassLoader.getResourceAsStream() 加载。
>3. src/test/java
-
存放 测试代码,一般用于 JUnit 单元测试或集成测试。
-
包结构应与
src/main/java保持一致,便于测试类与实际类一一对应。
示例:
src/test/java/
└── com/
└── example/
└── service/
└── UserServiceTest.java
>4. src/test/resources
-
测试中需要的配置文件、模拟数据(如 JSON、YAML、mock 文件)等,作用同
main/resources,只在测试中可用。
1.3 项目根目录常见文件解释
| 文件/目录名 | 说明 |
|---|---|
pom.xml |
Maven 配置文件(声明依赖、插件、编译信息等) |
build.gradle |
Gradle 配置文件(同上) |
README.md |
项目说明文件 |
.gitignore |
Git 忽略文件配置 |
.idea/、.vscode/ |
IDE 项目文件 |
target/ 或 build/ |
编译后生成的 .class、.jar 等内容 |
1.4 包结构命名规范
包命名建议以公司域名倒序开头:
com.example.projectname.module
举例结构:
src/main/java/com/example/blog/
├── BlogApplication.java # 主类
├── controller/ # 控制器层(MVC)
├── service/ # 业务逻辑
├── model/ # 实体类(POJO)
├── repository/ # 持久层(DAO)
└── util/ # 工具类
1.5 构建产物目录(自动生成)
对应构建工具:
-
Maven:
target/ -
Gradle:
build/
这些目录在执行 mvn package / gradle build 后自动生成,用于存放:
-
编译后的
.class文件 -
打包后的
.jar/.war -
测试报告、日志、临时文件等
不建议手动修改,通常在 .gitignore 中忽略提交。
1.6 标准结构带来的好处
| 优点 | 说明 |
|---|---|
| 清晰模块分工 | 将业务代码、测试、资源等分类明确 |
| IDE 支持良好 | IntelliJ IDEA / Eclipse 可直接识别 |
| 自动化构建支持 | Maven / Gradle 构建无需额外配置 |
| 测试代码与主逻辑隔离 | 避免生产环境中包含调试/测试代码 |
| 包路径与文件路径映射清晰 | com.xxx 对应目录结构清晰直观 |
1.7 整体结构图示意
project-root/
├── src/
│ ├── main/
│ │ ├── java/ ← Java 源码(包结构)
│ │ └── resources/ ← 配置文件、静态资源
│ └── test/
│ ├── java/ ← 测试源码(JUnit)
│ └── resources/ ← 测试用的配置或模拟数据
├── pom.xml / build.gradle ← 构建工具配置
├── target/ 或 build/ ← 编译输出(自动生成)
├── README.md ← 项目说明
└── .gitignore ← Git 忽略文件
二、Maven
Maven 是 Java 领域中最常用的 构建工具和依赖管理系统,它的核心职责:
| 功能 | 说明 |
|---|---|
| 依赖管理 | 自动下载第三方 jar 包 |
| 构建项目 | 编译、测试、打包、部署 |
| 插件系统 | 支持代码编译、打包、测试、部署等插件 |
| 统一结构 | 使用标准目录结构,便于协作开发 |
2.1 pom.xml 基本结构
Maven 项目的核心配置文件就是 pom.xml(Project Object Model)。
一个最基本的 pom.xml 文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId> <!-- 包名(组织ID) -->
<artifactId>my-app</artifactId> <!-- 项目名 -->
<version>1.0.0</version> <!-- 项目版本 -->
<packaging>jar</packaging> <!-- 打包类型:jar/war/pom -->
</project>
2.2 依赖管理
Maven 依赖通过 <dependencies> 标签引入:
<dependencies>
<!-- 1. 生产依赖 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<!-- 2. 测试依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope> <!-- 只在测试时有效 -->
</dependency>
</dependencies>
常见的 scope 范围含义
| scope | 说明 |
|---|---|
compile |
默认值,主程序运行和编译都需要(最常用) |
test |
测试阶段使用 |
provided |
编译期需要,运行时不包含(如 Servlet API) |
runtime |
编译期不需要,运行时需要 |
system |
本地 jar 包,需要手动指定路径,不推荐使用 |
2.3 依赖仓库与本地缓存
Maven 会自动从远程仓库(默认是 Maven Central)下载 jar 包,并保存在本地仓库中:
-
默认本地仓库路径:
~/.m2/repository/ -
如果依赖未指定版本,Maven 会报错或使用最近一次缓存的版本。
2.4 插件使用(build/plugins)
Maven 构建生命周期依赖插件来实现,比如编译、打包、测试等。
1)编译插件示例(maven-compiler-plugin)
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source> <!-- Java 源码版本 -->
<target>1.8</target> <!-- 字节码版本 -->
</configuration>
</plugin>
</plugins>
</build>
2)打包插件示例(maven-jar-plugin)
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifest>
<mainClass>com.example.MainApp</mainClass> <!-- 指定启动类 -->
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
打包后就可以直接运行:
java -jar target/my-app-1.0.0.jar
3)常用插件列表
| 插件名 | 功能 |
|---|---|
maven-compiler-plugin |
编译 Java 代码 |
maven-jar-plugin |
打包 jar |
maven-surefire-plugin |
运行单元测试 |
maven-dependency-plugin |
依赖分析、复制 |
maven-clean-plugin |
清理 target/ 目录 |
maven-assembly-plugin |
打包带依赖的 fat jar |
2.5 完整 pom.xml 示例
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>myapp</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- 打包插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifest>
<mainClass>com.example.MainApp</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.6 常用 Maven 命令回顾
| 命令 | 说明 |
|---|---|
mvn clean |
清理 target/ |
mvn compile |
编译主程序 |
mvn test |
执行测试类 |
mvn package |
编译 + 打包 |
mvn install |
安装 jar 到本地仓库 |
mvn dependency:tree |
查看依赖树 |
mvn help:effective-pom |
查看完整的有效 POM |
2.7 小结
pom.xml 配置结构:
├── groupId / artifactId / version # 基础身份
├── dependencies # 依赖管理
├── build
│ └── plugins # 构建插件
│ └── compiler / jar / ...
├── properties # 自定义属性(如 Java 版本)
└── profiles(可选) # 多环境配置(开发/测试/生产)
三、Gradle
Gradle 是一个现代化、基于 Groovy/Kotlin DSL 的构建工具,用于:
| 功能 | 描述 |
|---|---|
| 依赖管理 | 类似 Maven,自动引入 jar 包 |
| 构建流程 | 编译、测试、打包、部署 |
| 插件化 | 自定义构建任务,灵活可编程 |
| 性能高 | 支持增量构建和缓存机制 |
| Android 开发 | 官方推荐构建工具 |
3.1 Gradle 项目的基本目录结构
Gradle 项目也遵循和 Maven 相似的标准结构:
project-root/
├── build.gradle ← Gradle 配置文件(核心)
├── settings.gradle ← 项目名与模块声明
├── src/
│ ├── main/
│ │ ├── java/ ← 主程序代码
│ │ └── resources/ ← 资源文件
│ └── test/
│ ├── java/ ← 测试代码
│ └── resources/
├── build/ ← 编译输出目录(自动生成)
3.2 build.gradle 详解(Groovy DSL)
下面是一个典型的 Java 项目的 build.gradle 文件结构:
// 1. 插件(功能)
plugins {
id 'java' // 应用 Java 插件
}
// 2. 项目信息
group = 'com.example' // 组织名称
version = '1.0.0' // 项目版本
// 3. 仓库(依赖从哪儿下)
repositories {
mavenCentral() // 使用中央仓库
}
// 4. 项目依赖
dependencies {
// 编译期依赖(默认)
implementation 'org.apache.commons:commons-lang3:3.12.0'
// 测试期依赖
testImplementation 'junit:junit:4.13.2'
}
// 5. 编译器配置(可选)
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8' // 设置文件编码
}
3.3 依赖导入方式(dependencies 块)
Gradle 支持多种依赖作用范围:
1)常见依赖作用域
| 作用域 | 说明 |
|---|---|
implementation |
编译期 & 运行期依赖(推荐) |
api |
公开依赖(用于库项目) |
compileOnly |
编译期依赖(运行时无效) |
runtimeOnly |
运行期依赖(编译时无效) |
testImplementation |
测试代码专用依赖 |
2)示例依赖导入
dependencies {
// 主程序依赖
implementation 'com.google.guava:guava:32.1.2-jre'
// 只在测试中用
testImplementation 'junit:junit:4.13.2'
// 编译期依赖但不打包
compileOnly 'javax.servlet:servlet-api:2.5'
// 运行期依赖(不参与编译)
runtimeOnly 'mysql:mysql-connector-java:8.0.33'
}
3)本地 jar 文件依赖
dependencies {
implementation files('libs/mylib.jar')
}
4)自定义仓库
repositories {
mavenCentral()
mavenLocal()
maven {
url 'https://repo.spring.io/milestone'
}
}
3.4 常用插件及配置
Gradle 插件添加方式(Groovy DSL):
1)Java 插件(编译 Java 项目)
plugins {
id 'java'
}
2)Application 插件(指定 main 方法并允许运行)
plugins {
id 'application'
}
application {
mainClass = 'com.example.MainApp'
}
执行命令:
gradle run
3.5 常用命令
| 命令 | 功能 |
|---|---|
gradle build |
编译、测试并打包 |
gradle clean |
清理 build 目录 |
gradle test |
执行测试类 |
gradle run |
运行 main 函数(需配置 application 插件) |
gradle dependencies |
查看依赖树 |
gradle --offline |
离线构建 |
3.6 补充:settings.gradle 文件
如果是单模块项目:
rootProject.name = 'myapp'
如果是多模块项目:
rootProject.name = 'parent-project'
include 'module-a', 'module-b'
3.7 完整 build.gradle 示例
plugins {
id 'java'
id 'application'
}
group = 'com.example'
version = '1.0.0'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.apache.commons:commons-lang3:3.12.0'
testImplementation 'junit:junit:4.13.2'
}
application {
mainClass = 'com.example.MainApp'
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
3.8 小结
build.gradle
├── plugins # 插件(java、application等)
├── group/version # 项目信息
├── repositories # 依赖仓库(mavenCentral)
├── dependencies # 项目依赖(impl、testImpl)
├── application # 入口类配置(mainClass)
└── tasks.withType # 编译设置(编码、警告等)
四、单元测试
JUnit 是 Java 中最常用的单元测试框架,用于对 Java 方法进行自动化测试。
它的作用是:
| 功能 | 描述 |
|---|---|
| 自动验证函数行为 | 比如:加法是否正确、异常是否抛出 |
| 回归测试 | 每次修改后自动跑测试,保证老功能没出问题 |
| 提高质量 | 提高代码的健壮性和可维护性 |
| 自动集成 | 可与 Maven/Gradle/CI/CD 集成自动执行测试 |
4.1 JUnit 常见版本
| 版本 | 特点 |
|---|---|
| JUnit 4.x | 最广泛使用,使用注解 @Test |
| JUnit 5.x | 新一代框架,分为 3 个模块(Jupiter、Platform、Vintage),更强大但结构更复杂 |
这里用最常见的 JUnit 4 讲解
4.2 Maven/Gradle 中引入 JUnit
Maven 中添加依赖:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
Gradle 中添加依赖:
dependencies {
testImplementation 'junit:junit:4.13.2'
}
4.3 测试代码目录规范
project-root/
├── src/
│ ├── main/
│ │ └── java/com/example/Calculator.java ← 被测试类
│ └── test/
│ └── java/com/example/CalculatorTest.java ← 测试类
测试类放在 src/test/java,包路径与主类保持一致
4.4 一个最基本的测试类示例
被测试类(Calculator.java):
package com.example;
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int divide(int a, int b) {
return a / b; // 可能抛出异常
}
}
对应测试类(CalculatorTest.java):
package com.example;
import org.junit.Test;
import static org.junit.Assert.*;
public class CalculatorTest {
@Test
public void testAdd() {
Calculator c = new Calculator();
int result = c.add(2, 3);
assertEquals(5, result); // 断言结果为 5
}
@Test(expected = ArithmeticException.class)
public void testDivideByZero() {
Calculator c = new Calculator();
c.divide(10, 0); // 应该抛异常
}
}
4.5 常用断言方法(org.junit.Assert)
| 方法 | 说明 |
|---|---|
assertEquals(expected, actual) |
判断相等(值类型) |
assertTrue(condition) |
判断为 true |
assertFalse(condition) |
判断为 false |
assertNull(obj) |
判断为 null |
assertNotNull(obj) |
判断不为 null |
assertArrayEquals(expected, actual) |
判断数组相等 |
assertThrows(Exception.class, () -> xxx) |
判断抛出异常(JUnit 5) |
@Test(expected = Exception.class) |
判断抛出异常(JUnit 4) |
4.6 测试生命周期注解(JUnit 4)
| 注解 | 说明 |
|---|---|
@Before |
每个测试方法执行前运行(初始化) |
@After |
每个测试方法执行后运行(清理) |
@BeforeClass |
所有测试前执行一次(必须是 static) |
@AfterClass |
所有测试后执行一次(必须是 static) |
@Test |
表示该方法是测试方法 |
示例:
@Before
public void setUp() {
System.out.println("每次测试前初始化");
}
@After
public void tearDown() {
System.out.println("每次测试后清理");
}
4.7 如何运行测试
方式 1:命令行运行
- Maven:
mvn test
- Gradle:
gradle test
方式 2:IDEA 中运行
- 右键点击测试类或方法 → Run
>测试结果展示
测试通过 ✔ :绿色
测试失败 ✘ :红色(IDE 会显示期望值与实际值差异)
4.8 使用测试套件(Test Suite)
当有很多测试类时,可以用 @RunWith 和 @SuiteClasses 组织一个测试集合:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
CalculatorTest.class,
OtherTest.class
})
public class AllTests {
// 空类,仅用于组合多个测试
}
4.9 小结
测试类结构
├── Calculator.java ← 生产类
├── CalculatorTest.java ← 测试类
│ ├── @Test ← 测试函数
│ ├── assertEquals 等 ← 断言
│ ├── @Before / @After ← 生命周期钩子
├── 测试运行方式:mvn test / gradle test / IDE
五、Java 项目运行流程
一个标准 Java 项目的运行流程,大致可以总结为以下 5 步:
1. 确定主类(含 main 方法入口)
2. 编译源代码(.java → .class)
3. 加载依赖(jar 包、本地类)
4. 构建 ClassPath(类路径)
5. JVM 调用 main() 执行程序
5.1 主类(程序入口)
> 什么是主类?
主类是包含 public static void main(String[] args) 方法的类。
public class MainApp {
public static void main(String[] args) {
System.out.println("Hello, Java!");
}
}
-
main 方法是 Java 应用程序的入口点
-
它必须是
public static修饰,接收String[]作为参数
> 运行方式
-
通过 IDE(右键 → Run
MainApp.main()) -
命令行方式:
javac MainApp.java # 编译成 class 文件
java MainApp # 运行,执行 main 方法
5.2 模块(module)
1)模块在标准项目中的含义
在非模块化(传统)项目中,“模块”通常指:
-
项目中的一个子系统(如
user,order,common模块) -
独立的包结构 + 代码目录
例如:
com.example.user
com.example.payment
2)Java 9+ 模块化系统
Java 9 引入了正式的模块系统(module-info.java),但并不是所有项目都使用。
示例:
module com.example.myapp {
requires java.sql;
exports com.example.myapp.api;
}
初学阶段可以不接触 Java Module System(复杂度较高)
5.3 依赖(第三方/内部)
> 什么是依赖?
-
Java 项目中调用的 不是你写的类(外部库、jar 包),就是依赖。
-
如:Spring、Guava、Jackson、JDBC Driver
> 依赖加载方式
| 来源 | 加载方式 |
|---|---|
本地 .class 文件 |
自动加载进内存 |
本地 .jar 包 |
JVM 通过 classpath 加载 |
| 远程依赖(Maven/Gradle) | 会先下载 → 缓存到本地 .m2 或 .gradle 仓库,然后加入构建路径 |
示例依赖:使用 commons-lang3
import org.apache.commons.lang3.StringUtils;
String str = "abc";
System.out.println(StringUtils.isNotEmpty(str));
这段代码依赖了 Apache 的 commons-lang3 库,需要添加:
-
Maven:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
-
Gradle:
implementation 'org.apache.commons:commons-lang3:3.12.0'
5.4 ClassPath 与类加载
> ClassPath 是什么?
-
ClassPath 是 JVM 在运行时查找
.class文件的路径。 -
含义类似 Python 的 sys.path、Linux 的 PATH。
可以通过命令查看:
java -cp target/classes:libs/* com.example.MainApp
> 类加载器(ClassLoader)作用
JVM 使用以下几种类加载器:
| 类加载器 | 作用 |
|---|---|
| BootstrapClassLoader | 加载核心类(rt.jar) |
| ExtensionClassLoader | 加载扩展库(lib/ext) |
| AppClassLoader | 加载我们自己的类 |
| 自定义 ClassLoader | 特殊用途(框架、热部署) |
5.5 Java 程序执行流程详解图
启动 JVM → 找到入口类 main() → 加载依赖(jar)→ 创建 ClassLoader → 执行方法
图解:
+------------------+
| java MainApp |
+--------+---------+
|
v
+------------------------+
| 加载 MainApp.class |
+------------------------+
|
v
+--------------------------+
| 初始化依赖类(StringUtils)|
+--------------------------+
|
v
+-------------------+
| 执行 main() |
| 打印输出 |
+-------------------+
5.6 打包运行流程(.jar)
Maven 打包命令:
mvn clean package
会在 target/ 目录生成 xxx.jar
设置 mainClass 打包运行:
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.example.MainApp</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
运行 jar:
java -jar target/myapp-1.0.0.jar
5.7 实践建议
-
使用 Maven 或 Gradle 来管理依赖和构建流程
-
主类必须有
main()且所在包正确(IDEA 会自动识别) -
每个模块职责明确(如 service、controller、model)
-
合理组织目录结构,遵循
src/main/java标准
5.8 小结
Main Class(main 方法)
↓
编译为 .class
↓
查找依赖(内部类 + 外部 jar)
↓
由 JVM 的类加载器加载进内存
↓
执行 main()
↓
运行中的堆/栈/方法栈执行逻辑
更多推荐

所有评论(0)