乐于分享
好东西不私藏

04-Maven 杂记——属性、参数、插件、仓库与实战技巧一网打尽

04-Maven 杂记——属性、参数、插件、仓库与实战技巧一网打尽

这些零散但实用的知识点,往往能解决你开发中的燃眉之急。

前几篇文章我们已经系统地学习了 Maven 的核心概念、依赖管理、继承与聚合。但 Maven 的生态远不止这些,在日常开发中,我们还会遇到很多零散但非常实用的场景:如何在 pom.xml 中引用环境变量?怎样一键跳过测试打包?如何配置多环境打包?本地开发时怎么用 Jetty 或 Tomcat 插件快速运行 Web 项目?

这篇文章就来专门解决这些"杂项"问题,它们虽然不成体系,但每一个都能在关键时刻派上用场。

一、在 POM 中引用属性

在 Maven 的 pom.xml 文件中,可以通过${}占位符引用各种属性值。这是一项非常实用的能力,能让你的 POM 配置更加灵活和动态。

1.1 五类可引用的属性

系统环境变量引用操作系统的环境变量,格式为 ${env.变量名}

<!-- 引用系统的 PATH 环境变量 --><property name="systemPath" value="${env.PATH}" />

Java 系统属性引用 Java 虚拟机提供的系统属性,通过 java.lang.System.getProperties() 能获取到的属性 pom中同样可以引用,格式为 ${java.属性名}

<!-- 引用 Java 安装目录 --><property name="javaHome" value="${java.home}" />

settings.xml 中的属性引用 Maven 本地配置文件 settings.xml 中 <settings> 根元素下的属性,格式为 ${settings.属性名}

<!-- 引用本地仓库地址 --><property name="localRepo" value="${settings.localRepository}" />

pom.xml 中的项目属性引用当前 pom.xml 中 <project> 根元素下的属性,格式为 ${project.属性名}

<!-- 引用当前项目的版本号 --><property name="currentVersion" value="${project.version}" />

自定义 properties 属性在 <properties> 标签中自定义的属性,直接用 ${自定义标签名} 引用。

<properties>  <my.custom.property>some-value</my.custom.property></properties><!-- 使用方式:${my.custom.property} -->

1.2 典型应用场景

统一版本号管理(前文已详细讲过)、根据环境动态配置数据库连接信息、在插件配置中引用项目元数据等。

二、执行 main 方法

有时我们需要在 Maven 构建过程中直接运行某个 Java 类的main方法,比如执行一个数据迁移脚本或代码生成器。

使用exec-maven-plugin可以轻松实现:

# 执行指定全限定名下的java类mvn exec:java -Dexec.mainClass="com.example.tools.DataMigration"

如果需要传递参数给 main 方法,可以用-Dexec.args

mvn exec:java -Dexec.mainClass="com.example.tools.DataMigration" -Dexec.args="arg1 arg2"

这个命令在本地开发调试工具类时非常方便,不需要额外写启动脚本。

三、settings.xml 配置文件

Maven 的settings.xml是全局配置文件,通常放在~/.m2/目录下(用户级配置),也可以在 Maven 安装目录的conf/下找到(全局级配置)。用户级配置会覆盖全局级。

一个最简但实用的 settings.xml 示例:

<settings>  <!-- 本地仓库路径,存放 jar 包 -->  <localRepository>D:/maven-repo</localRepository>  <mirrors>    <!-- 阿里云镜像 -->    <mirror>      <id>nexus-aliyun</id>      <mirrorOf>central</mirrorOf>      <name>Nexus aliyun</name>      <url>http://maven.aliyun.com/nexus/content/groups/public</url>    </mirror>  </mirrors></settings>

建议所有开发人员都配置国内镜像如阿里云镜像,可以大幅提升依赖下载速度。如果是公司内部使用,还可以配置自己的私服地址。

四、常用命令参数

4.1 -D 传入参数

-D 参数用于在命令行动态设置系统属性,最常见的用法是跳过单元测试:

# 打包时跳过单元测试mvn package -Dmaven.test.skip=true

-Dmaven.test.skip=true会跳过测试编译和执行,而-DskipTests只跳过测试执行,但仍然会编译测试代码。前者更彻底。

其他常见-D参数:

参数作用
-Dmaven.test.skip=true跳过所有测试(编译+执行)
-DskipTests跳过测试执行(但仍编译)
-Dmaven.compiler.source=11指定编译源码的 Java 版本
-Dmaven.compiler.target=11指定生成字节码的 Java 版本
-Dfile.encoding=UTF-8指定文件编码

4.2 -P 使用指定的 Profile 配置

-P参数用于激活 Maven Profile,实现多环境打包(如开发环境、测试环境、生产环境使用不同的配置)。

第一步:在 pom.xml 中定义 profiles

<profiles>  <!-- 开发环境 -->  <profile>    <id>dev</id>    <properties>      <env>dev</env>    </properties>    <activation>      <activeByDefault>true</activeByDefault>  <!--未指定环境时,默认打包dev环境-->    </activation>  </profile>  <!-- 测试环境 -->  <profile>    <id>test</id>    <properties>      <env>test</env>    </properties>  </profile>  <!-- 生产环境 -->  <profile>    <id>prod</id>    <properties>      <env>prod</env>    </properties>  </profile></profiles>

第二步:在 build 中引用 profile 的属性

<build>  <!--对于项目资源文件的配置放在build中-->  <resources>    <!-- 根据 profile 环境加载不同的配置文件目录 -->    <resource>      <directory>src/main/resources/${env}</directory>    </resource>    <resource>      <directory>src/main/java</directory>      <includes>        <include>**/*.xml</include>        <include>**/*.properties</include>      </includes>    </resource>  </resources></build>

