本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一.引入
Maven有什么作用?
1.管理规模庞大的jar包。
2.脱离IDE环境执行构建操作
Maven工作机制
编辑
Maven配置
Step1:配置Maven核心程序
去官网下载压缩包
Step2:指定本地仓库
默认仓库在C盘,而C盘是系统盘。
可以将仓库放在D盘。
编辑
在核心程序的conf文件下的settings中修改。
编辑
Step3:配置阿里云提供的镜像仓库
本地仓库如果没有相关的jar包,就需要访问中央仓库,中央仓库在国外,访问速度慢,但可以访问阿里云提供的镜像仓库。
编辑
Step4:配置JDK
因为Maven也是用Java写的
Step5:配置Maven
配置MAVEN_HOME,指向bin的上一级
配置PATH,指向bin
二.Maven的命令行环境
1.创建Maven版的Java工程
1)坐标的概念去理解jar包地址
类似于数学中的坐标,空间中三个坐标确定一个点
编辑
项目是包含多个工程的。
编辑
编辑
编辑
2)创建目录作为工作空间
此时有了三个目录
- Maven核心程序:运筹帷幄之地
- Maven本地仓库:兵营
- 本地工作空间:战场
编辑
3)使用命令生成Maven工程
运行 mvn archetype:generate命令
编辑
运行后,会从阿里云镜像仓库中下载必要的资源到中央仓库。
并且在工作空间中生成工作目录。
在工作目录中创建了一个工程
编辑
解读pom.xml
pom文件是maven工程的核心配置文件,后续所要做的所有配置都是在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"> <!-- 代表pom.xml所采用的标签结构--> <modelVersion>4.0.0</modelVersion> <!--坐标的信息 groupId标签:代表公司或组织开发的某一个项目 artifactId标签:代表项目下的某一个模块 version标签:代表当前模块的版本 packaging:打包方式,默认以jar包方式打包,说明这是Java工程。 如果取值是war,说明是web工程,如果是pom,说明这个工程管理其他工程的工程。 --> <groupId>qdu.maven</groupId> <artifactId>pro01-maven-java</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>pro01-maven-java</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- dependency标签:配置一个具体的依赖信息--> <dependency> <!-- 想导入哪个jar包,就配置它的坐标信息即可--> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <!-- scope标签:配置当前依赖的范围--> <scope>test</scope> </dependency> </dependencies> </project>
3)Maven的构建命令
编辑
编辑
target目录是存放编译结果的
编辑
在pom.xml中添加说明jdk版本的信息
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.encoding>UTF-8</maven.compiler.encoding> <java.version>16</java.version> <maven.compiler.source>16</maven.compiler.source> <maven.compiler.target>16</maven.compiler.target> </properties>
编辑
编辑
编辑
Java工程打jar包
web工程打war包
编辑
安装就是把打包的jar包放到本地仓库中
生成和jar包同名的.pom文件存到仓库中,这个文件中的信息就是项目的pom.xml中的信息
jar包的名字根据在pom.xml中的设置的项目坐标来确定
编辑
编辑
2.创建Maven版的Web工程
1)使用命令创建
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DarchetypeVersion=1.4
编辑
2)添加依赖
在Maven管理下的Web工程就不需要创建lib导入jar包了
编辑
可以直接在pom.xml文件下加入依赖
3)编译
mvn compile
在含义该web项目的pom.xml路径上运行该命令
4)打包
mvn package
编辑
在该web项目的target路径下生成了war包,war包上面就是解压后的程序目录。二者内容是一样的。
5)把war放到tomcat上部署运行
可以将war包或者直接将解压文件放到tomcat的webapp下
在命令行中启动tomcat的startup.bat。
3.让Web工程依赖Java工程
具体操作
编辑
2.将打包后的Java工程的jar包的坐标放到Web工程中的dependency中scope标签写compile,因为执行mvn install后,jar就放到了本地仓库了。
3.需要测试依赖可不可用,就把Java工程中的测试拷贝到Web工程,将如果测试类可以跑,那么就说明Java工程依赖导入成功了。
4.将Web工程打包后,会在WEB-INF下的lib中看到依赖的jar包
mvn dependency:list 可以查看依赖列表,也就是依赖了哪些jar包。
mvn dependency:tree 可以查看依赖之间的关系,有时候一个依赖也会依赖别的jar包。
测试依赖的范围
dependency中的scope属性
标签的可选值:compile/provided/test/system/runtime/import
编辑
在main目录的Java代码中引入带有@TEST的包,main就不能编译了。
编辑
provided方式时,打包war包时该jar就不会包含到war包里面。然后也就不部署到服务器上。
编辑
依赖的传递
A依赖B,B依赖C,那A能不能使用B依赖的jar包?
如果B依赖C的方式是compile,就能传递,如果是test或provided就不能传递。
A是自己写的Java工程,B是Spring-core,C是commons-logging。
A依赖B,编译A时,去本地仓库找B,找不到B就去中心仓库下载B。
这时想让web项目D依赖A。
A之前在未依赖B时编译安装过,在本地仓库中。如果这时让D依赖A,去本地仓库中找到的A是没有依赖B的jar包。想让D也可以依赖B,需要重新编译安装A。
B依赖的junit是范围是test,在A中依赖的jar中就找不到junit,所以test不能传递。
依赖的排除
编辑
阻断依赖的传递。
假如A依赖B和C,B和C同时依赖D的不同的版本,那么D的这两个版本会传递到A,就会可能发生冲突。
如果需要C依赖的D的那个版本,就需要在A依赖B时做一个阻断,阻断A依赖B的D。
使用exclusions标签配置依赖的排除
<exclusions>
在exclusion标签中配置一个具体的排除
<exclusion>
指定要排除的依赖的坐标,不需要写version
<groupId></groupId>
<artifactId></artifactId>
<exclusion>
</exclusions>
在A依赖B的位置排除对D的依赖
3.继承
A工程继承B工程,本质上是A工程的pom.xml中的配置继承了B工程中pom.xml的配置
继承的作用
在父工程中统一管理依赖信息,具体说是管理依赖信息的版本。
比如A,B,C,D都用到了一个依赖S,那么就可以通过继承向上抽取。
依赖的版本号需要指明,除非这个依赖的父工程中指明了版本号,或者再往上追溯可以追溯到。
对继承的使用
使用Spring时,要求所有的Spring的jar包版本一致。
Step1:mvn archetype:generate
创建父工程,跟创建普通Java工程的方式一样。
Step2:修改pom文件方式中的打包方式
父工程的打包方式为pom,打包方式为pom的Maven工程不写业务代码。它专门用来管理其他Maven工程。
编辑
Step3:创建模块工程,也就是子工程,在pro03-maven-parent下面创建。
创建子工程后,在父工程中会自动出现下面内容
编辑
子工程中也有类似的代码会自动出现
编辑
子工程的groupId和version要是和父工程的相同,则可以省略
在父工程中管理依赖
通过dependencyManagement标签来管理
<!-- 在父工程中统一管理依赖--> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.0.0.RELEASE</version> </dependency> </dependencies> </dependencyManagement>
虽然在父工程中写了要管理的依赖,但是父工程做的只是管理这个依赖的版本号。
在子工程中还是要添加依赖的,但是不用指定依赖的版本号,这个版本号在父工程中指明了。
如果在子工程中又添加了版本号,那么以子工程中的版本号为主。
子工程需要什么依赖就写什么依赖,不需要和父工程中的标签的内容相同。
父工程管理的好处就是可以统一的更改子工程依赖的版本号
继承-配置自定义属性
为了版本号的实现一处修改,处处生效的效果。
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <mySpringVersion>4.1.0.RELEASE</mySpringVersion> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${mySpringVersion}</version> </dependency> </dependencies> </dependencyManagement>
在标签中配置自定义标签,并添加属性值。
在标签中使用变量的形式。
相当于定义一个变量。
继承的实际意义
编辑
继承(聚合)的好处
在安装操作时(将jar包放到本地仓库),maven要求有父工程先安装父工程,有依赖的工程先安装被依赖的工程。所以在工程聚合之后,许多mvn命令都可以一键完成。
依赖的时候不要循环依赖,不然安装命令时就会报错。
比如A依赖B,B依赖C,C依赖A。
三Maven的IDEA环境
1.创建父工程
Create from archetype勾选不同的选项创建的目录不同,在这里可以不选。
编辑
2.配置Maven信息
设置maven的路径
编辑
3.创建Java模块工程
在父工程中创建module,创建完成后,父工程和子工程的pom文件都会做自动的修改。
pom文件中的打包方式改为pom,并加上子模块信息,子模块的pom文件中也会加上父模块的信息。
编辑
右侧来管理maven,install命令包含测试打包编译。
执行一个命令会从它声明周期最开头开始执行。
编辑
点击m可以手动输入要执行的命令,比如一次要进行多个命令
编辑
编辑
注意右上角是在哪个范围内执行,有project范围和module范围。
还可以添加选项,比如执行命令的过程中跳过测试
编辑
还可以通过IDEA进来命令行
编辑
4.创建Web模块工程
Step1:首先创建一个普通的maven module。
Step2:在pom文件中添加war
Step3:
编辑
5.导入
导入Maven项目
file-open 直接选择要导入的项目的pom.xml文件所在的目录
导入Maven模块
先将模块(文件夹)复制到Maven项目下。
编辑
进行设置
编辑
编辑
直接导入pom.xml文件也可以
四.Maven的核心概念
1.POM
编辑
编辑
编辑
2.Maven目录结构
编辑
src:源码目录
main:主体程序目录
test:测试程序目录
resources:配置文件
编辑
3.生命周期
为了构建过程自动化完成,Maven设定了三个生命周期,生命周期的每一个环节对应构建过程的一个操作
三个生命周期
编辑
编辑
在同一个生命周期中,执行某个操作,在这个生命周期下的这个操作的前面所有操作都会被自动执行。
比如执行install会自动执行package和compile,但不会执行clean,因为clean和install所处的生命周期不同。
4.插件和目标
插件
Maven的核心程序仅仅负责宏观调度,不做具体的工作,具体工作都是由maven插件完成的,例如编译就是由maven-compiler-plugin-3.1.jar插件来执行的。
一个插件就是本地库中的一个具体的jar包。点开就可以看到有哪些具体的目标
编辑
目标
一个插件可以对应多个目标,每一个目标都和生命周期中的某一个环节对应。
Defalut生命周期中有compile和test-compile两个和编译相关的环节,这两个环节对应compile和test-compile两个目标,而这两个目标都是由maven-compiler-plugin-3.1.jar插件来执行的。
目标其实就是插件的某个功能。
5.仓库
编辑
如果有自己搭建的Maven私服,则本地仓库没有会先访问Maven私服,Maven私服没有再访问中央仓库或镜像仓库。
\