Maven
0 Maven 简介
Maven是什么?
Maven的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM)
POM(Project Object Model):项目对象模型

Maven的作用
- 项目构建:提供标准的、跨平台的自动化项目构建方式
- 依赖管理:方便快捷的管理项目依赖的资源(jar包),避免资源间的版本冲突问题
- 统一开发结构:提供标准的、统一的项目结构

下载与安装
黑马教程
1 Maven 基础概念
1.1 仓库
仓库用于存储资源,包含各种 jar 包

仓库分类:
- 本地仓库:自己电脑上存储资源的仓库,连接远程仓库获取资源
- 远程仓库:非本机电脑上的仓库,为本地仓库提供资源
- 中央仓库:Maven团队维护,存储所有资源的仓库
- 私服:部门/公司范围内存储资源的仓库,从中央仓库获取资源
私服的作用:
- 保存具有版权的资源,包含购买或自主研发的jar
- 中央仓库中的jar都是开源的,不能存储具有版权的资源
- 一定范围内共享资源,仅对内部开放,不对外共享
坐标
-
什么是坐标?
- Maven中的坐标用于描述仓库中资源的位置
- https://repo1.maven.org/maven2/
-
Maven坐标主要组成
-
groupld:定义当前Maven项目隶属组织名称(通常是域名反写,例如:org.mybatis)
-
artifactld:定义当前Maven项目名称(通常是模块名称,例如CRM、SMS)
-
version:定义当前项目版本号
// packaging:定义该项目的打包方式
-
仓库配置
本地仓库配置
"maven安装路径\apache-maven-3.8.5\conf\settings.xml"修改为自定义路径

远程仓库配置
Maven默认连接的仓库位置
central Central Repository https://repo.maven.apache.org/maven2 default false
默认设置在国外(如下图),不在此处做修改
配置
maven-default-http-blocker
external:http:*
Pseudo repository to mirror external repositories initially using HTTP.
http://0.0.0.0/
true
nexus-aliyun
public
Nexus aliyun
https://maven.aliyun.com/repository/public
用户可以在自己建立的"...\maven\repository" 的maven 目录下新建一个
settings.xml
1.2 第一个Maven项目(手工制作)
Maven工程目录结构
# 使用命令创建
# 打开记事本后缀改为".cmd",内容如下:
mkdir src
mkdir src\main
mkdir src\main\resources
mkdir src\main\java
mkdir src\test
mkdir src\test\resources
mkdir src\test\java
在main 和 test 文件夹下建立com.lee的package ,内容分别为:
// main.com.lee 文件夹下
package com.lee
public class Demo {
public String sayHi(String str) {
System.out.println("Hello " + str);
return "Hello " + str ;
}
}
// test.com.lee 文件夹下
package com.lee
import org.junit.Test;
import org.junit.Assert;
public class DemoTest {
public void testSay() {
Demo d = new Demo();
String ret = d.sayHi("maven");
Assert.assertEquals("Hello maven", ret);
}
}
在src 同级目录下建立pom.xml文件(拷贝其他pom.xml 进行删减)
<?xml version="1.0" encoding="UTF-8"?>
4.0.0
com.lee
project-java
1.0
jar
junit
junit
4.12
web工程目录
Maven项目构建命令
Maven构建命令使用mvn开头,后面添加功能参数,可以一次执行多个命令,使用空格分隔
mvn compile #编译
mvn clean #清理
mvn test #测试
mvn package #打包
mvn install #安装到本地仓库
mvn compile
成功后,会生成一个target 文件夹
mvn clean
清除 target 文件夹
mvn test
? 测试报告在
target\surefire-reports
mvn package
打包
mvn install
安装到本地仓库(目录:group_id\项目名称\版本号)
1.3 第一个Maven项目(IDEA生成)
视频: 黑马教程
博客: IDEA配置Maven
3.8.5 配置成功,但是依赖包不能自动加载,手动加载也不会保存在自定义的本地仓库,会保存在C盘。于是,改为配置3.6.3成功。
tomcat 配置
在 web 项目的pom.xml 文件里加上:
org.apache.tomcat.maven
tomcat7-maven-plugin
2.1

org.apache.tomcat.maven
tomcat7-maven-plugin
2.1
80
/
Web工程项目的pom.xml 解析
<?xml version="1.0" encoding="UTF-8"?>
4.0.0
war
com.lee
web01
1.0-SNAPSHOT
web01 Maven Webapp
http://www.example.com
UTF-8
1.7
1.7
junit
junit
4.11
test
org.apache.tomcat.maven
tomcat7-maven-plugin
2.1
80
/
1.4 依赖管理
依赖配置
依赖指当前项目运行所需的 jar ,一个项目可以设置多个依赖
格式 :
<!--设置当前项目所依赖的所有jax-->
<!-设置具体的依赖-->
<!-依赖所属群组id-->
junit
<!-依赖所属项目id-->
junit
<!-依赖版本号-->
4.12
依赖传递
建立三个项目
log4j
log4j
1.2.12
junit
junit
4.12
log4j
log4j
1.2.13
log4j
log4j
1.2.14
红色为配置的依赖,绿色为依赖传递