第三步:使用 -P 激活指定 profile

# 打包生产环境,并跳过测试mvn package -Pprod -Dmaven.test.skip=true

这样你就可以在 src/main/resources/devtestprod 目录下分别放置不同环境的配置文件,打包时会自动选择正确的配置。

五、Web 项目开发插件

在开发 Web 项目时,我们经常需要快速启动一个 Servlet 容器来调试。Maven 提供了 Jetty 和 Tomcat 两种常用插件,可以在本地一键运行。

5.1 Jetty 插件

Jetty 是一个轻量级的 Servlet 容器,启动速度非常快,非常适合开发调试。

<build>  <plugins>    <plugin>      <groupId>org.mortbay.jetty</groupId>      <artifactId>maven-jetty-plugin</artifactId>      <version>6.1.25</version>      <configuration>        <!-- 热部署:每10秒扫描一次文件变化 -->        <scanIntervalSeconds>10</scanIntervalSeconds>        <!-- 应用上下文路径 -->        <contextPath>/myapp</contextPath>        <connectors>          <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">            <!-- 启动端口 -->            <port>9090</port>          </connector>        </connectors>      </configuration>    </plugin>  </plugins></build>

配置完成后,在项目根目录执行:

mvn jetty:run

浏览器访问http://localhost:9090/myapp即可看到应用。

5.2 Tomcat 插件

如果你更习惯使用 Tomcat,也有对应的 Maven 插件:

<build>    <finalName>Demo</finalName>    <plugins>        <plugin>            <groupId>org.apache.tomcat.maven</groupId>            <artifactId>tomcat7-maven-plugin</artifactId>            <version>2.1</version>            <configuration>                <!--启动端口默认:8080-->                <port>8081</port>                <!--项目的站点名,即对外访问路径-->                <path>/test</path>                <!--字符集编码默认:ISO-8859-1-->                <uriEncoding>UTF-8</uriEncoding>                <!--服务器名称-->                <server>tomcat7</server>            </configuration>        </plugin>    </plugins></build>

执行命令:

mvn tomcat7:run

浏览器访问http://localhost:8081/myapp

对比建议:如果只是做普通的 Web 开发调试,Jetty 启动更快、配置更轻量。如果项目最终部署在 Tomcat 上,用 Tomcat 插件可以更贴近生产环境。

六、Maven 仓库配置详解

6.1 私服配置

在公司内部,通常会搭建 Maven 私服(如 Nexus、Artifactory)。私服作为团队内部的统一仓库,有诸多好处:

  • • 降低中央仓库负荷:只要有人下载过的 jar 包,就会缓存在私服上
  • • 节省外网带宽:大量依赖从内网获取,速度快且稳定
  • • 加速构建:内网下载远比外网快
  • • 部署第三方控件:公司内部开发的公共组件可以发布到私服,供其他项目引用
  • • 提高稳定性:即使中央仓库暂时不可用,已缓存的依赖仍然可以正常下载

在项目的 pom.xml 或 settings.xml 中配置私服地址:

<repositories>  <repository>    <id>public</id>    <name>Public Repositories</name>    <url>http://192.168.0.56:8081/content/groups/public/</url>    <snapshots>      <enabled>true</enabled>   <!-- 允许下载 SNAPSHOT 版本 -->    </snapshots>  </repository>  <!-- 第三方专用仓库 -->  <repository>    <id>getui-nexus</id>    <url>http://mvn.gt.igexin.com/nexus/content/repositories/releases/</url>  </repository></repositories>

6.2 公共镜像配置

如果公司没有私服,强烈建议在 settings.xml 中配置国内镜像仓库:

<mirror>  <id>nexus-aliyun</id>  <mirrorOf>central</mirrorOf>  <name>Nexus aliyun</name>  <url>http://maven.aliyun.com/nexus/content/groups/public</url></mirror>

<mirrorOf>central</mirrorOf> 表示该镜像会拦截所有对中央仓库的请求,也就是说所有依赖都会从这个阿里云镜像下载。

七、几个好用的 Debug 技巧

1. 查看 Maven 的最终 POM

mvn help:effective-pom

这个命令会输出当前项目最终生效的 POM,包含从父 POM 继承和 profile 合并后的完整内容。当你怀疑某个配置为什么没有生效时,用它来验证最直接。

2. 查看依赖树

mvn dependency:tree

清晰地展示所有传递依赖,是排查版本冲突的利器。

3. 查看哪些插件绑定了哪些生命周期阶段

mvn help:describe -Dcmd=compile

输出 compile 阶段执行的插件和目标,帮助你理解 Maven 在背后做了什么。

4. 调试 Maven 本身

mvn clean install -X   # 输出完整的调试日志

当构建失败且错误信息不清晰时,-X开启调试模式,能打印出非常详细的执行日志,帮助定位问题。

八、结语

这篇文章涵盖的内容虽然零散,但都是实战中频繁用到的技能:

知识点一句话总结
属性引用${env.JAVA_HOME} 等引用方式让 POM 更灵活
执行 mainmvn exec:java -Dexec.mainClass="..." 快速运行工具类
settings.xml配置本地仓库和镜像,是使用 Maven 的第一步
-D 参数-Dmaven.test.skip=true 跳过测试,加速构建
-P 参数多环境打包,一套代码适配 dev/test/prod多环境
Jetty/Tomcat 插件一条命令启动 Web 项目,告别手动部署
私服配置加速构建、管理内部组件

本文内容参考了B站视频Maven零基础入门教程和 GitHub 开源项目NOTE_Maven 整理的学习笔记,在此向以上作者表示感谢。

链接地址:                                  https://www.bilibili.com/video/BV1TW411g7hP https://github.com/vectorxxxx/NOTE_Maven