Apache Maven是一个项目管理工具,它包含了一个项目对象模型POM (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。当你使用Maven的时候,你用一个明确定义的项目对象模型来描述你的项目,然后Maven可以应用横切的逻辑,这些逻辑来自一组共享的(或者自定义的)插件。
Maven 有一个生命周期,当你运行 mvn install 的时候被调用。这条命令告诉 Maven 执行一系列的有序的步骤,直到到达你指定的生命周期。遍历生命周期旅途中的一个影响就是,Maven 运行了许多默认的插件目标,这些目标完成了像编译和创建一个 JAR 文件这样的工作。
此外,Maven能够很方便的帮你管理项目报告,生成站点,管理JAR文件,等等。
Maven有两大核心功能:
依赖管理:对jar的同一管理,maven提供了一个maven的中央仓库,地址https://mvnrepository.com。当在项目中添加完依赖后,maven会自动去中央仓库下载相关依赖,并解决依赖问题。
项目构建:对项目进行编译、测试、打包、部署、上传到私服等。
1、由于maven是一个Java项目,所以要提前安装jdk。
2、下载maven , https://maven.apache.org/download.html
3、解压并配置环境变量
配置MAVEN_HOME
4、检查
Maven安装完成后就可以使用了。但是maven默认使用自己的中央仓库,下载依赖jar网速非常慢。所以可以修改maven配置文件,将仓库地址改为国内镜像仓库,使用较多的是阿里巴巴的仓库。同时也可以修改jar包在本地存放的位置。
仓库类型:
本地仓库:个人电脑上的仓库,默认位置是${user}\.m2\repository
私服仓库:一般是公司内部搭建的maven私服,处于局域网内,访问速度较快,这个仓库中可以存放公司内部开发的jar。
中央仓库:由apache团队维护,包含了大量的jar。
Jar包查找顺序,从小范围到大范围。
修改配置文件%MAVEN_HOME%/conf/settings.xml
修改jar包存储位置。
配置阿里云镜像仓库
<mirror> <id>nexus-aliyun</id> <mirrorOf>central</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </mirror> |
常用命令 | 含义 | 说明 |
mvn clean | 清理 | 清理已经编译好的文件 |
mvn compile | 编译 | 将Java代码编程成class文件 |
mvn test | 测试 | 项目测试 |
mvn package | 打包 | 将项目打成jar或war包 |
mvn install | 安装 | 将jar包安装到本地仓库 |
mvn deploy | 部署 | 将jar包上传到私服 |
1、IDE中生成jar包,安装到本地仓库
使用IDEA或Eclipse就很简单了,点击相应指令就行。
2、使用mvn命令操作
Mvn install xxx
Mvn clear xxx
groupId、artifactId、version三个元素生成了一个依赖的唯一坐标。在所有仓库(个人仓库、私服、中央仓库)中必须是唯一的。
groupId : 团体、公司、组织机构等的唯一标识。团体标识的约定是它以创建这个项目的组织的域名逆向开头,如:org.apache.zookeeper。一个maven坐标必须包含groupId.
artifactId : 在该组织下所有项目中的唯一标识,一般是项目名称。
Version:项目的版本。项目迭代时经常会有多个版本。
<dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> <version>4.8.0</version> </dependency> |
Maven 一个重点部分, 使用 Maven 最主要的就是使用它的依赖管理功能。
1依赖的目的
当A.jar包用到了B.jar包中的某些类时,A就对B产生了依赖,这是概念上的描述。怎样在项目中以依赖的方式引入一个jar包呢?
就是使用dependency标签指定被依赖jar包的坐标就可以了。
<dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> <version>4.8.0</version> </dependency> |
如果有一个在编译时需要的jar包,而在发布时不需要,则可以用scope标记该包,并将其值设为provided。
依赖的范围有几个可选值, 一般场景用得到的是:compile、test、provided、runtime、system、important。
参数 | 描述 |
Compile | Scope的默认值,表示被依赖项目需要参与当前项目的编译、测试、运行阶段,是一个较强的依赖。打包时也要包含进去。 |
Provided | provided表示打包时可以打包进去,Web Container会提供。该依赖理论上可以参与编译、测试、运行等周期。 |
Runtime | 表示依赖不作用在编译阶段,但会作用在运行和测试阶段,如JDBC驱动适用于运行和测试阶段 |
System | 和provided相似,但是在系统中要以外jar包的形式提供,Maven不会在repository中查找它 |
Test | 表示依赖作用在测试阶段,不作用在运行阶段。只在测试阶段使用,用于编译和运行测试代码,不会随项目发布。 |
A依赖B,B依赖C,A能否使用C呢?
B依赖C的范围如果是compile,则可用,否则不可用。
如果在A工程中依赖B,B又依赖C,但是在A工程中不想使用C,这时候就可以排除C。需要用到C的其他版本可以再依赖进入。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> |
由于依赖具有传递性,经常会遇到版本冲突问题。
路径最短者优先: 最终依赖C-v1
路径相同时先声明者优先: 最终依赖C-v1
如果不想依赖C-v1,而要使用C-v2 , 就在A的坐标中排除C-v1即可。
如果要定义变量,可以在<properties></properties>标签中进行变量的定义,然后在其他节点中引用该变量。好处是:在依赖配置时引用变量,可以达到统一版本号的目的。
<properties> <java.version>1.8</java.version> <rocketmq-client.version>4.8.0</rocketmq-client.version> </properties> |
可以通过表达式${变量名}来调用
<dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> <version>${rocketmq-client.version}</version> </dependency> |
在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管理器。
在dependencyManagement下申明的dependencies,Maven并不会去实际下载所依赖的jar包,而是在dependencyManagement中用一个Map记录了jar的三维坐标。
而被仅仅是被dependencies包裹的元素,Maven是会去仓库实际下载所需要的jar包的,而至于需要下载什么
版本的jar包就有两种判断途径:
A:如果dependencies里的dependency自己没有声明version元素,那么maven就会到dependencyManagement里面去找有没有对该artifactId和groupId进行过版本声明,如果有,就继承它,如果没有就会报错,告诉你必须为dependency声明一个version
B:如果dependencies中的dependency声明了version,则以dependency里的version为准。
pom.xml //只是对版本进行管理,不会实际引入jar, 也不会下载jar <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> <version>4.8.0</version> </dependency> </dependencies> </dependencyManagement> //会实际引入jar包 <dependencies> <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> </dependency> </dependencies> |
插件一般用来配置编译环境和打包使用。
继承自spring-boot-starter-parent的SpringBoot项目配置编译打包插件
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> |
普通maven项目配置,想达到继承spring-boot-starter-parent的效果
<plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <!-- 主类全路径 ,可以直接填写类路径,或者${start-class} , 参考spring-boot-starter-parent的pom文件 --> <!--<mainClass>com.abc.test.Application</mainClass> --> <mainClass>${start-class}</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> <!--jdk编译版本--> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <!--跳过单元测试 --> <skipTests>true</skipTests> </configuration> </plugin> </plugins> |