Maven 基本使用
简介
Maven是专门用于管理和构建Java项目的工具,它的主要功能有:
- 提供了一套标准化的项目结构
- 提供了一套标准化的构建流程(编译,测试,打包,发布……)
- 提供了一套依赖管理机制
官网:http://maven.apache.org/ (opens new window)
项目结构
# Maven仓库
分类
本地仓库: 自己计算机上的一个目录
**中央仓库:**由Maven团队维护的全球唯一的仓库
地址:https://repo1.maven.org/maven2/ (opens new window)
**远程仓库(私服):**一般由公司团队搭建的私有仓库
当项目中使用坐标引入对应依赖jar包后,首先会查找本地仓库中是否有对应的jar包:
- 如果有,则在项目直接引用;
- 如果没有,则去中央仓库中下载对应的jar包到本地仓库。
还可以搭建远程仓库,将来jar包的查找顺序则变为:
本地仓库->远程仓库->中央仓库
配置本地仓库: 修改 conf/settings.xml 中53行的 <localRepository> 为一个指定目录
<localRepository>本地仓库路径</localRepository>
配置阿里云私服: 修改 conf/settings.xml 中146行的 <mirrors>标签,为其添加如下子标签:
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
2
3
4
5
配置JDK版本: Maven默认使用的是JDK1.5的版本。 在187行的<profiles>标签添加:
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
2
3
4
5
6
7
8
9
10
11
12
# IDEA配置与创建Maven
指定maven地址,idea默认会使用内置的maven
如果汉字乱码可以进行如下设置
-DarchetypeCatalog=internal -Dfile.encoding=GBK
创建Maven项目
# Maven坐标
maven坐标导入快捷键:alt+insert
maven jar包检索网站:https://mvnrepository.com/ (opens new window)
Maven 坐标主要组成
- groupId:定义当前Maven项目隶属组织名称(通常是域名反写,例如:cn.kk)
- artifactId:定义当前Maven项目名称(通常是模块名称,例如 order-service、goods-service)
- version:定义当前项目版本号,如果是开发中的工程通常后面会添加SNAPSHOT
- 以上三项本质上代表三级目录,groupid有可能代表一级或多级目录
- scope:依赖范围
# 依赖范围
| classpath范围 | 理解为 |
|---|---|
| 编译类路径 | 只有main目录下源代码起作用 |
| 测试类路径 | 只有test目录下起作用 |
| 运行时类路径 | 在运行的时候起作用, 可以理解为会打包最终的工程中,target目录下起作用 |
| 依赖范围 | 编译classpath | 测试classpath | 运行classpath | 例子 |
|---|---|---|---|---|
| compile默认 | Y | Y | Y | log4j |
| test | - | Y | - | Junit |
| provided | Y | Y | - | servlet-api |
| runtime | - | Y | Y | jdbc驱动 |
| system | Y | Y | - | 存储在本地的jar包 |
| import | 引入DependencyManagement |
# Maven常用命令
| 命令 | 说明 |
|---|---|
| clean | 删除target目录 |
| compile | 编译main目录 |
| test | 执行test目录 |
| package | 打包到target目录下 |
| install | 安装到本地仓库中 |
| validate | 验证项目是正确的并且所有的信息是可用的 |
| deploy | 在构建环境中完成,复制最终部署到远程库。 |
# Maven的环境变量配置
用于DOS命令行执行Maven命令
# Maven的生命周期
Maven 对项目构建的生命周期划分为3套
- clean:清理工作
- default:核心工作,例如编译,测试,打包,安装等
- site:产生报告,发布站点等

