|
| 1 | +--- |
| 2 | +title: Maven最佳实践 |
| 3 | +category: 开发工具 |
| 4 | +head: |
| 5 | + - - meta |
| 6 | + - name: keywords |
| 7 | + content: Maven坐标,Maven仓库,Maven生命周期,Maven多模块管理 |
| 8 | + - - meta |
| 9 | + - name: description |
| 10 | + content: Maven 是一种广泛使用的 Java 项目构建自动化工具。它简化了构建过程并帮助管理依赖关系,使开发人员的工作更轻松。在这篇博文中,我们将讨论一些最佳实践、提示和技巧,以优化我们在项目中对 Maven 的使用并改善我们的开发体验。 |
| 11 | +--- |
| 12 | + |
| 13 | +> 本文由 JavaGuide 翻译并完善,原文地址:<https://medium.com/@AlexanderObregon/maven-best-practices-tips-and-tricks-for-java-developers-438eca03f72b> 。 |
| 14 | +
|
| 15 | +Maven 是一种广泛使用的 Java 项目构建自动化工具。它简化了构建过程并帮助管理依赖关系,使开发人员的工作更轻松。Maven 详细介绍可以参考我写的这篇 [Maven 核心概念总结](./maven-core-concepts.md) 。 |
| 16 | + |
| 17 | +这篇文章不会涉及到 Maven 概念的介绍,主要讨论一些最佳实践、建议和技巧,以优化我们在项目中对 Maven 的使用并改善我们的开发体验。 |
| 18 | + |
| 19 | +## Maven 标准目录结构 |
| 20 | + |
| 21 | +Maven 遵循标准目录结构来保持项目之间的一致性。遵循这种结构可以让其他开发人员更轻松地理解我们的项目。 |
| 22 | + |
| 23 | +Maven 项目的标准目录结构如下: |
| 24 | + |
| 25 | +```groovy |
| 26 | +src / |
| 27 | + main / |
| 28 | + java/ |
| 29 | + resources/ |
| 30 | + test/ java |
| 31 | + / |
| 32 | + resources/ |
| 33 | +pom.xml |
| 34 | +``` |
| 35 | + |
| 36 | +- `src/main/java`:源代码目录 |
| 37 | +- `src/main/resources`:资源文件目录 |
| 38 | +- `src/test/java`:测试代码目录 |
| 39 | +- `src/test/resources`:测试资源文件目录 |
| 40 | + |
| 41 | +这只是一个最简单的 Maven 项目目录示例。实际项目中,我们还会根据项目规范去做进一步的细分。 |
| 42 | + |
| 43 | +## 指定 Maven 编译器插件 |
| 44 | + |
| 45 | +默认情况下,Maven 使用 Java5 编译我们的项目。要使用不同的 JDK 版本,请在 `pom.xml` 文件中配置 Maven 编译器插件。 |
| 46 | + |
| 47 | +例如,如果你想要使用 Java8 来编译你的项目,你可以在`<build>`标签下添加以下的代码片段: |
| 48 | + |
| 49 | +```xml |
| 50 | +<build> |
| 51 | + <plugins> |
| 52 | + <plugin> |
| 53 | + <groupId>org.apache.maven.plugins</groupId> |
| 54 | + <artifactId>maven-compiler-plugin</artifactId> |
| 55 | + <version>3.8.1</version> |
| 56 | + <configuration> |
| 57 | + <source>1.8</source> |
| 58 | + <target>1.8</target> |
| 59 | + </configuration> |
| 60 | + </plugin> |
| 61 | + </plugins> |
| 62 | +</build> |
| 63 | +``` |
| 64 | + |
| 65 | +这样,Maven 就会使用 Java8 的编译器来编译你的项目。如果你想要使用其他版本的 JDK,你只需要修改`<source>`和`<target>`标签的值即可。例如,如果你想要使用 Java11,你可以将它们的值改为 11。 |
| 66 | + |
| 67 | +## 有效管理依赖关系 |
| 68 | + |
| 69 | +Maven 的依赖管理系统是其最强大的功能之一。在顶层 pom 文件中,通过标签 `dependencyManagement` 定义公共的依赖关系,这有助于避免冲突并确保所有模块使用相同版本的依赖项。 |
| 70 | + |
| 71 | +例如,假设我们有一个父模块和两个子模块 A 和 B,我们想要在所有模块中使用 JUnit 5.7.2 作为测试框架。我们可以在父模块的`pom.xml`文件中使用`<dependencyManagement>`标签来定义 JUnit 的版本: |
| 72 | + |
| 73 | +```xml |
| 74 | +<dependencyManagement> |
| 75 | + <dependencies> |
| 76 | + <dependency> |
| 77 | + <groupId>org.junit.jupiter</groupId> |
| 78 | + <artifactId>junit-jupiter</artifactId> |
| 79 | + <version>5.7.2</version> |
| 80 | + <scope>test</scope> |
| 81 | + </dependency> |
| 82 | + </dependencies> |
| 83 | +</dependencyManagement> |
| 84 | +``` |
| 85 | + |
| 86 | +在子模块 A 和 B 的 `pom.xml` 文件中,我们只需要引用 JUnit 的 `groupId` 和 `artifactId` 即可: |
| 87 | + |
| 88 | +```xml |
| 89 | +<dependencies> |
| 90 | + <dependency> |
| 91 | + <groupId>org.junit.jupiter</groupId> |
| 92 | + <artifactId>junit-jupiter</artifactId> |
| 93 | + </dependency> |
| 94 | +</dependencies> |
| 95 | +``` |
| 96 | + |
| 97 | +## 针对不同环境使用配置文件 |
| 98 | + |
| 99 | +Maven 配置文件允许我们配置不同环境的构建设置,例如开发、测试和生产。在 `pom.xml` 文件中定义配置文件并使用命令行参数激活它们: |
| 100 | + |
| 101 | +```xml |
| 102 | +<profiles> |
| 103 | + <profile> |
| 104 | + <id>development</id> |
| 105 | + <activation> |
| 106 | + <activeByDefault>true</activeByDefault> |
| 107 | + </activation> |
| 108 | + <properties> |
| 109 | + <environment>dev</environment> |
| 110 | + </properties> |
| 111 | + </profile> |
| 112 | + <profile> |
| 113 | + <id>production</id> |
| 114 | + <properties> |
| 115 | + <environment>prod</environment> |
| 116 | + </properties> |
| 117 | + </profile> |
| 118 | +</profiles> |
| 119 | +``` |
| 120 | + |
| 121 | +使用命令行激活配置文件: |
| 122 | + |
| 123 | +```bash |
| 124 | +mvn clean install -P production |
| 125 | +``` |
| 126 | + |
| 127 | +## 保持 pom.xml 干净且井然有序 |
| 128 | + |
| 129 | +组织良好的 `pom.xml` 文件更易于维护和理解。以下是维护干净的 `pom.xml` 的一些技巧: |
| 130 | + |
| 131 | +- 将相似的依赖项和插件组合在一起。 |
| 132 | +- 使用注释来描述特定依赖项或插件的用途。 |
| 133 | +- 将插件和依赖项的版本号保留在 `<properties>` 标签内以便于管理。 |
| 134 | + |
| 135 | +```xml |
| 136 | +<properties> |
| 137 | + <junit.version>5.7.0</junit.version> |
| 138 | + <mockito.version>3.9.0</mockito.version> |
| 139 | +</properties> |
| 140 | +``` |
| 141 | + |
| 142 | +## 使用 Maven Wrapper |
| 143 | + |
| 144 | +Maven Wrapper 是一个用于管理和使用 Maven 的工具,它允许在没有预先安装 Maven 的情况下运行和构建 Maven 项目。 |
| 145 | + |
| 146 | +Maven 官方文档是这样介绍 Maven Wrapper 的: |
| 147 | + |
| 148 | +> The Maven Wrapper is an easy way to ensure a user of your Maven build has everything necessary to run your Maven build. |
| 149 | +> |
| 150 | +> Maven Wrapper 是一种简单的方法,可以确保 Maven 构建的用户拥有运行 Maven 构建所需的一切。 |
| 151 | +
|
| 152 | +Maven Wrapper 可以确保构建过程使用正确的 Maven 版本,非常方便。要使用 Maven Wrapper,请在项目目录中运行以下命令: |
| 153 | + |
| 154 | +```bash |
| 155 | +mvn wrapper:wrapper |
| 156 | +``` |
| 157 | + |
| 158 | +此命令会在我们的项目中生成 Maven Wrapper 文件。现在我们可以使用 `./mvnw` (或 Windows 上的 `./mvnw.cmd`)而不是 `mvn` 来执行 Maven 命令。 |
| 159 | + |
| 160 | +## 通过持续集成实现构建自动化 |
| 161 | + |
| 162 | +将 Maven 项目与持续集成 (CI) 系统(例如 Jenkins 或 GitHub Actions)集成,可确保自动构建、测试和部署我们的代码。CI 有助于及早发现问题并在整个团队中提供一致的构建流程。以下是 Maven 项目的简单 GitHub Actions 工作流程示例: |
| 163 | + |
| 164 | +```groovy |
| 165 | +name: Java CI with Maven |
| 166 | +
|
| 167 | +on: [push] |
| 168 | +
|
| 169 | +jobs: |
| 170 | + build: |
| 171 | + runs-on: ubuntu-latest |
| 172 | +
|
| 173 | + steps: |
| 174 | + - name: Checkout code |
| 175 | + uses: actions/checkout@v2 |
| 176 | +
|
| 177 | + - name: Set up JDK 11 |
| 178 | + uses: actions/setup-java@v2 |
| 179 | + with: |
| 180 | + java-version: '11' |
| 181 | + distribution: 'adopt' |
| 182 | +
|
| 183 | + - name: Build with Maven |
| 184 | + run: ./mvnw clean install |
| 185 | +``` |
| 186 | + |
| 187 | +## 利用 Maven 插件获得附加功能 |
| 188 | + |
| 189 | +有许多 Maven 插件可用于扩展 Maven 的功能。一些流行的插件包括(前三个是 Maven 自带的插件,后三个是第三方提供的插件): |
| 190 | + |
| 191 | +- maven-surefire-plugin:配置并执行单元测试。 |
| 192 | +- maven-failsafe-plugin:配置并执行集成测试。 |
| 193 | +- maven-javadoc-plugin:生成 Javadoc 格式的项目文档。 |
| 194 | +- maven-checkstyle-plugin:强制执行编码标准和最佳实践。 |
| 195 | +- jacoco-maven-plugin: 单测覆盖率。 |
| 196 | +- sonar-maven-plugin:分析代码质量。 |
| 197 | +- ...... |
| 198 | + |
| 199 | +jacoco-maven-plugin 使用示例: |
| 200 | + |
| 201 | +```xml |
| 202 | +<build> |
| 203 | + <plugins> |
| 204 | + <plugin> |
| 205 | + <groupId>org.jacoco</groupId> |
| 206 | + <artifactId>jacoco-maven-plugin</artifactId> |
| 207 | + <version>0.8.8</version> |
| 208 | + <executions> |
| 209 | + <execution> |
| 210 | + <goals> |
| 211 | + <goal>prepare-agent</goal> |
| 212 | + </goals> |
| 213 | + </execution> |
| 214 | + <execution> |
| 215 | + <id>generate-code-coverage-report</id> |
| 216 | + <phase>test</phase> |
| 217 | + <goals> |
| 218 | + <goal>report</goal> |
| 219 | + </goals> |
| 220 | + </execution> |
| 221 | + </executions> |
| 222 | + </plugin> |
| 223 | + </plugins> |
| 224 | +</build> |
| 225 | +``` |
| 226 | + |
| 227 | +如果这些已有的插件无法满足我们的需求,我们还可以自定义插件。 |
| 228 | + |
| 229 | +探索可用的插件并在 `pom.xml` 文件中配置它们以增强我们的开发过程。 |
| 230 | + |
| 231 | +## 总结 |
| 232 | + |
| 233 | +Maven 是一个强大的工具,可以简化 Java 项目的构建过程和依赖关系管理。通过遵循这些最佳实践和技巧,我们可以优化 Maven 的使用并改善我们的 Java 开发体验。请记住使用标准目录结构,有效管理依赖关系,利用不同环境的配置文件,并将项目与持续集成系统集成,以确保构建一致。 |
0 commit comments