Maven使用教程
项目管理问题
常规的jar包管理主要存在以下的问题:
- 繁琐:要为每个项目手动导入所需的jar,需要搜集全部jar
- 复杂:项目中的jar如果需要版本升级,就需要再重新搜集jar
- 冗余: 相同的jar在不同的项目中保存了多份
那么怎么样才能方便快捷的管理我们项目中的jar包呢?
Maven概述
目前开发中常用的项目管理工具主要就是:
Maven
和Gradle
Maven(/ˈmeɪvn/):Maven这个单词来自于意第绪语(犹太语),意为知识的积累.
Maven是一个基于项目对象模型(POM)的概念的纯java开发的开源的项目管理工具。主要用来管理java项目,进行依赖管理(jar包依赖管理)和项目构建(项目编译、打包、测试、部署)。此外还能分模块开发,提高开发效率。
Gradle([ɡredl]):是一个基于JVM的构建工具,是一款通用灵活的构建工具,支持传递性依赖管理,而不需要远程仓库或者是pom.xml和ivy.xml配置文件,基于Groovy,build脚本使用Groovy编写。
Maven安装
下载链接:http://maven.apache.org/download.cgi ,历史版本: https://archive.apache.org/dist/maven/maven-3/
将下载的文件,选择合适的目录进行解压即可。 注意: 解压文件尽量不要放在含有中文或者特殊字符的目录下。
1
2
3
4bin:含有mvn运行的脚本
boot:含有plexus-classworlds类加载器框架,Maven 使用该框架加载自己的类库。
conf:含有settings.xml配置文件
lib:含有Maven运行时所需要的java类库环境变量设置
1
2
3# maven依赖java环境,所以要确保java环境已配置好 (maven-3.3+ 需要jdk7+)
MAVEN_HOME = maven的安装目录
PATH = maven的安装目录下的bin目录查看maven版本信息
1
2
3
4
5
6C:\Users\sfuli>mvn -v
Apache Maven 3.6.1 (d66c9c0b3152b2e69ee9bac180bb8fcc8e6af555; 2019-04-05T03:00:29+08:00)
Maven home: D:\scoop\apps\maven\current\bin\..
Java version: 1.8.0_201, vendor: Oracle Corporation, runtime: D:\scoop\apps\oraclejdk8\current\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
Maven配置
maven的conf目录中有 settings.xml ,是maven的配置文件,做如下配置:
本地仓库
1 | <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" |
JDK配置
在profiles标签中增加 一个profile标签,限定maven项目默认的jdk版本.
1 | <profiles> |
仓库
存储依赖的地方,体现形式就是本地的一个目录。
仓库中不仅存放依赖,而且管理着每个依赖的唯一标识(坐标),Java项目凭坐标获取依赖。
当需要依赖时,会从仓库中取查找,优先顺序为:
本地仓库 > 私服(如果配置了的话) > 公共仓库(如果配置了的话) > 中央仓库
Maven 中央仓库是由 Maven 社区提供的仓库,不用任何配置。 提供仓库搜索服务
中央仓库在国外,下载依赖速度过慢,所以都会配置一个国内的公共仓库替代中央仓库。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<!--setting.xml中添加如下配置-->
<mirrors>
<mirror>
<id>aliyun</id>
<!-- 中心仓库的 mirror(镜像) -->
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<!-- aliyun仓库地址 以后所有要指向中心仓库的请求,都会指向aliyun仓库-->
<url>https://maven.aliyun.com/repository/central</url>
</mirror>
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
私服
公司范围内共享的仓库,不对外开放。 可以通过 Nexus来创建、管理一个私服。
Idea-Maven
在idea中关联本地安装的maven,后续就可以通过idea使用maven,管理项目啦。
Idea中关联Maven
创建Maven项目
项目结构
src/main/java
存放源代码,建包,放项目中代码(service,dao,User,….)src/main/resources
书写配置文件,项目中的配置文件(jdbc.properties)src/test/java
书写测试代码,项目中测试案例代码src/test/resources
书写测试案例相关配置文件项目根/pom.xml
(project object model) maven项目核心文件,其中定义项目构建方式,声明依赖等
创建web项目
pom.xml中设置 war
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
<project ...>
...
<packaging>war</packaging>
<!-- 导入JSP 和 Servlet 和 JSTL 依赖 -->
<dependencies>
<dependency>
<!-- jstl 支持 -->
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<!-- servlet编译环境 -->
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<!-- jsp编译环境 -->
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>按照maven规范,新建web项目特有目录
webapp
. 新建src\main\webapp\WEB-INF\web.xml
1
2
3
4
5
6
7
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 这是一个空白的web.xml文件模板 -->
</web-app>
依赖生命周期
Jar包生效的时间段,即Jar的生命周期
标识 | 周期 |
---|---|
compile | 缺省值,适用于所有阶段(测试运行,编译,运行,打包) |
provided | 类似compile,期望JDK、容器或使用者会提供这个依赖。如servlet-api.jar;适用于(测试运行,编译)阶段 |
runtime | 只在运行时使用,如 mysql的驱动jar,适用于(运行,测试)阶段 |
test | 只在测试时使用,适用于(编译,测试运行)阶段,如 junit.jar |
system | Maven不会在仓库中查找对应依赖,在本地磁盘目录中查找;适用于(编译,测试运行,运行)阶段 |
1 | <dependency> |
Maven指令
compile
编译clean
删除target/test
运行测试test case junit/testNGpackage
打包install
把项目install到local repodeploy
发本地jar发布到remote
私服
搭建私服
- 所谓私服就是一个服务器,但是不是本地层面的,是公司层面的,公司中所有的开发人员都在使用同一个私服,有了私服之后,当 Maven 需要下载依赖时,直接请求私服,私服上存在则下载到本地仓库;否则,私服请求外部的远程仓库,将构件下载到私服,再提供给本地仓库下载。
- 私服可以解决在企业做开发时每次需要的jar包都要在中心仓库下载,且每次下载完只能被自己使用,不能被其他开发人员使用的问题
- 我们可以使用专门的 Maven 仓库管理软件来搭建私服,比如:Apache Archiva,Artifactory,Sonatype Nexus。这里我们使用 Sonatype Nexus
下载: 请根据自己需要,选择如下对应版本(目前 Nexus 分为 Nexus 2.x 和 Nexus 3.x 两个大版本,目前使用最多,运行最稳定的是 Nexus 2.x)
从nexus官网下载地址:https://www.sonatype.com/download-oss-sonatype
可以使用wget下载方式,命令如下:
1
2
3
4
5
6
7
8
9
10# 一般远程调用下载软件 路径类型是http;如果下载的路径类型是https,则需要一个认证指令,即wget 后面加上--no-check-certificate
wget --no-check-certificate https://download.sonatype.com/nexus/3/latest-unix.tar.gz
# 解压到当前文件夹下:
tar -xzvf nexus-3.19.1-01-unix.tar.gz
# 解压后在bin目录中执行:
nexus install 在系统中安装nexus服务
nexus uninstall 卸载nexus服务
nexus start 启动服务
nexus stop 停止服务修改配置文件
1
2
3
4
5cd /home/maven/nexus3/nexus-3.19.1-01/etc
vi nexus-default.properties
# 修改host为对应服务器的ip
application-host=192.168.61.10启动nexus
1
2
3
4
5
6
7
8
9cd /home/maven/nexus3/nexus-3.19.1-01/bin
# 启动nexus
./nexus start
# 查看启动日志
cd /home/maven/nexus3/sonatype-work/nexus3/log
tail -f nexus.log
# 查看链接日志
tail -f nexus-request.log登录nexus manager:http://192.168.61.10:9998/nexus/ 用户名默认
admin
,密码存在/home/maven/nexus3/sonatype-work/nexus3/ 下的admin.password文件中。
Maven配置私服
配置settings.xml,设置私服地址、认证等信息
1 | <servers> |
Maven 项目中依赖的搜索顺序
网上有很多关于maven项目中mirror、profile、repository的搜索顺序的文章,说法不一。官方文档并没有找到相关的说明,鉴于此,我抽时间做了一个验证。
依赖仓库的配置方式
maven项目使用的仓库一共有如下几种方式:
- 中央仓库,这是默认的仓库
- 镜像仓库,通过 sttings.xml 中的 settings.mirrors.mirror 配置
- 全局profile仓库,通过 settings.xml 中的 settings.repositories.repository 配置
- 项目仓库,通过 pom.xml 中的 project.repositories.repository 配置
- 项目profile仓库,通过 pom.xml 中的 project.profiles.profile.repositories.repository 配置
- 本地仓库
如果所有配置都存在,依赖的搜索顺序就会变得异常复杂。
分析依赖搜索顺序
先从最简单开始,慢慢增加配置,查看有什么变化。
准备测试环境
安装jdk、maven。
使用如下命令创建测试项目:
1 | yes | mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=true -DgroupId=com.pollyduan -DartifactId=myweb -Dversion=1.0 -Dpackage=com.pollyduan |
创建完成后,为了避免后续测试干扰,先执行一次compile。
1 | cd myweb |
最后,修改 pom.xml 文件,将 junit版本号改为 4.12 。我们要使用这个jar来测试依赖的搜索顺序。
默认情况
首先确保junit4.12不存在:
1 | rm -rf ~/.m2/repository/junit/junit/4.12 |
默认情况下没有配置任何仓库,也就是说,既没改 $M2_HOME/conf/settings.xml 也没有添加 ~/.m2/settings.xml
执行编译,查看日志中拉取junit的仓库。
1 | mvn compile |
- 可以看出,默认是从 central 中央仓库拉取的jar.
配置镜像仓库 settings_mirror
创建 ~/.m2/setttings.xml ,内容如下:
1 | <settings> |
重新测试:
1 | rm -rf ~/.m2/repository/junit/junit/4.12 |
在日志中查看下载依赖的仓库:
1 | Downloaded from settings_mirror: https://maven.aliyun.com/repository/public/junit/junit/4.12/junit-4.12.pom (24 kB at 35 kB/s) |
- 可以看出,是从 settings_mirror 中下载的jar
- 结论:settings_mirror 的优先级高于 central
配置pom中的仓库 pom_repositories
在 project 中增加如下配置:
1 | <repositories> |
- 由于我们改变了id的名字,所以仓库地址无所谓,使用相同的地址也不影响测试。
执行测试:
1 | rm -rf ~/.m2/repository/junit/junit/4.12 |
在日志中查看下载依赖的仓库:
1 | Downloaded from pom_repositories: http://10.18.29.128/nexus/content/groups/public/junit/junit/4.12/junit-4.12.pom (24 kB at 95 kB/s) |
从显示的仓库id可以看出:
- jar 是从 pom_repositories 中下载的。
- pom_repositories 优先级高于 settings_mirror
配置全局profile仓库 settings_profile_repo
在 ~/.m2/settings.xml 中 settings 的节点内增加:
1 | <profiles> |
执行测试:
1 | rm -rf ~/.m2/repository/junit/junit/4.12 |
在日志中查看下载依赖的仓库:
1 | Downloaded from settings_profile_repo: http://mirrors.163.com/maven/repository/maven-public/junit/junit/4.12/junit-4.12.pom (24 kB at 63 kB/s) |
从显示的仓库id可以看出:
- jar 是从 settings_profile_repo 中下载的。
- settings_profile_repo 优先级高于 settings_mirror。
- settings_profile_repo 优先级高于 pom_repositories 。
配置项目profile仓库 pom_profile_repo
1 | <profiles> |
执行测试:
1 | rm -rf ~/.m2/repository/junit/junit/4.12 |
在日志中查看下载依赖的仓库:
1 | Downloaded from settings_profile_repo: http://mirrors.163.com/maven/repository/maven-public/junit/junit/4.12/junit-4.12.pom (24 kB at 68 kB/s) |
从显示的仓库id可以看出:
- jar 是从 settings_profile_repo 中下载的
- settings_profile_repo 优先级高于 pom_profile_repo
进一步测试:
1 | rm -rf ~/.m2/repository/junit/junit/4.12 |
在日志中查看下载依赖的仓库:
1 | Downloaded from pom_profile_repo: http://10.18.29.128/nexus/content/groups/public/junit/junit/4.12/junit-4.12.pom (24 kB at 106 kB/s) |
从显示的仓库id可以看出:
- jar 是从 settings_profile_repo 中下载的
- pom_profile_repo 优先级高于 pom_repositories
最后确认 local_repo 本地仓库 ~/.m2/repository
这不算测试了,只是一个结论,可以任意测试。
- 只要
~/.m2/repository
中包含依赖,无论怎么配置,都会优先使用local本地仓库中的jar.
最终结论
settings_mirror 的优先级高于 central
settings_profile_repo 优先级高于 settings_mirror
settings_profile_repo 优先级高于 pom_repositories
settings_profile_repo 优先级高于 pom_profile_repo
pom_profile_repo 优先级高于 pom_repositories
pom_repositories 优先级高于 settings_mirror
通过上面的比较得出完整的搜索链:local_repo > settings_profile_repo > pom_profile_repo > pom_repositories > settings_mirror > central
设置Maven内存
windows修改mvn.bat(mvn.cmd)文件
1
2
3
4# 找到@REM MAVEN_OPTS... 在下面添加
set "MAVEN_OPTS=-Xss64m -Xmx2g -XX:ReservedCodeCacheSize=1g"
# maven -v 可以看到set命令被打印linux,修改mvn文件,添加
1
export MAVEN_OPTS="-Xss64m -Xmx2g -XX:ReservedCodeCacheSize=1g"