Maven
1. Maven 简介
1、Maven的本质是一个项目管理工具,由 java 编写,万物皆对象,Maven 将一个项目抽象成了一个对象 POM (Project Object Model,项目对象模型)。
2、Maven的作用:
-
项目构建管理:提供标准的、跨平台的自动化项目构建方式。(提供了多种插件可以对项目进行编译、打包)
-
依赖管理:方便快捷的管理项目依赖的资源(jar包),避免资源间的版本冲突问题。(之前是通过拷贝jar包的方式导入项目中,而且jar之间会互相依赖导致jar包冲突)
-
统一开发结构:提供标准的、统一的项目结构。(成为了java项目目录结构的一种规范,方便java程序员去理解其他新的java项目)
2. Maven基础概念
2.1 仓库
1、用于存储各种jar包。
2、可以分成本地仓库和远程仓库。
3、本地仓库就是在自己的计算机中的仓库。
4、远程仓库又分为私服和中央仓库。
- 中央仓库由maven团队维护,当本地仓库中没有指定的依赖时,可以去中央仓库下载。
- 由于中央仓库不在中国境内,下载速度慢,要是整个企业都在往中央仓库去下载,依赖基本都下不下来。这时出现了maven私服,它搭建在公司的局域网内,当我们电脑本地仓库中没有指定的依赖时,可以去中央仓库下载,大大提升了下载速度。并且maven上面的jar包都是开源的,要是公司有个私有的jar包,不想被公开访问,可以上传到maven私服中。(私服解决了访问速度慢与版权问题)
2.2 仓库配置
1、默认的本地仓库在 C:\Users\你的用户名\.m2\repository 目录下,由于 C 盘珍贵,所以要更换本地仓库的目录。
2、可以在其他盘符创建一个本地仓库,例如:D:\Maven\repository
3、需要在 maven 的 settings.xml 配置文件中修改配置。
<!-- 默认本地仓库地址: ${user.home}/.m2/repository -->
<localRepository>D:\Maven\repository</localRepository>
4、配置完后,所有下载的jar包将都存在自定义的目录。
5、修改远程仓库的配置,指定jar包从哪下。默认是从 https://repo.maven.org/maven2 下载,速度较慢。
<!-- 配置阿里云镜像 -->
<mirrors>
<mirror>
<!-- 此镜像的唯一标识符,用来区分不同的mirror元素 -->
<id>nexus-aliyun</id>
<!-- 对那种仓库进行镜像(就是替代哪种仓库)-->
<mirrorOf>central</mirrorOf>
<!-- 镜像名称 -->
<name>Nexus aliyun</name>
<!-- 镜像URL -->
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
2.3 坐标
1、使用唯一的标识,定位jar包的位置,为了之后下载jar包。
2、坐标的主要组成:
- groupId:定义当前Maven项目隶属组织名称(通常是域名反写,例如:org.mybatis)
- artifactId:定义当前Maven项目名称(通常是模块名称)
- version:定义当前版本号
- packaging:定义该项目的打包方式
3. 依赖管理
3.1 依赖传递
依赖具有传递性(A依赖B,B依赖C,A依赖B和C),包括直接传递和间接传递。
-
直接传递:在当前项目中通过依赖配置建立的依赖关系(A依赖B,A和B就是直接传递)
-
间接传递:被依赖的资源如果依赖其他资源,当前项目间接依赖其他资源(如果A依赖B,而B依赖C,那么A和C之间就是间接传递)
3.2 依赖冲突
依赖传递的冲突问题:
-
路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高。
当A依赖了B、C(v1版本),B依赖C(V2版本),A会优先使用V1版本 -
声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的。
当A依赖B、C,B依赖D(V1版本),C也依赖D(V2版本),如果B在A中声明在前,那么A会优先使用V1版本。 -
特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的。
A的pom文件中写了两个相同的依赖,例如依赖B(V1版本)和B(V2版本),如果V1版本的写在后面,那么A会优先使用V1版本。