- validate(校验) 校验项目是否正确并且所有必要的信息可以完成项目的构建过程。
- initialize(初始化) 初始化构建状态,比如设置属性值。
- generate-sources(生成源代码) 生成包含在编译阶段中的任何源代码。
- process-sources(处理源代码) 处理源代码,比如说,过滤任意值。
- generate-resources(生成资源文件) 生成将会包含在项目包中的资源文件。
- process-resources (处理资源文件) 复制和处理资源到目标目录,为打包阶段最好准备。
- compile(编译) 编译项目的源代码。
- process-classes(处理类文件) 处理编译生成的文件,比如说对Java class文件做字节码改善优化。
- generate-test-sources(生成测试源代码) 生成包含在编译阶段中的任何测试源代码。
- process-test-sources(处理测试源代码) 处理测试源代码,比如说,过滤任意值。
- generate-test-resources(生成测试资源文件) 为测试创建资源文件。
- process-test-resources(处理测试资源文件) 复制和处理测试资源到目标目录。
- test-compile(编译测试源码) 编译测试源代码到测试目标目录.
- process-test-classes(处理测试类文件) 处理测试源码编译生成的文件。
- test(测试) 使用合适的单元测试框架运行测试(Juint是其中之一)。
- prepare-package(准备打包) 在实际打包之前,执行任何的必要的操作为打包做准备。
- package(打包) 将编译后的代码打包成可分发格式的文件,比如JAR、WAR或者EAR文件。
- pre-integration-test(集成测试前) 在执行集成测试前进行必要的动作。比如说,搭建需要的环境。
- integration-test(集成测试) 处理和部署项目到可以运行集成测试环境中。
- post-integration-test(集成测试后) 在执行集成测试完成后进行必要的动作。比如说,清理集成测试环境。
- verify (验证) 运行任意的检查来验证项目包有效且达到质量标准。
- install(安装) 安装项目包到本地仓库,这样项目包可以用作其他本地项目的依赖。
- deploy(部署) 将最终的项目包复制到远程仓库中与其他开发者和项目共享。
# 复制Maven模块
复制一份后修改文件夹名、iml文件名以及pom文件中下图标识的位置
# 依赖传递
概念:某个项目依赖了另一个项目,另一个项目中jar包会不会传递到这个项目中来
面试题
- 项目A依赖junit,依赖范围是test,项目B依赖项目A,问: 项目B对junit是否有依赖? 没有
- 项目A依赖junit,依赖范围是compile,项目B依赖项目A,问: 项目B对junit是否有依赖? 有
- 项目A依赖junit,依赖范围是provided,项目B依赖项目A,问: 项目B对junit是否有依赖? 没有
- 项目A依赖junit,依赖范围是runtime,项目B依赖项目A,问: 项目B对junit是否有依赖? 有
**依赖范围:**compile, runtime 在运行时中起作用中范围会产生依赖传递
依赖可选与依赖排除
| 依赖配置 | 配置元素 |
|---|---|
| 可选 | <optional>true</optional> |
| 排除 | <exclusions><exclusion>坐标没有version</exclusion></exclusions> |
# 依赖可选
前提是会产生依赖传递的两种情况下:
- A项目依赖了junit
- B项目依赖了A项目
- 根据依赖传递特性,默认情况下B项目会依赖junit
- 我们可以在A项目通过可选依赖,让B项目不能依赖junit
配置方式
在A项目的依赖配置中,通过optional子标签进行配置。它有两个取值:
- true:是可选依赖,不进行依赖传递
- false:默认值,进行依赖传递。
我是A项目,由我决定要不要给你,我的地盘我做主
步骤
- 创建A项目,依赖于junit
- 创建B项目,依赖于项目A
- 在项目A中指定optional为true
- 查看项目B的依赖情况
# 依赖排除
- A项目依赖了junit
- B项目依赖了A项目
- 根据依赖传递特性,默认情况下B项目会依赖junit
- 我们可以在B项目通过排除依赖,配置B项目不依赖junit
配置步骤
通过在B项目中配置 exclusions标签进行配置
- 在依赖A项目下的version标签下编写exclusions
- exclusions中每个exclusion是一个要排除的jar包
- 只需指定groupId和artifactId就可以了,不用指定version版本
你给我就要,我不是很没面子?我来决定要不要
示例
<?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.itheima</groupId>
<artifactId>day51_02_A</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
<!-- 依赖可选,取值是true或false,这个包不会传递下去,我要决定给不给 -->
<!--<optional>true</optional>-->
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
</project>
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
<?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.itheima</groupId>
<artifactId>day51_03_B</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--依赖于项目A-->
<dependency>
<groupId>com.itheima</groupId>
<artifactId>day51_02_A</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 依赖排除,我来决定要不要 -->
<exclusions>
<!-- 可以设置多个 -->
<exclusion>
<!-- 要写排除的坐标,不用写version -->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
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
# 依赖冲突
| 依赖冲突的三种情况 | 依赖如何处理的 |
|---|---|
| 两个直接依赖 | 以下面配置的为准 |
| 一个直接依赖一个间接依赖 | 以直接为准 |
| 两个间接依赖 | 以上面配置的为准 |
情况一:两个直接依赖
<dependencies>
<!--默认是compile,会产生依赖传递-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
2
3
4
5
6
7
8
9
10
11
12
13
14
**结论:**会以下面配置的为准
情况二:一个直接依赖一个间接依赖
A项目依赖junit4.12,B项目依赖junit4.11,B项目依赖于A项目,B项目使用哪个版本的junit?
结论:以直接依赖为准
情况三:两个间接依赖
- spring-aop 5.2.0间接依赖了spring-core和spring-beans
- spring-tx 4.2.8间接依赖了spring-core和spring-beans
<!-- 两个间接依赖spring-core包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.2.8.RELEASE</version>
</dependency>
2
3
4
5
6
7
8
9
10
11
12
**结论:**以上面配置为准
# 多环境配置
介绍
maven提供配置多种环境的设定,帮助开发者使用过程中快速切换环境
# 步骤
- 创建的maven工程,复制jdbc.properties到resources目录下