直接依赖:在当前项目中通过依赖配置建立的依赖关系
间接依赖:心被资源的资源如果依赖其他资源,当前项目间接依赖其他资源

依赖传递冲突问题
路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高(1度 > 2度)
声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的
特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的(同一个文件中配置两次,第二次为准)

可选依赖
可选依赖指对外隐藏当前所依赖的资源——不透明
optional--> true 不可见 --> false(默认) 可见
junit junit 4.12 true 2--> 3-->c 3(optional true) 2--\ -->c
排除依赖
●排除依赖指主动断开依赖的资源,被排除的资源无需指定版本——不需要
junit
4.12
org.hamerest
hamcrest-core
2--> 3-->c 2(exclusion) 2--\ -->c

注意:
optional 和 exclusion 的操作对象不同
在项目2中,不需要依赖项目3中的
log4j包,但是项目1仍然需要依赖它,也就是说我们需要在项目1中将这个包排除掉,但是又不能影响其他项目对这个包的依赖,使用 exclusionoptional 只允许在当前项目使用,从不往下传递,下游项目要是想使用的话需要自己重新引入
依赖范围
依赖的jar默认情况可以在任何地方使用,可以通过scope标签设定其作用范围
作用范围
主程序范围有效(main文件夹范围内)
测试程序范围有效(test文件夹范围内)
是否参与打包(package指令范围内)
| Scope | 主代码 | 测试代码 | 打包 | 范例 |
|---|---|---|---|---|
| compile(默认) | Y | Y | Y | log4j |
| runtime | Y | jdbc | ||
| test | Y | junit | ||
| provided | Y | Y | servlet-api |
处 compile 不显示外, 其他的scope 类型都会显示出来
当1 配置 2 ,2 配置 3时:
- 当 2 配置 3 的scope类型为compile ,3 对 1 可见
- 当 2 配置 3 的scope类型为test ,3 对 1 不可见
- 当 2 配置 3 的scope类型为provided ,3 对 1 不可见
- 当 2 配置 3 的scope类型为runtime ,3 对 1 可见,scope类型为runtime

依赖范围的传递性


(注:图片来自网络,各有说辞,需要验证)
1.5 生命周期与插件
构建生命周期
Maven对项目构建的生命周期划分为3套
- clean: 清理工作
- default:核心工作,例如编译,测试,打包,部署等
- site:产生报告,发布站点等
clean 生命周期
| pre-clean | 执行一些需要在clean之前完成的工作 |
|---|---|
| clean | 移除所有上一次构建生成的文件 |
| post-clean | 执行一些需要在clean之后立刻完成的工作 |
default 生命周期
| 指令 | 内容 |
|---|---|
| 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(安装) | 安装项目包到本地仓库,这样项目包可以用作其他本地项目的依赖 |
| deplay(部署) | 将最终的项目包复制到远程仓库中与其他开发者和项目共享 |
site 构建生命周期
| pre-site | 执行一些需要在生成站点文档之前完成的工作 |
|---|---|
| site | 生成项目的站点文档 |
| post-site | 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备 |
| site-deploy | 将生成的站点文档部署到特定的服务器上 |
插件
插件与生命周期内的阶段绑定,在执行到对应生命周期时执行对应的插件功能
默认maven在各个生命周期上绑定有预设的功能
通过插件可以自定义其他功能
Maven 官网 --> Maven Plugin --> source
- source : jar is used to bundle the main sources of the project into a jar archive.
- source : test-jar on the other hand, is used to bundle the test sources of the project into a jar archive.
org.apache.maven.plugins
maven-source-plugin
2.2.1
jar
test-jar
generate-test-resources
对java01进行测试,在pom.xml文件中加入上方的代码,点击test可以看到,target 文件夹里多了两个jar 包,是java01 的源代码,需要注意是主程序的源代码,是测试的源代码。
2 Maven 进阶
2.1 分模块开发与设计
工程模块与模块划分

