一、生命周期与插件
1.1 三套生命周期
Maven 有三套相互独立的生命周期:clean、default、site。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ┌─────────────────────────────────────────────┐ │ Maven 三套生命周期 │ ├─────────────────────────────────────────────┤ │ │ │ Clean Lifecycle(清理生命周期) │ │ pre-clean → clean → post-clean │ │ │ │ Default Lifecycle(构建生命周期) │ │ validate → compile → test → package │ │ → verify → install → deploy │ │ │ │ Site Lifecycle(站点生命周期) │ │ pre-site → site → post-site → site-deploy │ │ │ └─────────────────────────────────────────────┘
|
1.2 Clean 生命周期
| 阶段 |
说明 |
pre-clean |
清理前的准备工作 |
clean |
清理 target 目录 |
post-clean |
清理后的收尾工作 |
1.3 Default 生命周期(核心)
| 阶段 |
说明 |
validate |
验证项目结构是否正确 |
initialize |
初始化构建状态 |
generate-sources |
生成源代码 |
process-resources |
处理资源文件(复制到 target) |
compile |
编译源代码 |
process-classes |
处理编译后的文件 |
generate-test-sources |
生成测试源代码 |
process-test-resources |
处理测试资源文件 |
test-compile |
编译测试代码 |
test |
运行单元测试 |
prepare-package |
打包前的准备工作 |
package |
打包(JAR/WAR) |
verify |
验证打包结果 |
install |
安装到本地仓库 |
deploy |
部署到远程仓库 |
1 2 3 4 5 6 7 8 9
| mvn compile mvn test mvn package mvn install mvn deploy
mvn clean package
|
1.4 Site 生命周期
| 阶段 |
说明 |
pre-site |
生成站点前的准备工作 |
site |
生成项目站点文档 |
post-site |
生成站点后的收尾工作 |
site-deploy |
发布站点到服务器 |
1.5 插件(Plugins)
Maven 的核心功能通过插件实现,插件绑定到生命周期的各个阶段。
常用插件:
| 插件 |
说明 |
绑定阶段 |
maven-compiler-plugin |
编译 Java 源代码 |
compile |
maven-surefire-plugin |
执行单元测试 |
test |
maven-jar-plugin |
打包 JAR |
package |
maven-war-plugin |
打包 WAR |
package |
maven-install-plugin |
安装到本地仓库 |
install |
maven-deploy-plugin |
部署到远程仓库 |
deploy |
maven-clean-plugin |
清理 target |
clean |
maven-resources-plugin |
处理资源文件 |
process-resources |
maven-shade-plugin |
打包可执行 JAR(包含依赖) |
package |
maven-assembly-plugin |
自定义打包 |
package |
插件配置示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>17</source> <target>17</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.1.2</version> <configuration> <testFailureIgnore>true</testFailureIgnore> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.3.0</version> <configuration> <archive> <manifest> <mainClass>com.example.Application</mainClass> <addClasspath>true</addClasspath> </manifest> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.5.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.example.Application</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build>
|
二、多模块项目
2.1 多模块项目结构
1 2 3 4 5 6 7 8 9 10
| my-project/ ├── pom.xml # 父 POM ├── common/ # 公共模块 │ └── pom.xml ├── api/ # API 模块 │ └── pom.xml ├── service/ # 服务模块 │ └── pom.xml └── web/ # Web 模块 └── pom.xml
|
2.2 聚合与继承
聚合(Aggregation):将多个模块聚合到一起构建。
继承(Inheritance):子模块继承父模块的配置。
1 2 3 4 5 6 7 8 9 10 11 12 13
| 聚合:父 POM 通过 <modules> 聚合子模块 继承:子 POM 通过 <parent> 继承父 POM
父 POM ├── modules(聚合) │ ├── common │ ├── api │ ├── service │ └── web └── 配置(继承) ├── dependencyManagement ├── pluginManagement └── properties
|
2.3 父 POM 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| <?xml version="1.0" encoding="UTF-8"?> <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>my-project</artifactId> <version>1.0.0</version> <packaging>pom</packaging> <name>My Project</name> <description>多模块项目父 POM</description> <modules> <module>common</module> <module>api</module> <module>service</module> <module>web</module> </modules> <properties> <java.version>17</java.version> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.boot.version>3.2.0</spring.boot.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring.boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.example</groupId> <artifactId>common</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>com.example</groupId> <artifactId>api</artifactId> <version>${project.version}</version> </dependency> </dependencies> </dependencyManagement> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin> </plugins> </pluginManagement> </build> </project>
|
2.4 子模块 POM 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| <?xml version="1.0" encoding="UTF-8"?> <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> <parent> <groupId>com.example</groupId> <artifactId>my-project</artifactId> <version>1.0.0</version> </parent> <artifactId>service</artifactId> <packaging>jar</packaging> <name>Service Module</name> <description>服务模块</description> <dependencies> <dependency> <groupId>com.example</groupId> <artifactId>common</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> </plugin> </plugins> </build> </project>
|
2.5 模块间依赖
1 2 3 4 5 6 7 8 9 10
| 依赖关系:
web(Web 层) └── service(服务层) └── api(API 层) └── common(公共层)
web 依赖 service service 依赖 api api 依赖 common
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <dependencies> <dependency> <groupId>com.example</groupId> <artifactId>service</artifactId> </dependency> </dependencies>
<dependencies> <dependency> <groupId>com.example</groupId> <artifactId>api</artifactId> </dependency> </dependencies>
<dependencies> <dependency> <groupId>com.example</groupId> <artifactId>common</artifactId> </dependency> </dependencies>
|
2.6 多模块构建命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| mvn clean install
mvn clean install -pl api,service
mvn clean install -pl web -am
mvn clean install -pl common -amd
|
三、构建配置
3.1 资源配置
资源文件过滤:在资源文件中使用占位符,构建时替换为实际值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <includes> <include>**/*.properties</include> <include>**/*.yml</include> <include>**/*.xml</include> </includes> </resource> </resources> <testResources> <testResource> <directory>src/test/resources</directory> <filtering>true</filtering> </testResource> </testResources> </build>
|
资源文件中使用占位符:
1 2 3 4 5
| app.name=${project.name} app.version=${project.version} app.encoding=${project.build.sourceEncoding} build.time=${maven.build.timestamp}
|
构建后自动替换:
1 2 3 4 5
| app.name=My Project app.version=1.0.0 app.encoding=UTF-8 build.time=2024-11-09T10:30:00Z
|
3.2 Profile 多环境配置
使用 <profiles> 定义不同环境的配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <profiles> <profile> <id>dev</id> <properties> <env>dev</env> <db.url>jdbc:mysql://localhost:3306/dev_db</db.url> <db.username>dev_user</db.username> <db.password>dev_pass</db.password> </properties> <activation> <activeByDefault>true</activeByDefault> </activation> </profile> <profile> <id>test</id> <properties> <env>test</env> <db.url>jdbc:mysql://test.example.com:3306/test_db</db.url> <db.username>test_user</db.username> <db.password>test_pass</db.password> </properties> </profile> <profile> <id>prod</id> <properties> <env>prod</env> <db.url>jdbc:mysql://prod.example.com:3306/prod_db</db.url> <db.username>prod_user</db.username> <db.password>prod_pass</db.password> </properties> </profile> </profiles>
|
application.properties 使用环境变量:
1 2 3 4 5
| spring.profiles.active=${env} spring.datasource.url=${db.url} spring.datasource.username=${db.username} spring.datasource.password=${db.password}
|
激活 Profile 的方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| mvn clean package -P test
mvn clean package -P dev,prod
<activation> <activeByDefault>true</activeByDefault> </activation>
|
3.3 Profile 配置不同环境的资源文件
1 2 3 4 5
| src/main/resources/ ├── application.yml # 公共配置 ├── application-dev.yml # 开发环境配置 ├── application-test.yml # 测试环境配置 └── application-prod.yml # 生产环境配置
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <profiles> <profile> <id>dev</id> <build> <resources> <resource> <directory>src/main/resources</directory> <excludes> <exclude>application-prod.yml</exclude> </excludes> </resource> </resources> </build> </profile> <profile> <id>prod</id> <build> <resources> <resource> <directory>src/main/resources</directory> <excludes> <exclude>application-dev.yml</exclude> </excludes> </resource> </resources> </build> </profile> </profiles>
|
四、高级技巧
4.1 自定义 Maven Archetype
创建 Archetype 模板项目:
1 2 3 4 5 6
| mvn archetype:create-from-project
cd target/generated-sources/archetype mvn install
|
使用自定义 Archetype:
1 2 3 4 5 6 7
| mvn archetype:generate \ -DarchetypeGroupId=com.example \ -DarchetypeArtifactId=my-archetype \ -DarchetypeVersion=1.0.0 \ -DgroupId=com.example \ -DartifactId=my-new-project \ -Dversion=1.0.0
|
4.2 自定义 Maven 插件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package com.example.maven.plugin;
import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter;
@Mojo(name = "hello") public class HelloMojo extends AbstractMojo { @Parameter(property = "name", defaultValue = "Maven") private String name; public void execute() throws MojoExecutionException { getLog().info("Hello, " + name + "!"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <packaging>maven-plugin</packaging>
<dependencies> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-plugin-api</artifactId> <version>3.9.5</version> </dependency> <dependency> <groupId>org.apache.maven.plugin-tools</groupId> <artifactId>maven-plugin-annotations</artifactId> <version>3.13.0</version> <scope>provided</scope> </dependency> </dependencies>
|
使用自定义插件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <build> <plugins> <plugin> <groupId>com.example</groupId> <artifactId>hello-maven-plugin</artifactId> <version>1.0.0</version> <configuration> <name>World</name> </configuration> <executions> <execution> <phase>compile</phase> <goals> <goal>hello</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
|
4.3 Maven Wrapper
Maven Wrapper 允许在没有安装 Maven 的机器上构建项目。
1 2 3 4 5 6 7 8 9 10
| mvn wrapper:wrapper
.mvn/wrapper/ ├── maven-wrapper.jar ├── maven-wrapper.properties └── MavenWrapperDownloader.java mvnw mvnw.cmd
|
使用 Maven Wrapper 构建:
1 2 3 4 5
| ./mvnw clean package
mvnw.cmd clean package
|
4.4 常见问题与解决方案
问题1:依赖下载失败
1 2 3 4 5 6 7 8
| mvn dependency:purge-local-repository
mvn clean install -U
rm -rf ~/.m2/repository/org/example
|
问题2:版本冲突
1 2 3 4 5 6 7
| mvn dependency:tree
mvn dependency:tree -Dverbose
|
问题3:构建速度慢
问题4:编译报错
1 2 3 4 5 6 7 8 9 10
| <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> </properties>
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
|
五、最佳实践
5.1 项目结构规范
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| project/ ├── pom.xml ├── README.md ├── .gitignore ├── docs/ # 项目文档 ├── scripts/ # 构建脚本 ├── src/ │ ├── main/ │ │ ├── java/ │ │ └── resources/ │ └── test/ │ ├── java/ │ └── resources/ └── target/
|
5.2 版本管理规范
1 2 3 4 5 6 7 8 9 10 11
| 主版本.次版本.修订版
主版本:重大变更,不兼容的 API 修改 次版本:新增功能,向下兼容 修订版:Bug 修复,向下兼容
示例: 1.0.0 初始版本 1.0.1 Bug 修复 1.1.0 新增功能 2.0.0 重大版本更新
|
5.3 settings.xml 最佳配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <settings> <localRepository>D:/maven/repository</localRepository> <mirrors> <mirror> <id>aliyun</id> <url>https://maven.aliyun.com/repository/public</url> <mirrorOf>central</mirrorOf> </mirror> </mirrors> <servers> <server> <id>my-nexus</id> <username>${env.NEXUS_USER}</username> <password>${env.NEXUS_PASSWORD}</password> </server> </servers> <profiles> <profile> <id>my-profile</id> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> </properties> </profile> </profiles> <activeProfiles> <activeProfile>my-profile</activeProfile> </activeProfiles> </settings>
|
💡 小结:本章深入讲解了 Maven 的生命周期机制(Clean、Default、Site 三套生命周期)、常用插件配置与自定义、多模块项目的聚合与继承、Profile 多环境配置、资源文件过滤等高级特性。掌握这些内容,可以应对企业级项目的复杂构建需求,实现标准化、自动化的项目构建流程。