3.3 隐藏依赖
A依赖B,默认A能看见B依赖于C。如果在B的依赖的C上添加 <optional>true</optional>,则A就看不见B依赖的C。
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<!--添加下面这一行-->
<optional>true</optional>
</dependency>
3.4 排除依赖
A依赖B,B依赖C,默认A会依赖于B、C,如果A不想依赖C,需要在引入B依赖的里面添加 <exclusions> 把C依赖排除掉。
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<!--添加下面这一块-->
<exclusions>
<exclusion>
<groupId></groupId>
<artifactId></artifactId>
</exclusion>
</exclusions>
</dependency>
3.5 依赖范围
1、如果要设置依赖的jar包的作用范围,可以通过scope标签限制作用范围,默认是全部范围。
2、作用范围:
- 主程序范围有效,主编程要用(main文件夹范围内)
- 测试程序范围有效,测试编程要用(test文件夹范围内)
- 是否参与打包,生产环境要使用(package文件夹范围内)

3、如果配置为 test 或者 provided 不参与打包,自然依赖传递也传递不了。
4. 生命周期与插件
1、Maven项目构建生命周期描述的是一次构建过程经历了多少个事件,例如:清理、编译、测试、打包、部署、发布等等。
2、插件与生命周期内的阶段绑定。
- 插件中要指定是在构建的什么生命周期,运行此插件时,会先将此生命周期之前定义的所有插件运行,再运行此插件。
- 运行某个生命周期时,会先将此生命周期之前定义的所有插件运行,再运行此生命周期的插件。
3、我们可以自定义生命周期插件,支持的生命周期插件可以在官网查看:https://maven.apache.org/plugins/index.html
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<phase>generate-test-resources</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
-
phase:指定声明周期的阶段,此生命周期阶段之前的阶段的插件也会执行。
-
goals:可以指定这个插件的具体功能,可以指定多个功能。
5. 聚合工程
1、背景:对于一个大型的项目,如果我们直接作为一个工程开发,由于相互之间的依赖我们只能从头到尾由一组人开发,否则就会出现一个类好多人开发,相互更改的混乱局面,这个时候我们就将项目进行了横向和纵向的拆分。
2、所谓的横向的拆分就是我们平常说的三层架构,将项目分成了web层,service层、dao层(web层也被叫做表现层,service层也被叫做业务层,dao层也被持久层),可以理解为将一个功能模块的不同调用过程进行了水平方向的拆分。
3、横向拆分后,每个功能模块进行了单独的开发之后,项目整合的时候就需要有一个能够整合这些项目或者模块的工程,这就是所谓聚合工程的意义。
4、聚合工程本身也是个Maven项目,不存放代码,只有单独的pom文件。
5、定义打包方式必须为 pom,代表这个项目是聚合工程,用于进行构建管理,只提供pom文件。
<packaging>pom</packaging>
6、定义管理的工程模块。
<modules>
<module>模块地址</module>
<module>模块地址</module>
<module>模块地址</module>
</modules>
7、对聚合工程执行生命周期插件时,所有的子工程会按照依赖顺序分别进行构建。
6. 继承
1、背景:如果子工程依赖相同一个依赖,但引入的版本不一致,可能会引起依赖冲突的问题。
2、使用maven的继承,在父工程中定义所有的依赖,对所有的依赖的版本进行管理。
<!--声明此处进行依赖管理-->
<dependencyManagement>
<!--具体的依赖-->
<dependencies>
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
</dependency>
</dependencies>
</dependencyManagement>
3、子工程定义父工程。
<!--定义父工程-->
<parent>
<!--父工程的坐标-->
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<!--填写父工程的pom文件地址-->
<relativePath>父工程pom文件地址</relativePath>
</parent>
4、原则上父工程的 groupId 和 version 和子工程保持一致,所以子工程可以不写 groupId 和 version。
5、子工程继承父工程后,在子工程中定义依赖关系,无需声明依赖版本,版本参照父工程中依赖的版本。
<dependencies>
<dependency>
<groupId></groupId>
<artifactId></artifactId>
</dependency>
</dependencies>
6、聚合工程一般也可以作为父工程,聚合工程用于快速构建,聚合工程执行插件,他管理的工程也全执行完了。继承用于统一、简化配置。
7. 属性
1、背景:现在父工程可以统一依赖的版本了,但是spring的依赖有很多,依赖的版本相同,万一有一个spring的依赖写错了,会导致spring依赖版本不统一。
2、属性类似于变量,在工程里面定义属性后,若要使用只需要用${属性名}引用即可。
<!--定义自定义属性-->
<properties>
<spring.version>5.1.9.RELEASE</spring.version>
<junit.version>4.12</junit.version>
</properties>
<!--调用属性-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
3、maven中也提供了很多内置属性
-
$
-
${version}:读取当前pom文件的version
-
${settings.localRepository}:可以使用Maven配置文件setting.xml中的标签属性
-
${user.home}、${env.JAVA_HOME}:Java系统属性、环境变量的属性,可以通过
mvn help:system查询
8. 资源配置
1、项目中的配置文件也可以引用pom文件中定义的属性。
2、在pom文件中定义jdbc.url。
<properties>
<jdbc.url>jdbc:mysql://127.0.0.1:3306/test</jdbc.url>
</properties>
3、在pom文件中要定义配置文件,这样配置文件才能引用定义的属性。
<!--配置资源文件对应的信息-->
<resources>
<resource>
<!--设定配置文件对应的位置目录,支持使用属性动态设定路径-->
<directory>地址</directory>
<!--开启对配置文件的资源加载过滤-->
<filtering>true</filtering>
</resource>
</resources>
4、在任意配置文件引用
jdbc.url=${jdbc.url}
9. 多环境开发配置
1、可以设置多个环境,不同的环境里面的变量属性不同。
2、可以指定一个默认环境。
<!--创建多环境-->
<profiles>
<!--定义具体的环境:生产环境-->
<profile>
<!--定义环境对应的唯一名称-->
<id>dep_env</id>
<!--定义环境中的专用的属性值-->
<properties>
<jdbc.url>jdbc:mysql://127.0.0.1:3306/test</jdbc.url>
</properties>
<!--默认环境-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!--定义具体的环境:开发环境-->
<!--格式同上-->
</profiles>
3、运行时指定环境:install -P 指定环境ID
10. 构建跳过测试
1、背景:整体模块功能未开发,或者某个模块的某个功能未开发完毕,但测试用例已经写完放到程序里了,这时候如果执行 mvn package 或者 mvn install 都会执行 mvn test 这一个插件,会导致测试不通过,使得打包或者安装jar包到本地仓库失败。为了便捷和能够快速打包,我们有时可以暂时跳过测试插件。
2、构建跳过测试方法一:点击idea的跳过测试步骤的图标,发现测试的生命周期被划掉了。