ssm_pojo拆分
- 新建模块
- 拷贝原始项目中对应的相关内容到ssm_pojo模块中
- 实体类(User)
- 配置文件(无)
ssm_dao拆分
- 新建模块
- 拷贝原始项目中对应的相关内容到ssm_dao模块中
- 数据层接口(UserDao)
- 配置文件:保留与数据层相关配置文件(3个)
- 注意:分页插件在配置中与SqlSessionFactoryBean绑定,需要保留
- pom.xml:引入数据层相关坐标即可,删除springmvc相关坐标
- spring
- mybatis
- spring整合mybatis
- mysql
- druid
- pagehelper
- 直接依赖ssm_pojo(对ssm_pojo模块执行install指令,将其安装到本地仓库)
ssm_service拆分
- 新建模块
- 拷贝原始项目中对应的相关内容到ssm_service模块中
- 业务层接口与实现类(UserService、UserServicelmpl)
- 配置文件:保留与数据层相关配置文件(1个)
- pom.xml:引入数据层相关坐标即可,删除springmvc相关坐标
- spring
- junit
- spring 整合junit
- 直接依赖ssm_dao(对ssm_dao模块执行install指令,将其安装到本地仓库)
- 间接依赖ssm_pojo(由ssm_dao模块负责依赖关系的建立)
- 修改service模块spring核心配置文件名,添加模块名称,格式:applicationContext-service.xml
- 修改dao模块spring核心配置文件名,添加模块名称,格式:applicationContext-dao.xml
- 修改单元测试引入的配置文件名称,由单个文件修改为多个文件
ssm_control拆分
- 新建模块(使用webapp模板)
- 拷贝原始项目中对应的相关内容到ssm_controller模块中
- 表现层控制器类与相关设置类(UserController、异常相关……)
- 配置文件:保留与表现层相关配置文件(1个)、服务器相关配置文件(1个)
- pom.xml:引入数据层相关坐标即可,删除springmvc相关坐标
- spring
- springmvc
- jackson
- servlet
- tomcat服务器插件
- 直接依赖ssm_service(对ssm_service模块执行install指令,将其安装到本地仓库)
- 间接依赖ssm_dao、ssm_pojo
- 修改web.xml配置文件中加载spring环境的配置文件名称,使用*通配,加载所有applicationContext-开始的配置文件
2.2 聚合

新键一个不使用框架的新项目ssm删掉 src 文件夹,在pom.xml 文件中加入:
pom
../ssm_pojo
../ssm_dao
../ssm_service
../ssm_codntroller
使用ssm的 compile


packaging 默认为 jar
2.3 继承
模块依赖关系维护

继续在 ssm 的pom.xml 中加入:
...
在其他各工程ssm_*的pom.xml中加入
com.lee
ssm 1.0-SNAPSHOT
../ssm/pom.xml
4.0.0
ssm_pojo
jar
| groupld | 项目组ID,项目坐标的核心元素 |
| version | 项目版本,项目坐标的核心因素 |
| description | 项目的描述信息 |
| organization | 项目的组织信息 |
| inceptionYear | 项目的创始年份 |
| url | 项目的URL地址 |
| developers | 项目的开发者信息 |
| contributors | 项目的贡献者信息 |
| distributionManagement | 项目的部署配置 |
| issueManagement | 项目的缺陷跟踪系统信息 |
| ciManagement | 项目的持续集成系统信息 |
| scm | 项目的版本控制系统信息 |
| malilingLists | 项目的邮件列表信息 |
| properties | 自定义的Maven属性 |
| dependencies | 项目的依赖配置 |
| dependencyManagement | 项目的依赖管理配置 |
| repositories | 项目的仓库配置 |
| build | 包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等 |
| reporting | 包括项目的报告输出目录配置、报告插件配置等 |
继承与聚合辨析
- 作用
- 聚合用于快速构建项目
- 继承用于快速配置
- 相同点:
- 聚合与继承的pom.xml文件打包方式均为pom,可以将两种关系制作到同一个pom文件中
- 聚合与继承均属于设计型模块,并无实际的模块内容
- 不同点:
- 聚合是在当前模块中配置关系,聚合可以感知到参与聚合的模块有哪些
- 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
2.4 属性

