maven
1、介绍
1.1、概念
Maven 是 Apache 下的一个纯 Java 开发的开源项目,是一个项目构建和管理的工具。将项目开发和管理过程抽象成一个项目对象模型(POM)。
1.2、作用
-
项目构建:提供标准的、跨平台的自动化项目构建方式
-
依赖管理:方便快捷的管理项目依赖的资源(jar包),避免资源间的版本冲突问题
-
统一开发结构:提供标准的、统一的项目结构
2、下载与安装
2.1、下载
我们安装在本地,所以选择windows版本。
2.2、解压
因为maven是免安装绿色版本,所以直接解压即可使用。
各目录结构说明:
-
bin:可执行程序目录
-
boot:maven自身的启动加载器
-
conf:maven配置文件的存放目录
-
lib:maven运行所需库的存放目录
2.3、配置环境变量
打开windows设置------>搜索环境变量------>
使用命令 mvn -version
来测试maven是否配置成功
出现上图字样,则表示maven已经安装配置完毕!撒花❀❀❀
3、maven基础概念
3.1、仓库
用于存储资源,主要是各种jar包。
3.1.1、仓库分类
-
本地仓库:自己电脑上存储资源的仓库,连接远程仓库获取资源
-
远程仓库:非本机电脑上的仓库,为本地仓库提供资源
-
- 中央仓库:Maven团队维护,存储所有资源的仓库
-
私服:部门/公司范围内存储资源的仓库,从中央仓库获取资源
3.1.2、私服的作用
- 保存具有版权的资源,包含购买或自主研发的jar包;中央仓库中的jar包都是开源的,不能存储具有版权的资源
- 一定范围内共享资源,仅对内部开放,不对外共享
3.2、坐标
3.2.1、介绍
maven中的坐标用于描述仓库资源的位置。
3.2.2、主要组成
-
groupId:定义当前maven项目隶属组织名称(通常是域名反写,例如org.apache)
-
artifactId:定义当前maven项目名称(通常是模板名称,例如CRM、SMS)
-
version:定义当前项目版本号
3.2.3、作用
使用唯一标识,唯一性定位资源位置,通过该标识可以将资源的识别与下载工作交由机器完成。
3.3、仓库配置
3.3.1、本地仓库配置
使用nodpad++打开maven解压目录下conf文件夹下的 settings.xml
文件。
打开后,找到第52行,可以看到maven默认下载的jar包放在 ${user.home}/.m2/repository
,即用户目录.m2\repository。
jar默认下载目录。
当然如果想修改jar包下载的地方(即本地仓库),只需照着如下示例修改成自己的配置即可。
3.3.2、远程仓库配置
maven默认连接的远程仓库位置。
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
3.3.3、镜像仓库配置(配置阿里云镜像)
在打开的 settings.xml
配置文件中找到 <mirrors></mirrors>
标签中添加 <mirror></mirror>
节点。
<mirror>
<!--此镜像的唯一标识符,用来区分不同的mirror元素-->
<id>aliyunmaven</id>
<!--对哪种仓库进行镜像,简单的说就是替代哪个仓库 -->
<mirrorOf>central</mirrorOf>
<!--镜像名称-->
<name>阿里云公共仓库</name>
<!--镜像URL-->
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
4、maven项目
4.1、idea的maven配置
当前项目的maven配置
当创建新项目时的maven配置:
4.2、maven项目构建命令
maven构建命令使用 mvn
开头,后面添加参数,可以一次执行多个命令,使用空格分隔。
mvn compile #编译
mvn clean #清理
mvn test #测试
mvn package #打包
mvn install #安装到本地仓库
如果是使用idea,则可以使用图形化界面快捷操作。
4.3、创建空的maven项目
使用idea创建一个空的maven项目。
查看当前项目的结构,使用快捷键 ctrl+alt+shift+s
或者使用如下操作:
4.4、创建maven的web项目
使用idea创建一个maven的web项目。
开始从阿里云仓库上下载资源。
安装tomcat插件
在项目的 pom.xml
配置文件中引入
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
双击运行 tomcat7:run
命令启动web项目:
访问本地80端口,可以看到运行结果:
5、依赖管理
5.1、依赖配置
- 依赖指的是当前项目运行所需要的jar包,一个项目可以设置多个依赖。
- 格式:
<!--设置当前项目所依赖的所有jar包坐标-->
<dependencies>
<!--设置具体的依赖坐标-->
<dependency>
<!--依赖所属的组织Id-->
<groupId>junit</groupId>
<!--依赖所属的项目Id-->
<artifactId>junit</artifactId>
<!--依赖的版本号-->
<version>4.11</version>
</dependency>
</dependencies>
5.2、依赖传递重要
-
依赖具有传递性
-
- 直接依赖:在当前项目中通过依赖配置建立的依赖关系
-
间接依赖:被依赖的资源如果依赖其他资源,当前项目间接依赖其他资源(比较拗口,意思就是如果A依赖B,而B依赖C,那么A就间接依赖C)
-
依赖传递冲突问题
-
- 路径最短者优先原则:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高
-
路径相同先声明优先原则:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的
-
- 特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的(概率是书写错误,不应该出现这种情况)
5.3、可选依赖
可选依赖指对外隐藏当前所依赖的资源---不透明。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<optional>true</optional>
</dependency>
5.4、排除依赖重要
排除依赖指主动断开依赖的资源,被排除的资源无需指定版本---不需要。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
5.5、依赖范围重要
依赖的jar包默认情况下可以在任何地方使用,可以通过scope标签设定其作用范围
作用范围:
-
主程 序范围有效(main文件夹范围内)
-
测试程序范围有效(test文件夹范围内)
-
是否参与打包(package指令范围内)
5.6、依赖范围传递性(了解)
带有依赖范围的资源在进行传递时,作用范围将受到影响。具体看使用效果。
6、生命周期与插件
6.1、项目构建生命周期
6.1.1、介绍
maven构建生命周期描述的是一次构建过程经历了多少个事件
6.1.2、3个阶段
maven对项目构建的生命周期划分为3个阶段。
6.1.2.1、clean生命周期
-
pre-clean:执行一些需要在clean之前完成的工作
-
clean:移除所有上一次构建生成的文件
-
post-clean:执行一些需要在clean之后立刻完成的工作
6.1.2.2、default构建生命周期
核心工作是编译、测试、打包、安装、部署。
在执行某一个操作时,同时会执行该操作前面的所有操作。
6.1.2.3、site构建生命周期
-
pre-site:执行一些需要在生成站点文档之前完成的工作
-
site:生成项目的站点文档
-
post-site:执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
-
site-deploy:将生成的站点文档部署到特定的服务器上
6.2、插件重要
-
插件与生命周期内的阶段绑定,在执行到对应生命周期时执行对应的插件功能
-
默认maven在各个生命周期上绑定有预设的功能
-
通过插件可以自定义其他功能
用户可以根据需要将任何插件目标绑定到任何生命周期的任何阶段,如配置在 generate-test-resources
生成测试资源文件阶段的时候使用 maven-source-plugin
插件将main文件夹进行源码打包。
<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>
7、聚合重要
7.1、作用
用于快速构建maven工程,一次性构建多个项目/模块。即编译、测试、打包、部署该模块的时候会同时操作关联的模块。
7.2、制作方式
- 创建一个空模块,打包类型定义为pom
<packaging>pom</packaging>
- 定义当前模块进行构建操作时关联的其他模块名称,注意,
module
内的值为关联模块的pom文件相对于当前pom文件所在文件夹目录。
如下示例就是关联模块与当前模块平级,如果关联模块位于当前模块文件夹内,则没有../
。
<!--当前父模块有哪些子模块-->
<modules>
<module>../ssm_controller</module>
<module>../ssm_service</module>
<module>../ssm_dao</module>
<module>../ssm_pojo</module>
</modules>
注意事项:参与聚合操作的模块最终执行顺序与模块间的依赖有关,与配置顺序无关。
8、继承重要
8.1、作用
通过继承可以实现在子模块中沿用父模块中的配置。
8.2、制作方式
在子模块中声明其父模块坐标与pom文件的位置。
<!-- 定义该模块的父模块 -->
<parent>
<groupId>com.itheima</groupId>
<artifactId>ssm</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 填写父模块的pom文件所在位置 -->
<relativePath>../ssm/pom.xml</relativePath>
</parent>
8.3、依赖继承
子模块将自动继承父模块中的依赖。
父模块maven-java
中引入 spring-boot-starter
依赖,子模块 maven-java-001
和maven-java-002
将自动继承父模块maven-java
中 spring-boot-starter
的依赖。
<groupId>org.xiaorang</groupId>
<artifactId>maven-java</artifactId>
<version>1.0.0-SNAPSHOT</version>
<modules>
<module>maven-java-001</module>
<module>maven-java-002</module>
</modules>
<packaging>pom</packaging>
<!--自定义属性列表-->
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<!--在该标签中编写的依赖,子模块会自动继承-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.5.3</version>
</dependency>
</dependencies>
8.4、依赖管理
在父模块中进行依赖管理,子模块中需要声明式的引入依赖,但是无需声明依赖版本,版本将使用父模块依赖管理中依赖的版本号,达到由父模块统一控制依赖的版本号。
在父模块中进行依赖管理:
<!--在该标签中声明的依赖,子模块可以选择性的继承,同时省略版本号-->
<dependencyManagement>
<!--具体的依赖-->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
在子模块中声明式引入依赖:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
</dependencies>
9、聚合与继承的异同点
-
作用:
-
- 聚合用于快速构建项目
-
继承用于快速配置
-
相同点:
-
- 聚合与继承的pom.xml文件打包方式均为pom,可以将两种关系制作到同一pom文件中
-
聚合与继承均属于设计型模块,并无实际的模块内容
-
不同点:
-
- 聚合时在当前模块中配置关系,聚合可以感知到参与聚合的模块有哪些
-
继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
10、属性重要
问题:如果对于spring的资源版本都应该使用5.1.9.RELEASE
版本,但是你其中一个资源写错了,写的不是这个版本号或者说想将spring的资源版本都升级到5.2.0.RELEASE
版本,这个时候你是不是需要将所有的spring资源的版本号都改成5.2.0.RELEASE
版本。
方案:属性
10.1、自定义属性
- 作用:等同于定义变量,方便统一维护版本号。
- 定义格式:
<!--定义自定义属性-->
<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>
10.2、内置属性
- 作用:使用maven内置属性,快速配置。
- 调用格式:
${basedir} ${version}
10.3、Setting属性
- 作用:使用maven配置文件
setting.xml
中的标签属性,用于动态配置。 - 调用格式:
${settings.localRepository
10.4、Java系统属性
-
作用:读取Java系统属性
-
调用格式:
${user.home}
-
系统属性查询方式:
mvn help:system
10.5、环境变量属性
-
作用:使用maven配置文件
setting.xml
中的标签属性,用于动态配置 -
调用格式:
${env.JAVA_HOME}
-
环境变量属性查询方式:
mvn help:system
11、版本管理
11.1、工程版本
-
SNAPSHOT(快照版本)
-
- 项目开发过程中,为方便团队成员合作,解决模块间相互依赖和时时更新的问题,开发者对每个模块进行构建的时候,输出的临时性版本就叫快照版本(测试阶段版本)
-
快照版本会随着开发的进展不断更新
-
RELEASE(发布版本)
-
- 项目开发进入阶段里程碑后,向团队外部发布较为稳定的版本,这种版本对应的构件文件是稳定的,即便进行功能的后续开发,也不会改变当前发布版本内容,这种版本成为发布版本
11.2、工程版本号约定
约定规范:
-
<主版本>.<次版本>.<增量版本>.<里程碑版本>
-
主版本:表示项目重大架构的变更,如Spring5相较于Spring4的迭代
-
次版本:表示有较大的功能增加和变化,或者全面系统的修复漏洞
-
增量版本:表示有重大漏洞的修复
-
里程碑版本:表明一个版本的里程碑(版本内部)。这样的版本同下一个正式版本相比,相对来说不是很稳定,有待更多的测试
12、资源配置
-
作用:在任意配置文件引用pom文件中定义的属性。
-
调用格式:
${属性名}
-
如何开启配置文件可以加载pom文件中定义的属性:
<!--配置资源文件对应的信息-->
<resources>
<resource>
<!--设定配置文件对应的位置目录,支持使用属性动态设定路径-->
<directory>${project.basedir}/src/main/resources</directory>
<!--开启对配置文件的资源加载过滤-->
<filtering>true</filtering>
</resource>
</resources>
13、多环境开发配置
13.1、多环境配置
<!--创建多环境-->
<profiles>
<!--定义具体的环境:生产环境-->
<profile>
<!--定义环境对应的唯一名称-->
<id>pro</id>
<!--定义环境中的专用的属性值-->
<properties>
<jdbc.url>jdbc:mysql://127.1.1.1:3306/test</jdbc.url>
</properties>
<!--设置默认启动-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!--定义具体的环境:开发环境-->
<!--格式同上-->
</profiles>
13.2、加载指定环境
-
作用:加载指定环境配置
-
调用格式:
mvn 指令 -p 环境定义id
-
范例:
mvn install -p pro
14、跳过测试
14.1、必要性
如执行maven打包发布项目时,如果测试类中有测试用例代码,打包maven默认会将测试用例一起编译并执行,编译执行不通过则会报错。
14.2、方法
14.2.1、使用mvn命令
# 不执行测试用例,但编译测试用例类生成相应的class文件至target/test-classes下
mvn clean install -DskipTests
# 不执行测试用例,也不编译测试用例类
mvn clean install -Dmaven.test.skip=true
14.2.2、使用idea的maven界面
没有跳过测试时,双击执行打包,控制台输出没有测试用例需要执行。
点击跳过测试后,test生命周期图标变灰,双击执行打包时,控制台输出测试用例已跳过。
14.2.3、使用配置文件
添加 maven-surefire-plugin
插件,设置跳过测试。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<skipTests>true</skipTests><!--设置跳过测试-->
</configuration>
</plugin>
可以看到即使没有点击跳过测试按钮,双击执行打包时,控制台输出的依然是测试用例已跳过。
详细指定:
-
包名路径,文件名带后缀
-
支持通配符*,其中
**
表示任何包,*
表示任何字符 -
excludes
优先级高于includes
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<!--详细指定要跑的测试-->
<includes>
<include>com/jerry/AppTest*.java</include>
</includes>
<!--详细指定排除的测试-->
<excludes>
<exclude>com/jerry/AppTest.java</exclude>
<exclude>com/jerry/AppTest1.java</exclude>
</excludes>
</configuration>
</plugin>
15、自定义骨架
maven官方通过插件给我们提供了大量的模板,但是这些模板或多或少的都存在一定的问题,无法满足我们实际的需求,所以我们需要根据自己的需求自定义模板出来。
15.1、生成模板
根据已经存在的项目创建骨架,在pom.xml文件中添加骨架插件 maven-archetype-plugin
。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-archetype-plugin</artifactId>
<version>2.2</version>
</plugin>
在idea的maven界面中可以看到这个插件
使用mvn命令将该项目做成骨架或者使用idea界面的插件按钮
mvn archetype:create-from-project
生成骨架的时候如果出现如下错误,需要在maven安装目录将mvn.cmd复制拷贝一份,名字改成mvn.bat。
骨架生成成功
切换到生成的骨架项目目录
cd target\generated-sources\archetype
向本地仓库中发布
mvn install
最后执行mvn archetype:crawl
命令 或者使用idea的maven界面中的插件按钮
执行完毕之后,在maven的本地仓库目录中生成一个archetype-catalog.xml文件。
15.2、使用模板
idea安装 maven archetype catalogs
插件
添加成功之后,在新建maven项目的时候就可以选到刚才创建的骨架。
16、私服
16.1、简介
私服是架设在局域网的一种特殊的远程仓库,目的是代理远程仓库及部署第三方构件。有了私服之后,当maven需要下载构件时,直接请求私服,私服上存在则下载到本地仓库;否则,私服请求外部的远程仓库,将构件下载到私服,再提供给本地仓库下载。
16.2、必要性(优点)
-
减少网络带宽流量。如果没有私服,我们所需的所有构件都需要通过maven的中央仓库或者第三方的maven仓库下载到本地,而一个团队中的所有人都重复的从maven仓库下载构件无疑加大了仓库的负载和浪费了外网带宽,如果网速慢的话,还会影响项目的进程。
-
一定范围内共享资源,仅对内部开放,不对外共享。很多情况下项目的开发都是再内网进行的,可能根本连接不了maven的中央仓库和第三方的maven仓库。
-
加速maven构建
-
部署第三方构件
-
提高稳定性、增强控制
-
降低中央仓库的负载
16.3、Nexus
16.3.1、简介
Nexus 是一个专门的 maven 仓库管理软件,它不仅能够搭建 maven 私服,还具有如下一些优点使其日趋成为最流行的 maven 仓库管理器。
-
提供了强大的仓库管理功能,构件搜索功能
-
它基于 REST,友好的 UI 是一个 ext.js 的 REST 客户端
-
它占用较少的内存
-
基于简单文件系统而非数据库
16.3.2、下载安装运行
- 使用docker安装nexus3。
docker search nexus
docker pull sonatype/nexus3
- 创建docker-compose.yml文件
cat /usr/local/docker/nexus/docker-compose.yml
version: '3'
services:
nexus:
restart: always
image: sonatype/nexus3
container_name: nexus3
ports:
- 8081:8081
volumes:
- /usr/local/docker/nexus/nexus-data:/nexus-data
:wq保存退出。
- 运行nexus3,如果访问不成功,则需要给nexus-data文件夹赋权限
chmod 777 nexus-data/
。
# 使用docker-compose启动
docker-compose up -d
# 使用docker-compose停止
docker-compose down
需要查看nexus-data文件夹下的admin.password文件,里面记录了密码。
cat admin.password
登录之后会出现弹窗界面需要你修改密码。
16.3.3、配置本地仓库访问私服的权限
在maven安装目录下的settings.xml配置文件中的servers中添加serve节点,因为私服不是谁都可以使用,所以需要配置用户名和密码。
<servers>
<server>
<id>nexus-releases</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>nexus-snapshots</id>
<username>admin</username>
<password>admin123</password>
</server>
</servers>
16.3.4、配置当前项目访问私服上传资源的保存位置
<distributionManagement>
<repository>
<id>nexus-releases</id>
<name>Nexus Release Repository</name>
<url>http://120.78.177.161:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Nexus Snapshot Repository</name>
<url>http://120.78.177.161:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
发布资源到私服命令
mvn deploy
注意:id名称需要与settings.xml配置文件中server节点配置的id保持一致。
可以看到项目快照版本已经上传到私服。
16.3.5、设置代理仓库(用于下载资源)
在测试的时候,先将本地仓库的依赖先删除掉,迫使项目去私服中下载。
<!-- 私服仓库配置:从私服下载-->
<repositories>
<repository>
<id>nexus</id>
<name>Nexus Repository</name>
<url>http://120.78.177.161:8081/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>nexus</id>
<name>Nexus Plugin Repository</name>
<url>http://120.78.177.161:8081/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
如果没有开启匿名访问,在下载资源的时候会报没有权限下载。
开启匿名访问
idea配置maven总是更新快照。
依赖下载成功
16.3.6、上传第三方jar包
打开cmd,先跳转到第三方jar包资源目录,然后执行如下mvn命令即可:
mvn deploy:deploy-file -DgroupId=com.alibaba -DartifactId=fastjson -Dversion=1.2.28 -Dpackaging=jar -Dfile=fastjson-1.2.28.jar -Durl=http://120.78.177.161:8081/repository/maven-releases/ -DrepositoryId=nexus-releases
查看nexus-releases仓库,发现有我们上传的第三方jar包。
至此,大功告成!!!先告一段落,❀❀❀