- 修改jdbc.properties中的jdbc.url=${jdbc.url}
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=${jdbc.url}
jdbc.username=root
jdbc.password=root
2
3
4
- 在pom.xml中profiles下配置三个不同的环境:开发,生产,测试
- 在profile的properties中分别指定不同的jdbc.url属性值
- 分别选择不同的profile
- 指定resource的目录地址和开启替换的参数
<?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.itheima</groupId>
<artifactId>multi-env</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 定义多个开发环境 -->
<profiles>
<!-- 1.开发环境 -->
<profile>
<!-- 开发环境的唯一标识 -->
<id>env_dev</id>
<!-- 定义不同的属性 -->
<properties>
<jdbc.url>jdbc:mysql://127.0.0.1:3306/ssm</jdbc.url>
</properties>
<!-- 设置默认开启 -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!-- 2. 生产环境 -->
<profile>
<!-- 开发环境的唯一标识 -->
<id>env_pro</id>
<!-- 定义不同的属性 -->
<properties>
<jdbc.url>jdbc:mysql://127.2.2.2:3306/ssm</jdbc.url>
</properties>
</profile>
<!-- 3. 测试环境 -->
<profile>
<!-- 开发环境的唯一标识 -->
<id>env_test</id>
<!-- 定义不同的属性 -->
<properties>
<jdbc.url>jdbc:mysql://127.3.3.3:3306/ssm</jdbc.url>
</properties>
</profile>
</profiles>
<build>
<resources>
<!-- 指定资源的配置 -->
<resource>
<!-- 必须指定resource所在的目录 -->
<directory>${basedir}/src/main/resources</directory>
<!-- 指定是否替换 -->
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
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
- 运行package命令,查看target中的jar包中jdbc.properties中的url是否不同


- 也可以使用命令行方式执行
mvn 指令 –P 环境定义id

#
继承与聚合
# 继承
**子模块继承于父模块:**配置在子模块/工程中
作用
- 抽取所有项目公用的配置和插件,子项目继承父项目,父项目的公用的配置就可以直接使用了
- 依赖管理:锁定当前项目中各个子项目依赖的版本
子项目的配置
在子工程中声明其父工程坐标与对应的位置
# 聚合
父类块聚合所有子类块
**作用:**配置在父工程中,聚合用于快速构建maven工程,一次性构建多个项目/模块。
制作方式:
- 创建一个空模块,打包类型定义为pom

- 定义当前模块进行构建操作时关联的其他模块名称

注意事项:参与聚合操作的模块最终执行顺序与模块间的依赖关系有关,与配置顺序无关
子项目的pom.xml文件:可以看到继承于父模块的信息
- 包含parent标签:指定父模块的坐标
- 包含当前模块的坐标信息
# 继承和聚合的作用

主要的两个作用:
1.继承:子工程可以继承父工程中所有配置的jar包,子工程无需再次配置,父工程使用dependencies元素配置
2.版本锁定:父工程使用dependencyManagement元素配置,声明当前工程需要哪些jar包,并且锁定版本号。子工程需要的时候再进行配置,不用指定jar包的版本号
# 项目开发的三种不同实现方式
方式一:传统开发
将这些业务集中在1个web项目中, 缺点是代码量大, 业务插拔不方便 。
方式二:分模块开发
模块化开发业务清晰, 维护方便, 业务插拔较简单, 缺点是各模块间 仍然存在依赖
方式三:微服务
将各个业务拆分成多个独立的系统
# 分模块开发


# 常用依赖坐标
| groupId | artifactId | 描述 | scope |
|---|---|---|---|
| org.springframework | spring-context | spring核心包 | |
| org.springframework | spring-test | spring测试包 | |
| org.springframework | spring-web | spring-web包 | |
| org.springframework | spring-webmvc | spring-web核心 | |
| org.springframework | spring-tx | spring事务控制 | |
| org.springframework | spring-jdbc | spring-jdbc驱动包 | |
| org.aspectj | aspectjweaver | AOP切入点表达式依赖 | |
| mysql | mysql-connector-java | mysql数据库驱动 | runtime |
| org.mybatis | mybatis | mybatis框架 | |
| c3p0 | c3p0 | 数据库连接池 | |
| com.alibaba | druid | 数据库连接池 | |
| org.apache.logging.log4j | log4j | 日志打印 | |
| javax.servlet | javax.servlet-api | Servlet | provide |
| javax.servlet.jsp | javax.servlet.jsp-api | JSP | provide |
| taglibs | standard (jstl1.2包含,可省略) | JSTL | |
| jstl | jstl | ||
| com.fasterxml.jackson.core | jackson-core | json相关 | |
| com.fasterxml.jackson.core | jackson-databind | ||
| com.fasterxml.jackson.core | jackson-annotations | ||
| commons-fileupload | commons-fileupload | 文件上传 | |
| commons-io | commons-io | IO流工具 | |
| commons-logging | commons-logging | 日志工具 | |
| commons-beanutils | commons-beanutils | 实体类封装工具类 | |
| org.projectlombok | lombok | 小辣椒 |