// 属性类比java中定义变量
String spring_version = "5.1.9.RELEASE";
System.out.println(spring_version);
1.0-SNAPSHOT
1.2.3
5.1.9
com.lee
project_dependency01
${version}
${group_id}
spring-context
${spring.version}
属性类别
-
自定义属性
-
作用:等同于定义变量,方便统一维护
-
格式:
5.1.9 -
调用格式:
${spring.version}
-
-
内置属性
-
作用:使用 maven 内置属性,快速配置
-
调用格式:
${basedir} ${version}
-
-
Setting属性
-
作用:使用 Maven 配置文件 setting.xml 中的标签属性,用于动态配置
-
调用格式:
${Setting.localRepository}
-
-
Java系统属性
-
作用:读取 java 系统属性
-
调用格式:
${user.home} -
系统属性查询方式:
mvn help:system
-
-
环境变量属性
-
作用:使用 Maven 配置文件 setting.xml 中的标签属性,用于动态配置
-
调用格式:
${env.JAVA_HOME} -
环境变量属性查询方式:
mvn help:system
-
2.5 版本管理
工程版本
- SNAPSHOT(快照版本)
- 项目开发过程中,为方便团队成员合作,解决模块间相互依赖和时时更新的问题,开发者对每个膜块进行构建的时候,输出的临时性版本叫快照版本(测试阶段版本)
- 快照版本会随着开发的进展不断更新
- RELEASE(发布版本)
- 项目开发到进入阶段里程碑后,向团队外部发布较为稳定的版本,这种版本所对应的构件文件是稳定的,即便进行功能的后续开发,也不会改变当前发布版本内容,这种版本称为发布版本
工程版本号约定
约定规范:
<主版本>.<次版本>.<增量版本>.<里程碑版本>
- 主版本:表示项目重大架构的变更,如:spring5相较于spring4的迭代
- 次版本:表示有较大的功能增加和变化,或者全面系统地修复漏洞
- 增量版本:表示有重大漏洞的修复
- 里程碑版本:表明一个版本的里程碑(版本内部)。这样的版本同下一个正式版本相比,相对来说不是很稳定,有待更多的测试
2.6 资源配置
资源配置多文件维护

在pom.xml文件中的 build 标签下加入
...
5.1.9.RELEASE
4.12
jdbc:mysql://127.0.0.1:3306/ssm_db
...
../ssm_dao/src/main/resources
${project.basedir}/src/main/resources
true
${project.basedir}/src/main/resources
true
配置文件引用 pom 属性
-
作用:在任意文件中加载 pom 文件中定义的属性
-
调用格式:
${jdbc.url} -
开启配置文件加载 pom 属性
${project.basedir}/src/main/resources true
2.7 多环境开发配置
在 pom.xml 中创建多环境:
pro_env
jdbc:mysql://127.1.1.1:3306/ssm_db
dep_env
jdbc:mysql://127.2.2.2:3306/ssm_db
定义了不同的环境,在编译安装的时候要选择哪一个环境:

install -P dev_env # 选择 开发环境
install -P pro_env # 选择 生产环境
# 设置默认环境(如下)以后,可直接使用 install 安装默认环境
pro_env
jdbc:mysql://127.1.1.1:3306/ssm_db
true
2.8 跳过测试
install -D skipTests在
pom.xml文件中对插件进行配置maven-surefire-plugin 2.22.1 true **/TestDemo.java ...
2.9 私服

nexus服务器安装与启动
nexus下载地址 网络原因不易下载
下载安装后在安装目录的bin目录下进入cmd输入 nexus /run nexus,等待至如下结果:

进入浏览器输入:localhost:8081

修改端口号
位置:"...\nexus\sonatype-work\nexus3\etc\nexus.properties"
修改后重启
服务器相关设置
安装目录下的bin 目录
仓库分类与手动上传组件

仓库分类
- 宿主仓库hosted
- 保存无法从中央仓库获取的资源
- 自主研发
- 第三方非开源项目
- 保存无法从中央仓库获取的资源
- 代理仓库proxy
- 代理远程仓库,通过nexus访问其他公共仓库,例如中央仓库
- 仓库组group
- 将若干个仓库组成一个群组,简化配置
- 仓库组不能保存资源,属于设计型仓
登录
- 用户名 admin
- 密码存放在:..\nexus\sonatype-work\nexus3
自动要求重置密码
新建仓库
把新建仓库加入到仓库组

图形化界面操作自行探究一下
- 文件上传及删除
- 保存的位置(宿主仓库)
- 资源文件
- 对应坐标
- 设置角色和权限
本地仓库访问私服

- 访问私服的用户名密码不变,资源配置在本地仓库中
- 文件上传/下载会有不同,配置在项目中
lee-releases
admin
*******
lee-snapshots
admin
*******
aliyunmaven
central
阿里云公共仓库
https://maven.aliyun.com/repository/public
nexus-lee
*
nexus-lee
http://localhost:8081/repository/maven-public/
IDEA 访问私服与组件上传
发布配置
pom.xml文件中增加 发布配置管理
lee-releases
http://localhost:8081/repository/lee-releases/
lee-snapshots
http://localhost:8081/repository/lee-snapshots/

测试上传部署

成功

pom文件配置未进行统一整理,详细请参考
资料整理自黑马程序员Maven视频教程