3、构建跳过测试方法二:输入maven命令,后面加上 -D skipTests

4、构建跳过测试方法三:pom文件配置测试插件,skipTests 改成 true。maven所有插件安装在:D:\Maven\repository\org\apache\maven\plugins
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
5、我们也可以指定某些包下的某些测试类执行和排除。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<!-- 包含某些测试用例,例如5000个测试用例要测20个 -->
<includes>
<include>**/User*Test.java</include>
</includes>
<!-- 排除某些测试用例,例如5000个测试用例要排除20个 -->
<excludes>
<exclude></exclude>
</excludes>
</configuration>
</plugin>
11. Maven 私服
11.1 Maven 私服介绍
1、背景:如果公司要分模块开发,我开发订单模块,你开发商品模块,如果我订单模块需要使用到商品模块的jar包,该怎么办?用U盘拷贝,不行。上传到中央仓库,可以被所有人访问到,会产生版权问题,也不行。这时出现了maven私服,部署在公司局域网上,只能公司内部访问,你开发的商品模块的jar包上传到maven私服上,我访问maven私服下载。maven私服链接中央仓库,这样我们需要其他依赖的时候也不用去中央仓库下载了,直接去maven私服下载,速度快。
2、Nexus就是maven私服产品之一,自己搭建的maven服务器,供自己使用。
11.2 Nexus 安装
1、官网下载 Nexus 安装包,下载地址:https://help.sonatype.com/repomanager3/download/
2、上传到服务器的 /opt 目录下
3、解压缩,并把解压文件放到 /usr/local/nexus 目录下
tar -zxvf nexus-3.34.0-01-unix.tar.gz
mv nexus-3.34.0-01 /usr/local/nexus/
mv sonatype-work /usr/local/nexus/
- nexus-3.34.0-01:nexus的核心文件
- sonatype-work:存储下载下来的jar
4、修改 Nexus 配置文件,可以修改端口
vim ./etc/nexus-default.properties
application-port=8081
5、启动 Nexus ./nexus start
[root@localhost bin]# ./nexus start
WARNING: ************************************************************
WARNING: Detected execution as "root" user. This is NOT recommended!
WARNING: ************************************************************
Starting nexus
6、访问 Nexus ,http://192.168.200.110:8081/
7、登录,发现提示,admin 密码存放在 /usr/local/nexus/sonatype-work/nexus3/admin.password 文件里
Your admin user password is located in /usr/local/nexus/sonatype-work/nexus3/admin.password on the server.
8、登录成功后,会有初始化向导,包括:重设密码、是否开启匿名访问、是否发送数据改进Nexus。
11.3 仓库分类以及创建
1、仓库分类可以分为三种:
- 宿主仓库 hosted:保存无法从中央仓库获取的资源。例如:公司自主研发的jar包,第三方非开源项目。
- 代理仓库 proxy:代理远程仓库,通过 nexus 访问其他公共仓库。例如:maven 中央仓库。
- 仓库组 group:将若干个宿主仓库或者代理仓库分为一组,简化配置,自身不保存资源。

