1、下载maven配置环境变量
--官网下载地址
https://maven.apache.org/download.cgi
--解压完成之后,创建MAVEN_HOME配置到bin目录的上一级
MAVEN_HOME:maven安装路径
--在PATH中添加MAVEN_HOME
%MAVEN_HOME%\bin
--打开CMD检测MAVEN是否配置成功
mvn --version
2、maven仓库
maven仓库的分类:
本地仓库
远程仓库:
中央仓库
私服
其他公共库
本地仓库:存储在本地的仓库。maven会将jar包下载并存储到本地仓库。
本地仓库默认地址,无论是Windows还是Linux,在用户的目录
下都有一个.m2/repository/的仓库目录,这就是Maven仓库的默认位置。
自定义本地仓库地址:可修改conf/settings.xml来配置本地仓库的地址。
<!-- localRepository
| The path to the local repository maven will use to store artifacts.
|
| Default: ${user.home}/.m2/repository 默认本地仓库的文职
-->
<localRepository>自定义本地仓库目录</localRepository>
--------------------------------------------------------------------------
远程仓库:
默认的远程仓库就是中央仓库,由apache社区进行维护,中央仓库包含了
绝大多数流行的开源Java构件,以及源码、作者信息、SCM、信息、许可证信息等。
一般来说,简单的Java项目依赖的构件都可以在这里下载到。
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
3、maven核心pom文件
---pom
什么是pom
pom代表项目对象模型,它是Maven中工作的基本组成单位。它是一个XML文件,
始终保存在项目的基本目录中的pom.xml文件中。pom包含的对象是使用maven来构建的,
pom.xml文件包含了项目的各种配置信息,需要特别注意,每个项目都只有一个pom.xml文件。
项目配置信息
project:工程的根标签
modelVersion:pom模型版本,maven2和3只能为4.0.0
groupId:这是工程组的标识。它在一个组织或者项目中通常是唯一的。
artifactId:这是工程的标识。它通常是工程的名称。
version:这是工程的版本号。在 artifact 的仓库中,它用来区分不同的版本
最小pom
<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.xdclass</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
</project>
---super pom
super pom
父(Super)POM是 Maven 默认的 POM。所有的 POM 都继承自一个父 POM(无论是否显式定义了这个父 POM)。
父 POM 包含了一些可以被继承的默认设置。因此,当 Maven 发现需要下载 POM 中的 依赖时,它会到 Super POM 中配置的默认仓库 。
mvn help:effective-pom --查看super pom 配置信息
----依赖配置信息
dependencies --引入所需依赖jar包
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
---- pom继承的父工程
parent
<parent>
<groupId>lmr.class<groupId>
<artifactId>demo-parent</artifactId>
<relativePath>/</relativePath>
<version>1.0</version>
</parent>
groupId: 父项目的组Id标识符
artifactId:父项目的唯一标识符
relativePath:Maven首先在当前项目中找父项目的pom,然后在文件系统的这个位置(relativePath),然后在本地仓库找,再在远程仓库找。
version: 父项目的版本
----modules
有些maven项目会做成多模块的,这个标签用于指定当前项目所包含的所有子模块。
之后对这个项目进行的maven操作,会让所有子模块也进行相同操作。
<modules>
<module>com-a</module>
<module>com-b</module>
<module>com-c</module>
</modules>
----- 常量定义
properties
<properties>
<java.version>1.7</java.version>
<mysql.version>5.6</mysql.version>
</properties>
配置的常量,在pom中使用方式为:${xxxxx}. 案列:${java.version}
--统一依赖的版本,各个子模块使用相同版本避免因版本不同产生错误。
<span>
注意:在父模块中定义后,子模块不会直接使用对应依赖,子模块必须显示指定使用具体的哪个依赖,
在使用依赖的时候可以不加版本号,会引用父模块dependencyManagement中定义依赖的版本号。
若子模块使用依赖是添加了版本号,那么将会以子模块添加版本号的依赖为准。
</span>
dependencyManagement
父项目:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
子项目1:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
子项目2:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
子项目3[指定使用版本号,子项目3将会以此版本依赖为准]:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>5.0</version>
</dependency>
----注意
dependencyManagement与dependencies区别
<span>
dependencies即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承)。
dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。
如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,
才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,
那么会使用子项目中指定的jar版本。
</span>
4、maven生命周期
----生命周期
Maven的生命周期就是对所有的构建过程进行抽象和统一。
包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有的构建步骤。
maven的三个构建生命周期
* clean 执行步骤顺序
* pre-clean 执行一些清理前需要完成的工作
* clean 清理上一次构建生成的文件
* post-clean 执行一些清理后需要完成的工作
* default
* validate:编译验证工程是否正确
* compile:编译项目的源代码
* test:使用合适的单元测试框架来测试已编译的源代码。
* package:把已编译的代码打包成可以发布的格式,比如jar或者war
* verify:运行所有检查,验证包是否有效
* install:安装到maven本地仓库
* deploy:部署到远程的仓库,使得其他开发者或者工程可以共享
* Site
5、maven常用命令
常用命令
* mvn validate 验证项目是否正确
* mvn package maven打包
* mvn generate-sources 生成源代码
* mvn compile 编译
* mvn test-compile 编译测试代码
* mvn test 运行测试
* mvn verify 运行检查
* mvn clean 清理项目
* mvn install 安装项目到本地仓库
* mvn deploy 发布项目到远程仓库
* mvn dependency:tree 显示Maven依赖树
* mvn dependency:list 显示Maven依赖列表
* 常用参数
* -D 指定参数,如 -Dmaven.test.skip=true 跳过单元测试;
* -P 指定 Profile 配置,可以用于区分环境;
<span>
常用打包案列:mvn clean package -Pdev -Dmaven.test.skip=true
只打包不运行的命令
mvn clean package -Pdev -Dmaven.test.skip=true -Dmaven.javadoc.skip=true
</span>
* web相关命令
* mvn tomcat:run 启动tomcat
* mvn jetty:run 启动jetty
* mvn tomcat:deploy 运行打包部署
6、导入第三方jar包到本地仓库
--- 进入cmd命令界面
* 输入指令如下:mvn install:install-file -Dfile=xxxxxx -DgroupId=xxxxx
-DartifactId=xxxx -Dversion=xxxx -Dpackaging=xxx -DgeneratePom=true -DcreateChecksum=true
* 参数说明
* Dfile为jar包文件路径
* DgroupId一般为jar开发组织的名称,也是坐标groupId
* DartifactId一般为jar名称,也是坐标 artifactId
* Dversion是版本号
* Dpackaging是打包类型
--- 实际案列
<span>
mvn install:install-file -Dfile=C:\activitiProject\fastjson-1.2.58.jar -
DgroupId=com.myjar -DartifactId=fastjson -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true
-DcreateChecksum=true
</span>
7、常用的maven插件
* maven官方插件列表
* groupId为org.apache.maven.plugins
* [http://maven.apache.org/plugins/index.html](http://maven.apache.org/plugins/index.html)
* 两种方式调用maven插件
* 将插件目标与生命周期阶段绑定,例如maven默认将maven-compiler-plugin的compile与maven生命周期的compile阶段绑定。
* 直接在命令行显示指定要执行的插件目标,例如mvn archetype:generate就表示调用maven-archetype-plugin的generate目标。
* 常用的maven插件
* maven-antrun-plugin
* maven-antrun-plugin能让用户在Maven项目中运行Ant任务。用户可以直接在该插件的配置以Ant的方式编写Target,然后交给该插件的run目标去执行。
* maven-archetype-plugin
* Archtype指项目的骨架,Maven初学者最开始执行的Maven命令可能就是mvn archetype:generate,这实际上就是让maven-archetype-plugin生成一个很简单的项目骨架,帮助开发者快速上手。
* maven-assembly-plugin
* maven-assembly-plugin的用途是制作项目分发包,该分发包可能包含了项目的可执行文件、源代码、readme、平台脚本等等。
* maven-dependency-plugin
* maven-dependency-plugin最大的用途是帮助分析项目依赖
* dependency:list能够列出项目最终解析到的依赖列表
* dependency:tree能进一步的描绘项目依赖树
* maven-enforcer-plugin
* maven-enforcer-plugin能够允许你创建一系列规则强制大家遵守,包括设定Java版本、设定Maven版本、禁止某些依赖、禁止SNAPSHOT依赖。
* maven-help-plugin
* maven-help-plugin是一个小巧的辅助工具。
* 最简单的help:system可以打印所有可用的环境变量和Java系统属性。
* maven-release-plugin
* maven-release-plugin的用途是帮助自动化项目版本发布,它依赖于POM中的SCM信息。
8、Nexus私服搭建
----nexus
私服是在局域网的一种特殊的远程仓库,目的是代理远程仓库及部署第三方构件。
有了私服之后,当 Maven 需要下载jar包时,先请求私服,私服上如果存在则下载到本地仓库。
否则,私服直接请求外部的远程仓库,将jar包下载到私服,再提供给本地仓库下载。
nexus下载地址:https://help.sonatype.com/repomanager2/download
nexus下载地址:https://download.csdn.net/download/qq_33274797/12057873(官网下载速度太慢推荐)
Nexus 专业版是需要付费的,这里我们下载开源版 Nexus OSS,最新的是OSS3.x,我们选择稳定的版本2.x。
* 启动
* 以管理员身份打开cmd,进入到bin目录,先执行nexus install命令,再执行nexus start。
* 打开浏览器,访问http://localhost:8081/nexus
* 点击右上角Log in,使用用户名:admin,密码:admin123登录
![](https://i-blog.csdnimg.cn/blog_migrate/2dabe5a74d583c8aaafe42bf16eced17.png)
![](https://i-blog.csdnimg.cn/blog_migrate/fa3fa00a1a175b4bbee29c56e57ffc29.png)
9、nexus仓库介绍
类型介绍
hosted:是本地仓库,用户可以把自己的一些jar包,发布到hosted中,比如公司的第二方库
proxy: 代理仓库,它们被用来代理远程的公共仓库,如maven中央仓库。不允许用户自己上传jar包,只能从中央仓库下载
group: 仓库组,用来合并多个hosted/proxy仓库,当你的项目希望在多个repository使用资源时就不需要多次引用了,只需要引用一个group即可
virtual:虚拟仓库基本废弃了。
预置仓库
* Central:该仓库代理Maven中央仓库,其策略为Release,因此只会下载和缓存中央仓库中的发布版本构件。
* Releases:这是一个策略为Release的宿主类型仓库,用来部署正式发布版本构件
* Snapshots:这是一个策略为Snapshot的宿主类型仓库,用来部署开发版本构件。
* 3rd party:这是一个策略为Release的宿主类型仓库,用来部署无法从maven中央仓库获得的第三方发布版本构件,比如IBM或者oracle的一些jar包(比如classe12.jar),由于受到商业版权的限制,不允许在中央仓库出现,如果想让这些包在私服上进行管理,就需要第三方的仓库。
* Public Repositories:一个组合仓库
10、在nexus建立你的第一个仓库
* 建库,Add-- >Hosted Repository
* 填写仓库信息
* Respository ID 仓库编号
* Repository NAME 仓库名称
* Repository Type 仓库类型
* Repository Policy 仓库策略
--路径默认在sonatype-work\nexus\storage
* Default Local Storage Location 仓库路径
* Deployment Policy 发布策略
* 然后选择Public Repositories,打开configuration选项卡,将自己创建的仓库添加到group
![](https://i-blog.csdnimg.cn/blog_migrate/a70687954d1b5fb18d8132a2e8932b58.png)
11、将项目发布到maven私服
---配置setting.xml
<!-- 配置用户和密码-->
<!-- id为仓库的id[或者:也可以是自定义id,但是必须与pom文件中id相同],具体发布是和pom文件关联-->
<server>
<id>lmr</id>
<username>admin</username>
<password>admin123</password>
</server>
<!-- 以下的配置信息与将本地工程包上传到私服没关系是用来下载jar。与之有关联的是pom文件
distributionManagement标签配置私服远程仓库地址
-->
<!-- 配置镜像-->
<mirror>
<!-- 镜像id自定义-->
<id>lmrId</id>
<!-- <mirrorOf>central</mirrorOf>里是要替代的仓库的id。 填*就会代替所有仓库-->
<mirrorOf>nexus,central</mirrorOf>
<!-- 镜像name自定义-->
<name>lmrName</name>
<url>http://localhost:8081/nexus/content/groups/public/</url>
</mirror>
<!-- 配置远程仓库-->
<profile>
<!-- id自定义设置 但是需要与activeProfile中定义相同 -->
<id>lmr_repositories_id</id>
<repositories>
<repository>
<!-- id自定义设置,如果下载jar包有权限设置,需要配置和server中id相同-->
<id>local-nexus</id>
<name>local-nexus-name</name>
<url>http://localhost:8081/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</profile>
<!--使lmr_repositories_id远程仓库生效 -->
<activeProfiles>
<activeProfile>lmr_repositories_id</activeProfile>
</activeProfiles>
---pom文件修改
<!-- 配置此信息可将当前项目生产上传至私服 -->
<distributionManagement>
<repository>
<!-- 配置和server中id相同 通过账号密码-->
<id>lmr</id>
<url>http://localhost:8081/nexus/content/repositories/lmr</url>
</repository>
</distributionManagement>
---执行以下命令
mvn clean
mvn package
mvn deploy
12、snapshot快照
解决的问题:
假设一个团队工作,其中有个项目叫做data-use,同时他们使用数据服务工程(data-service.jar:1.0)。
现在负责数据服务的团队可能正在进行修 bug 或者更新迭代,每次发布都会发布工程到远程仓库中。
现在如果数据服务团队每天上传新的版本,那么就会有下面的问题:
- 每次数据服务团队发布了一版更新的代码时,都要告诉应用接口团队。
- 应用接口团队需要定期更新他们的 pom.xml 来得到更新的版本
<span>
快照是一个特殊的版本,它表示当前开发的一个副本。与常规版本不同,Maven 每一次构建都从远程仓库中检出一份新的快照版本。
</span>
<!-- 配置远程仓库-->
<profile>
<id>lmr_repositories_id</id>
<repositories>
<repository>
<id>local-nexus</id>
<name>local-nexus-name</name>
<url>http://localhost:8081/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<!-- 快照策略
always 每次都去远程仓库查看是否有更新
daily 每天第一次的时候查看是否有更新
interval 允许设置一个分钟为单位的间隔时间,在这个间隔时间内只会去远程仓库中查找一次
never 从不会
-->
<updatePolicy>
always
</updatePolicy>
</snapshots>
</repository>
</repositories>
</profile>
---------------------------------------------------------------------
---实战测试
(1)在私服上创建一个本地的snapshot仓库(略 参考上面如何创建仓库)
(2)在setting.xml中配置仓库的<server></server>,id为仓库的id(略 参考上文)
(3)创建一个项目data-service,定义为snapshot版本
<groupId>com.lmr</groupId>
<artifactId>data-service</artifactId>
<version>1.0-SNAPSHOT</version>
(4) 在data-service项目中pom文件,配置上传私服仓库的地址(略 参考上文)
<distributionManagement>
<snapshotRepository>
<id>lmrSnapshotId</id>
<url>http://localhost:8081/nexus/content/repositories/lmrSnapshotId</url>
</snapshotRepository>
</distributionManagement>
(5) 创建一个data-demo项目引入data-servicejar测试
<dependency>
<groupId>com.lmr</groupId>
<artifactId>data-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
13、maven的依赖管理
依赖的传递性
传递性依赖是在maven2中添加的新特征,这个特征的作用就是你不需要考虑你依赖的库文件所需要依赖的库文件,能够将依赖模块的依赖自动的引入。
依赖的作用范围:
compile:默认范围,编译依赖对项目所有的classpath都可用。此外,编译依赖会传递到依赖的项目。
provided:表示该依赖项将由JDK或者运行容器在运行时提供,也就是说由Maven提供的该依赖项我们只有
在编译和测试时才会用到,而在运行时将由JDK或者运行容器提供。
runtime:表明编译时不需要依赖,而只在运行时依赖。
test:只在编译测试代码和运行测试的时候需要,应用的正常运行不需要此类依赖。
system:系统范围与provided类似,不过你必须显式指定一个本地系统路径的JAR,此类依赖应该一直有效,Maven也不会去仓库中寻找它。
<!-- <scope></scope>标签设置依赖作用范围-->
<dependency>
<groupId>sun.jdk</groupId>
<artifactId>tools</artifactId>
<version>1.5.0</version>
<scope>system</scope>
<systemPath>jar包路径地址</systemPath>
</dependency>
import:范围只适用于<dependencyManagement>部分。表明指定的POM必须使用<dependencyManagement>部分的依赖。
依赖的两大原则:
路径近者优先:
A 依赖 B 依赖 C (1.0)
A 依赖 C(2.0)
结果:最后A依赖C(2.0) 路劲优先原则
第一声明优先:
A 依赖 B 依赖 C (1.0)
A 依赖 B 依赖 C (2.0)
结果:最后A依赖C (1.0) 路径相同,采用第一声明优先原则。
依赖的排除
方法1:任何可传递的依赖都可以通过 "exclusion" 元素被排除在外
A 依赖 B 依赖 C 现在A不想依赖C,只依赖B。
在A项目pom中排除掉B依赖C的部分
<dependency>
<groupId>com.lmr</groupId>
<artifactId>data-service</artifactId>
<version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</exclusion>
</exclusions>
</dependency>
方法2:任何可传递的依赖可以被标记为可选的,通过使用 "optional" 元素。
A 依赖 B 依赖 C 现在A不想依赖C,只依赖B。
在B项目pom使用optional标签,先排除掉C。然后A项目中引用B就不会依赖引用C
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
<optional>true</optional>
</dependency>
14、解决jar包冲突
---查看依赖引入Tree 自行排除
mvn dependency:tree -Dverbose
15、mirror(镜像)与repository(仓库区别)
mirror镜像
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>aliyunName</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
<mirrorOf>*</mirrorOf> 最重要,当配置不同值覆盖不同的远程仓库。
举例:
(1)值为central,表示该配置为中央仓库的镜像,任何对于中央仓库的请求都会转至该镜像(url),从该url下载所需的jar文件,将不会去请求中央仓库。
(2)值为*,覆盖所有的远程仓库。
具体的配置方式,可以百度搜索