Maven由浅入深
1. maven是什么?
maven是一个项目管理工具,它包含了一个项目对象模型,一组标准集合,一个项目生命周期,一个依赖管理系统,和用来运行定义在生命周期阶段中插件目标的逻辑。
2. 安装和运行maven
1. 需要java支持
2. 下载maven
http://maven.apache.org/download.html
3. 安装maven
1. yum安装
wget http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo -O /etc/yum.repos.d/epel-apache-maven.repo
yum install apache-maven -y
2. 下载文件apache-maven-3.6.1-bin.zip
unzip apache-maven-3.6.1-bin.zip
mv apache-maven-3.6.1 /usr/local/maven
cd /usr/local/maven3 && ln -s apache-maven-3.6.1 maven3
在/etc/profile文件中,添加下面的内容
export MAVEN_HOME=/usr/local/maven/maven3
export PATH=$PATH:$MAVEN_HOME/bin
source /etc/profile
4. 验证maven
mvn -v
5. maven安装目录结构
bin/ 包含了运行maven的mvn脚本
boot/ 包含了一个负责创建maven运行所需要的类装载器的jar文件
conf/ 包含了一个全局setting.xml文件
lib/ 有了一个包含maven核心的jar文件
LICENSE 包含了apache maven的软件许可证
NOTICE 包含了一些maven依赖的类库锁需要的通告及权限
README.txt 包含了一些安装指令
6. 用户相关配置和仓库
~/.m2/settting.xml 该文件包含了用户相关的认证,仓库和其它信息的配置,用来自定义maven的行为
~/.m2/repository 该目录是你本地的仓库。当你从远程maven仓库下载依赖的时候,maven在你本地仓库存储了这个依赖的副本
7. 使用maven help插件
help:active-profiles 列出当前构建中活动的profile
help:effective-pom 显示当前构建的实际POM
help:effective-settings 打印出项目的实际settings
help:describe 描述插件的属性
3. Maven配置文件settings.xml详解
1. 文件整体结构
<settings xmlns="http://maven.apache.org/SETTINGS/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0
https://maven.apache.org/xsd/settings-1.1.0.xsd">
<localRepository>本地仓库路径</localRepository>
<interactiveMode>true/false</interactiveMode>
<offline>true/false</offline>
<servers>…</servers>
<mirrors>…</mirrors>
<proxies>…</proxies>
<profiles>…</profiles>
<activeProfiles>…</activeProfiles>
</settings>
2. localRepository本地仓库位置
默认在~/.m2/repository,可以自己修改地址
作用:缓存构建所需的所有依赖,插件,以及它们的元数据,避免重复下载,提高构建速度与稳定性。
<!-- localRepository
| Default: ${user.home}/.m2/repository
<localRepository>/path/to/local/repo</localRepository>
-->
这个配置,默认的~/.m2/repository是生效的,localRepository标签内是被屏蔽的。
如果去掉屏蔽,jenkins需要重启一下,才能生效。
3. interactiveMode
作用:决定maven构建时是否需要人工输入
当interactiveMode为true,Maven构建时允许提示用户输入信息,某些插件可能会弹出询问。
当interactiveMode为false,Maven禁止询问用户,所有任务都必须自动执行,否则失败,常用于CI/CD环境。
4. offline
作用:禁止Maven访问远程仓库,只使用本地仓库进行构建。
当开启offline时:
Maven不会从远程仓库下载依赖
如果依赖在本地仓库不存在,构建直接失败
Maven不会上传构件到远程仓库
5. servers 私服的账号密码
用于上传/下载私库需要认证的私库
<servers>
<server>
<id>nexus-releases</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>nexus-snapshots</id>
<username>admin</username>
<password>admin123</password>
</server>
</servers>
注意:<id>要和pom.xml的<repository>或<distributionManagement>里的id一致
6. mirrors
mirrors是用来替代原仓库的“代理仓库地址映射规则”
当Maven本来要去访问某个仓库,mirrors会强制让Maven访问Nexus代理仓库。
详细解释:
1. maven默认去这里下载视频
https://repo.maven.apache.org/maven2
2. 搭建nexux以后,并创建了一个代理仓库(proxy)或仓库组(group)
http://localhost:8081/repository/maven-public/
3. 我希望所有依赖都不要直接跑外网,而是统一从nexus下载
就需要使用settings.xml的<mirrors>
4. mirrors做的事情是:替换仓库地址
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8081/repository/maven-public/</url>
</mirror>
</mirrors>
mirrorOf="*": 拦截所有仓库
当Maven要访问central,aliyun等仓库时:一律强制走Nexus
url: 你想让maven使用的nexus仓库
5. 模式示意图
Maven(项目) ──────► mirrors 拦截仓库请求
│
└─────► 统一转发到你的 Nexus 代理仓库
mirrors不下载包
不缓存包
不存仓库
它只是一个干预Maven访问目标仓库的规则
6. 为什么要用mirrors
1. Maven默认仓库很慢
2. 公司内网不能访问外网
3. 希望所有项目统一走Nexus
4. 控制依赖版本,权限,安全审计
7. profiles 使用profiles进行私库管理
<profiles>
<profile>
<id>use-nexus</id>
<repositories>
<repository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2</url>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>use-nexus</activeProfile>
</activeProfiles>
<mirrors>
<mirror>
<id>nexus-mirror</id>
<mirrorOf>central</mirrorOf>
<url>http://localhost:8081/repository/maven-public/</url>
</mirror>
</mirrors>
profile id profile名字,用来启用不同配置
mvn clean install -P dev
<repostitories>中的<id> 用来标识该仓库,是仓库本身的名字
主要用于与mirrors进行匹配
8. activeProfiles 启用哪个profile
<activeProfiles> <activeProfile>nexus</activeProfile> </activeProfiles>
4. Maven功能
1. 提供标准化的项目结构和构建生命周期
2. 自动处理项目依赖关系
3. 丰富的插件支持各种构建任务
4. 多模块支持,简化大型项目的管理
5. 中央仓库,访问全球共享的库资源
5. Maven约定配置
| 目录 | 目的 |
|---|---|
| ${basedir} | 存放pom.xml和所有的子目录 |
| ${basedir}/src/main/java | 项目的java源代码 |
| ${basedir}/src/main/resources | 项目的资源,比如说property文件,springmvc.xml |
| ${basedir}/src/test/java | 项目的测试类,比如说Junit代码 |
| ${basedir}/src/test/resources | 测试用的资源 |
| ${basedir}/src/main/webapp/WEB-INF | web应用文件目录,web项目的信息,比如存放web.xml、本地图片、jsp视图页面 |
| ${basedir}/target | 打包输出目录 |
| ${basedir}/target/classes | 编译输出目录 |
| ${basedir}/target/test-classes | 测试编译输出目录 |
| Test.java | Maven只会自动运行符合该命名规则的测试类 |
| ~/.m2/repository | Maven默认的本地仓库目录位置 |
6. Maven第一个项目
1. 创建Maven项目
使用Maven Archetype生成项目
mvn archetype:generate \
-DgroupId=com.example \
-DartifactId=my-first-app \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false
参数说明:
| 参数 | 说明 |
|---|---|
-DgroupId |
组织名(如公司域名倒写) |
-DartifactId |
项目名称(会成为项目文件夹名) |
-DarchetypeArtifactId |
使用的模板(quickstart 是基础 Java 项目) |
-DinteractiveMode=false |
非交互模式(避免手动确认) |
执行后生成的项目结构:
my-first-app/
├── pom.xml # Maven 项目配置文件
├── src/
│ ├── main/ # 主代码目录
│ │ └── java/ # Java 源代码
│ │ └── com/example/App.java # 自动生成的示例类
│ └── test/ # 测试代码目录
│ └── java/ # 测试类
│ └── com/example/AppTest.java # 自动生成的测试类
2. 项目结构解析
pom.xml详解
<project>
<!-- POM 模型版本,固定 4.0.0 -->
<modelVersion>4.0.0</modelVersion>
<!-- 项目坐标(唯一标识) -->
<groupId>com.example</groupId>
<artifactId>my-first-app</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 项目打包方式(默认 jar,也可以是 war、pom 等) -->
<packaging>jar</packaging>
<!-- 项目名称和 URL(可选) -->
<name>my-first-app</name>
<url>http://www.example.com</url>
<!-- 依赖管理 -->
<dependencies>
<!-- JUnit 测试依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope> <!-- 仅用于测试 -->
</dependency>
</dependencies>
</project>
源代码结构
| 目录 | 作用 |
|---|---|
src/main/java |
主 Java 源代码 |
src/main/resources |
配置文件(如 application.properties) |
src/test/java |
测试代码 |
src/test/resources |
测试资源文件 |
3. 构建与运行
常用Maven命令
| 命令 | 作用 |
|---|---|
mvn compile |
编译源代码 |
mvn test |
运行测试 |
mvn package |
打包(生成 .jar 文件) |
mvn install |
安装到本地仓库(供其他项目依赖) |
mvn clean |
清理 target 目录 |
完整构建流程
1. 编译项目
mvn compile
编译后的.class文件会放在target/classes目录
2. 运行测试
mvn test
执行src/test/java下的测试类
测试报告生成在target/surefire-reports
3. 打包
mvn package
生成 target/my-first-app-1.0-SNAPSHOT.jar
4. 运行程序
java -cp target/my-first-app-1.0-SNAPSHOT.jar com.example.App
4. 扩展项目
1. 添加依赖
修改pom.xml
<dependencies>
<!-- 原有 JUnit 依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- 新增 Gson 依赖 -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
</dependency>
</dependencies>
运行mvn compile,Maven会自动下载Gson.
修改主类使用Gson
package com.example;
import com.google.gson.Gson;
public class App {
public static void main(String[] args) {
Gson gson = new Gson();
String json = gson.toJson("Hello Maven with Gson!");
System.out.println(json);
}
}
重新打包并运行
mvn pakage
java -cp target/my-first-app-1.0-SNAPSHOT.jar com.example.App
输出
"Hello Maven with Gson!"
5. 常见问题
1. 依赖下载失败
原因:网络问题或仓库不可用
解决方案:
1. 检查网络连接
2. 配置国内镜像仓库
<!-- 在 settings.xml 或 pom.xml 中配置 -->
<mirror>
<id>aliyun</id>
<url>https://maven.aliyun.com/repository/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
2. 编译版本问题
错误:javac: invalid target release: 11
解决方案:在 pom.xml 中指定 Java 版本:
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
7. Maven POM
1. 基本概念
POM(Project Object Model,项目对象模型)是Maven的核心配置文件,采用xml格式,默认名为pom.xml
POM 是 Maven 工程的基本工作单元,是一个 XML 文件,包含了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。执行任务或目标时,Maven 会在当前目录中查找 POM,获取所需的配置信息,然后执行目标。
2. POM文件基本结构
<project>
<!-- 1. 基础信息 -->
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<!-- 2. 元信息 -->
<name>My Application</name>
<description>A demo project</description>
<url>https://example.com</url>
<!-- 3. 依赖管理 -->
<dependencies>...</dependencies>
<!-- 4. 构建配置 -->
<build>...</build>
<!-- 5. 环境配置 -->
<properties>...</properties>
<repositories>...</repositories>
</project>
1. 基础信息
2. 元信息