2、登录 Nexus 查看

3、创建仓库,设置->仓库->创建仓库->仓库类型为 maven2(hosted)

4、选中 maven-public 仓库组,将刚刚创建的 yinrz-release 仓库加入组中。

11.4 手动上传 jar 包到仓库
1、上传jar包,选中要保存的宿主仓库、选择要上传的资源文件、提供对应的maven坐标。(第三方的jar包可以使用手动上传)

2、查看上传的jar包与删除。

11.5 本地仓库访问私服
1、本地仓库与私服连接,本地仓库需要配置访问私服的用户名和密码,下载的仓库组是哪。
2、具体上传的仓库是哪,由工程决定,在idea中配置。

3、配置本地仓库,编辑 setting.xml
1)配置私服的用户名密码,因为拒绝了匿名访问。
<servers>
<!-- 访问 yinrz-release 仓库的用户名密码 -->
<server>
<id>yinrz-release</id>
<username>admin</username>
<password>root</password>
</server>
<!-- 访问 yinrz-snapshots 仓库的用户名密码 -->
<server>
<id>yinrz-snapshot</id>
<username>admin</username>
<password>root</password>
</server>
</servers>
2)配置jar包下载的地址,之前使用的是阿里云的镜像从中央仓库下载。现在添加nexus私服下载其他jar包,例如公司内部或者第三方jar包。
<mirrors>
<!-- 中央仓库的jar包全从阿里云私服下载 -->
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
<!-- 其他jar包全从nexus私服下载 -->
<mirror>
<id>nexus-yinrz</id>
<mirrorOf>*</mirrorOf>
<name>Nexus yinrz</name>
<url>http://192.168.200.110:8081/repository/maven-public/</url>
</mirror>
</mirrors>
3)整个 setting.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 http://maven.apache.org/xsd/settings-1.2.0.xsd">
<localRepository>D:\Maven\repository</localRepository>
<servers>
<!-- 配置访问服务器的权限 -->
<server>
<id>yinrz-release</id>
<username>admin</username>
<password>root</password>
</server>
<server>
<id>yinrz-snapshot</id>
<username>admin</username>
<password>root</password>
</server>
</servers>
<mirrors>
<!-- 中央仓库的jar包全从阿里云私服下载 -->
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
<!-- 其他jar包全从nexus私服下载 -->
<mirror>
<id>nexus-yinrz</id>
<mirrorOf>*</mirrorOf>
<name>Nexus yinrz</name>
<url>http://192.168.200.110:8081/repository/maven-public/</url>
</mirror>
</mirrors>
</settings>
11.6 idea 上传 jar 包到私服
1、在项目的 pom 文件中添加
<distributionManagement>
<repository>
<id>yinrz-release</id>
<url>http://192.168.200.110:8081/repository/yinrz-release/</url>
</repository>
<snapshotRepository>
<id>yinrz-snapshot</id>
<url>http://192.168.200.110:8081/repository/yinrz-snapshot/</url>
</snapshotRepository>
</distributionManagement>
2、上传此工程 jar 包到 Nexus,使用 maven 的 deploy 生命周期,会执行 deploy 生命周期前的所有插件。
注意:deploy 执行后,会根据 version 判断此项目是 release 还是 snapshot,如果后缀是 snapshot,则将 jar 包上传到 snapshotRepository 定义的 url 中,这时发现访问此 url 需要用户名和密码,就会按照 snapshotRepository 定义的 id 去找本地仓库配置中的 server 中的 id 是否匹配,如果匹配就按照此 server 配置的用户名和密码登录上传。


浙公网安备 33010602011771号