maven 的简单使用
maven 的简单使用
Jin概念
Maven 是一个依赖管理工具,为 Java 项目提供构建和依赖管理支持的工具
简单来说就是 jar包的仓库,依赖对应的 jar 包能够自动下载,不用自己到处找依赖 jar 包
配置 maven
下载 maven 下载连接
下载后解压到一个目录
核心配置文件 conf/settings.xml
配置本地仓库位置
默认本地仓库位置 用户家目录/.m2/repository
自定义本地仓库位置
在 conf/settings.xml 配置文件 找到 localRepository
标签
<localRepository>写入本地仓库的目录</localRepository>
注意:本地仓库本身也需要使用一个非中文、没有空格的目录
配置镜像源
maven 默认访问国外的中心仓库,下载速度较慢,要配置阿里云的镜像仓库
在 conf/settings.xml 配置文件 找到 mirror
标签
原来 id 为 maven-default-http-blocke
的镜像注释或删除掉
加入阿里云的镜像
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
配置 jdk
在 conf/settings.xml 配置文件 找到 profiles
标签
在里面加入
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
配置环境变量
确保要配置好 java 环境
linux 系统
在 /etc/profile
文件下加入环境变量
# 填写 maven 所在的目录
export MAVEN_HOME=/usr/local/apache-maven-3.8.5
export PATH=$PATH:$MAVEN_HOME/bin
window 系统
右键此电脑点击选择属性 ->高级系统设置->高级->环境变量
新建环境变量 :变量名 MAVEN_HOME
变量值 maven的路径
配置PATH:%MVNEN_HOME/bin%
配置验证
输入 mvn -v
查看是否有版本号
例如
idea 配置
设置->找到 maven 设置 配置好maven 主路径,设置文件,本地仓库
创建 maven
坐标
首先认识 maven 坐标
maven 中坐标是资源的
唯一标识
组成:
- groupId:定义当前Maven项目隶属组织名称(通常是域名反写,例如:org.mybatis)
- artifactId:定义当前Maven项目名称(通常是模块名称,例如 mybatis、junit)
- version:定义当前项目资源版本号
例如 mybatis 和 mysql 的依赖 jar 包
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
创建项目
使用命令创建项目
mvn archetype:generate
按照下面提示
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 7:【直接回车,使用默认值】
Define value for property 'groupId': com.example.maven
Define value for property 'artifactId': demo-maven-java
Define value for property 'version' 1.0-SNAPSHOT: :【直接回车,使用默认值】
Define value for property 'package' com.example.maven: :【直接回车,使用默认值】
Confirm properties configuration: groupId: com.example.maven artifactId: demo-maven-java version: 1.0-SNAPSHOT package: com.atguigu.maven Y: :【直接回车,表示确认。如果前面有输入错误,想要重新输入,则输入 N 再回车。】
建好项目目录结构
依赖在 pom.xml
配置
<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>
<!-- 当前Maven工程的坐标 -->
<groupId>com.example.maven</groupId>
<artifactId>demo-maven-java</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 项目打包方法:可选 jar war pom -->
<packaging>jar</packaging>
<name>demo-maven-java</name>
<url>http://maven.apache.org</url>
<properties>
<!-- 工程构建过程中读取源码时使用的字符集 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- 当前工程所依赖的jar包 -->
<dependencies>
<!-- 在dependency标签内使用具体的坐标
依赖我们需要的一个jar包
例如这里为 junit
-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<!-- scope 标签配置依赖的范围
默认值是 compile
test 在测试环境生效
-->
<scope>test</scope>
</dependency>
</dependencies>
</project>
要导入其他依赖包 添加该包的坐标信息到 dependencies 下
查找其他包的信息:https://mvnrepository.com/
例如 mybatis
选择版本信息,推荐使用人数多的
复制坐标信息添加到 pom.xml 即可
创建 web 项目
使用命令
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DarchetypeVersion=1.4
目录结构和上面的目录在java同目录下多了一个 webapp 目录,用来编写web工程
构建命令
构造命令要在 maven 项目根目录下执行,即 pom.xml 目录下
命令 | 描述 |
---|---|
mvn clean | 清理操作:删除 target 目录 |
mvn compile / mvn test-compile | 编译操作:存放的目录 target/classes ; 测试程序编译 target/test-classes |
mvn test | 测试操作:报告存放的目录:target/surefire-reports |
mvn package | 打包操作:结果jar 包,存放的目录:target |
mvn install | 安装操作:构建过程中生成的 jar 包存入 Maven 本地仓库,路径是根据它的坐标生成 |
跳过测试
mvn 指令 -D skipTests
idea 项目用可视化 maven 构建命令
idea 里跳过测试
依赖管理
依赖的范围
maven的依赖范围用
<scope>
元素表示的,例如上面的 junit scope为test
依赖范围有六种: compile、test、provided、runtime、import和system
常用的前面4种
- compile:编译依赖, 是默认的依赖范围,在 main 和 test 都可以访问这个范围的依赖,服务器可访问,布署到 tomcat下时, 把这个依赖放置在 WEB-INF 下的 lib 文件夹里面
- test:测试依赖,是测试使用的。test目录下可访问,main目录下的代码不能访问这个依赖,服务器不可访问
- provided:提供依赖 在 main 和test 目录的代码可以访问这个依赖,服务器不可访问
- runtime:运行依赖,main目录下的代码不能访问这个依赖, test目录可以访问,服务器可访问
作用域
依赖范围 | 对于编译执行环境有效 | 对于测试执行环境有效 | 对于运行时执行环境有效 | 例子 |
---|---|---|---|---|
compile | ✔ | ✔ | ✔ | spring-core |
test | ✖ | ✔ | ✖ | junit |
provided | ✔ | ✔ | ✖ | servlet-api |
runtime | ✖ | ✔ | ✔ | jdbc |
总结:
compile是缺省设置,需要在开发的整个过程中都用到
test 只是在测试过程中用到,所以不需要在main目录下使用,也不需要发布到服务器中
provided意思是,这种jar包是tomcat已经提供的了,所以不需要像compile那样打包时再打进去。例如servlet-api、jsp-api,此时,如果强行改为缺省的compile,则可能会引起冲突报错
依赖的传递
如果我们项目引用的 jar 包 ,该 jar 包又引用了其他 jar 包,这就是传递依赖,默认编译项目时 Maven 会把直接引用和间接引用的Jar包都下载到本地仓库
传递的原则
在 A 依赖 B,B 依赖 C 的前提下,C 是否能够传递到 A,取决于 B 依赖 C 时使用的依赖范围。
- B 依赖 C 时使用 compile 范围:可以传递
- B 依赖 C 时使用 test 或 provided 范围:不能传递,所以需要这样的 jar 包时,就必须在需要的地方明确配置依赖才可以
传递的冲突
项目 需要引入依赖包A,依赖包A又引入了依赖包C,那么B是项目的直接依赖,C是项目的传递依赖。如果项目还需要引入依赖包B,依赖包B也引用了依赖包C,当依赖包A引用的C和依赖包B引用的C版本不同时,则发生了依赖冲突
Maven中采用了两种避免冲突的策略:
- 短路径优先:哪一个传递依赖离它最近则就优先选择它
- 声明优先:(上面图情况)谁先声明的就先选择谁,即在 pom.xml 里先写的优先
因此在Maven中实际上是不存在依赖冲突的
依赖的排除
项目A依赖于B,B依赖于C,但有可能C依赖是不兼容的,会对项目造成一定的影响。此时,我们可以使用关键字exclusion排除C依赖
<dependency>
<groupId>com.example.maven</groupId>
<artifactId>demo-maven-java</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
<!-- 使用excludes标签配置依赖的排除 -->
<exclusions>
<!-- 在exclude标签中配置一个具体的排除 -->
<exclusion>
<!-- 指定要排除的依赖的坐标(不需要写version) -->
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
继承和聚合
继承
Maven工程之间,A 工程继承 B 工程,本质上是 A 工程的 pom.xml 中的配置继承了 B 工程中 pom.xml 的配置
使用继承的目的是为了消除重复性,常用的是把子模块 pom 中很多相同的依赖配置提取出来,统一锁定在父模块的pom中。如:grouptId、artifactId、version等等。在使用的时候子模块会直接继承父模块的依赖版本号,子模块中不再需要指定具体版本号,方便统一管理项目的依赖问题
操作
父工程
工程创建好之后,要修改它的打包方式:
<groupId>com.example.maven</groupId>
<artifactId>demo-maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 当前工程作为父工程,它要去管理子工程,所以打包方式必须是 pom -->
<packaging>pom</packaging>
注意的是父模块坐标中的packaging必须是pom类型,否则子模块就不会继承
创建子工程
在父工程目录里,IDEA右击项目选择 Module maven项目 或者 mvn archetype:generate 命令来创建模块工程
例如
子模块 pom 配置
<!-- 使用parent标签指定当前工程的父工程 -->
<parent>
<!-- 父工程的坐标 -->
<groupId>com.example.maven</groupId>
<artifactId>demo-maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>>
</parent>
父工程配置依赖统一管理
<!-- 集中定义依赖版本号 -->
<properties>
<spring.version>5.2.6.RELEASE</spring.version>
<junit.version>4.12</junit.version>
</properties>
<!-- 版本锁定,当子模块中有需要并且自行添加了具体依赖后才有效,
它仅仅是起到锁定作用,不下载依赖包 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
子模块设置依赖
<!--依赖包的下载仍然有dependencies管理-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<!-- 版本号由父模块里面统一指定不再需要特别指定 -->
<!--<version>4.12</version>-->
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
</dependencies>
聚合
使用一个“总工程”将各个“模块工程”汇集起来,作为一个整体对应完整的项目
一键执行 Maven 命令:很多构建命令都可以在“总工程”中一键执行
配置聚合之后,各个模块工程会在总工程中展示一个列表,让项目中的各个模块一目了然
配置:在总工程中配置 modules 即可
前面继承例子中的Child1、Child2和Child3这三个模块,我们对它进行聚合
<!--在父模块中聚合-->
<modules>
<module>Child1</module>
<module>Child2</module>
<module>Child3</module>
</modules>