3. 依赖管理
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>

4. 构建配置中的插件管理
<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>
</plugins>
</build>
5. 环境配置
1. properties
定义项目中的一些属性变量
<properties>
<java.version>11</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
2. repositories
用于指定仓库配置
<repositories>
<repository>
<id>aliyun</id>
<url>https://maven.aliyun.com/repository/public</url>
</repository>
</repositories>
3. dependencyManagement
用于管理依赖的版本,特别是在多模块项目中。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.9</version>
</dependency>
</dependencies>
</dependencyManagement>
4. profiles
用于定义不同的构建配置,可以根据不同的环境进行构建。
<profiles>
<profile>
<id>development</id>
<properties>
<environment>dev</environment>
</properties>
</profile>
<profile>
<id>production</id>
<properties>
<environment>prod</environment>
</properties>
</profile>
</profiles>
6. 继承和聚合
1. 继承
通过parent元素,一个POM文件可以继承另一个POM文件的配置
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
2. 聚合
通过modules元素,一个POM文件可以管理多个子模块
<modules>
<module>module1</module>
<module>module2</module>
</modules>
3. 完整的POM例子
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>My Application</name>
<description>A demo project</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</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>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
8. 父(Super)POM
父(Super)POM是 Maven 默认的 POM。
所有的 POM 都继承自一个父 POM(无论是否显式定义了这个父 POM)。
父 POM 包含了一些可以被继承的默认设置。因此,当 Maven 发现需要下载 POM 中的 依赖时,它会到 Super POM 中配置的默认仓库 http://repo1.maven.org/maven2 去下载。
Maven 使用 effective pom(Super pom 加上工程自己的配置)来执行相关的目标,它帮助开发者在 pom.xml 中做尽可能少的配置,当然这些配置可以被重写。
1. 查看Super POM默认配置
mvn help:effective-pom
9. Maven构建生命周期
1. 三个标准生命周期
clean: 清理项目
default(或build): 核心构建流程
site: 生成项目文档

2. clean生命周期
clean生命周期负责清理项目的临时文件和目录(主要是target/),包含以下主要阶段:

常用命令:
mvn clean #执行clean阶段(包含pre-clean和clean)
mvn post-clean 执行pre-clean,clean,post-clean三个阶段
3. default生命周期
default生命周期是maven最主要的生命周期,包含项目部署和部署的所有核心不走。

常用命令:
mvn compile # 编译主代码 mvn test # 运行测试 mvn package # 打包(生成target/*.jar) mvn install # 安装到本地仓库(~/.m2/repository) mvn deploy # 部署到远程仓库(需配置distributionManagement)
4. site生命周期
site生命周期用于生成项目站点文档

常用命令:
mvn site # 生成站点(输出在target/site/) mvn site-deploy # 部署站点(需配置site URL)
10. Maven构建配置文件
使用构建配置文件,你可以为不同的环境,比如生产环境和开发环境,定制构建方式。
配置文件在pom.xml文件中使用activeProfiles或者profiles元素指定,并且可以通过方式触发。
1. 构建配置文件的类型

2. 配置文件激活多种方式
使用命令控制台输入显式激活。 通过 maven 设置。 基于环境变量(用户或者系统变量)。 操作系统设置(比如说,Windows系列)。 文件的存在或者缺失。
举例项目结构目录
1. 命令行
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jsoft.test</groupId>
<artifactId>testproject</artifactId>
<packaging>jar</packaging>
<version>0.1-SNAPSHOT</version>
<name>testproject</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>test</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>Using env.test.properties</echo>
<copy file="src/main/resources/env.test.properties" tofile="${project.build.outputDirectory}/env.properties" overwrite="true"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>normal</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>Using env.properties</echo>
<copy file="src/main/resources/env.properties" tofile="${project.build.outputDirectory}/env.properties" overwrite="true"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>prod</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>Using env.prod.properties</echo>
<copy file="src/main/resources/env.prod.properties" tofile="${project.build.outputDirectory}/env.properties" overwrite="true"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
mvn test -Ptest
第一个test为Maven生命周期阶段,第二个test为构建配置文件指定的<id>参数,使用-P来传输
2. 通过Maven配置文件settings.xml
<settings 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/settings-1.0.0.xsd">
...
<activeProfiles>
<activeProfile>test</activeProfile>
</activeProfiles>
</settings>
3. 通过环境变量激活配置文件
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jsoft.test</groupId>
<artifactId>testproject</artifactId>
<packaging>jar</packaging>
<version>0.1-SNAPSHOT</version>
<name>testproject</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>test</id>
<activation>
<property>
<name>env</name>
<value>test</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>Using env.test.properties</echo>
<copy file="src/main/resources/test.txt" tofile="${project.build.outputDirectory}/test.txt" overwrite="true"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>normal</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>Using env.properties</echo>
<copy file="src/main/resources/dev.txt" tofile="${project.build.outputDirectory}/dev.txt" overwrite="true"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>prod</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>Using env.prod.properties</echo>
<copy file="src/main/resources/prod.txt" tofile="${project.build.outputDirectory}/prod.txt" overwrite="true"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
mvn test -Denv=test
4. 通过操作系统激活配置文件
<profile>
<id>test</id>
<activation>
<os>
<name>Windows XP</name>
<family>Windows</family>
<arch>x86</arch>
<version>5.1.2600</version>
</os>
</activation>
</profile>
现在打开命令控制台,跳转到 pom.xml 所在目录,并执行下面的 mvn 命令。不要使用 -P 选项指定 Profile 的名称。Maven 将显示被激活的 test Profile 的结果。
mvn test
5. 通过文件的存在或者缺失激活配置文件
现在使用 activation 元素包含下面的操作系统信息。当 target/generated-sources/axistools/wsdl2java/com/companyname/group 缺失时,test Profile 将会被触发。
<profile>
<id>test</id>
<activation>
<file>
<missing>target/generated-sources/axistools/wsdl2java/
com/companyname/group</missing>
</file>
</activation>
</profile>
mvn test

浙公网安备 33010602011771号