Maven的核心概念
—2020年06月11日
什么是Maven
Maven是一款服务于Java平台的自动化构建工具。
约定的目录结构
目录结构:
- 根目录:工程名
- src目录:源码
- pom.xml文件:Maven工程的核心配置文件
- main目录:存放主程序
- test目录:存放测试程序
- java目录:存放java源文件
- resource目录:存放框架或其他工具的配置文件
为什么要约定目录结构
- Maven要负责我们这个项目的构建,以编译为例,Maven要想自动进行编译,那么它必须知道Java源文件保存在哪里。
- 如果我们自己定义的东西想要让框架或工具知道,有两种办法:
- 以配置的方式明确告诉框架 如:配置文件
- 遵守框架内部已经存在的约定 如:log4j.xml,log4j.properties
- 约定>配置>编码
POM
- 含义:Project Object Model 项目对象模型
- pom.xml对于Maven工程是核心配置文件,与构建工程相关的一切设置都在这个文件中进行配置。
坐标
使用下面三个向量在仓库中唯一定位一个Maven工程:
-
groupid:公司或组织域名倒叙+项目名
<groupId>org.springframework.boot</groupId>
-
artifactid:模块名
<artifactId>spring-boot-starter-parent</artifactId>
-
version:版本
<version>2.2.2.RELEASE</version>
Maven工程的坐标与仓库中路径的对应关系
坐标:
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
路径:
org/springframework/boot/spring-boot-starter-parent/2.2.2.RELEASE/spring-boot-starter-parent-2.2.2.RELEASE.jar
依赖
Maven解析依赖信息时会到本地仓库中查找被依赖的jar包。
对于我们自己开发的Maven工程,使用install命令安装后就可以进入仓库。
依赖的范围:
-
compile
- 对主程序是否有效 有效
- 对测试程序是否有效 有效
- 是否参与打包 参与
- 是否参与部署 参与
- 典型例子:spring-core
-
test
- 对主程序是否有效 无效
- 对测试程序是否有效 有效
- 是否参与打包 不参与
- 是否参与部署 不参与
- 典型的例子:junit
-
provided
- 对主程序是否有效 有效
- 对测试程序是否有效 有效
- 是否参与打包 不参与
- 是否参与部署 不参与
- 典型的例子:servlet-api.jar、jsp-api.jar
依赖的传递性
好处:可以传递的依赖不必在每个模块工程中重复声明,在依赖关系的最下面一层的工程中依赖一次即可。
注意:非compile范围的依赖不能传递,所以在各个模块工程中,如果需要就必须重复声明依赖。
依赖的排除
<exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions>
依赖的原则
-
作用:解决jar包的冲突问题
-
路径最短优先原则
根据依赖的传递性,MakeFriends可以选择log4j.1.2.17和log4j.1.2.14
MakeFriends和log4j.1.2.17距离是3,但是和log4j.1.2.14距离是2,所以选择log4j.1.2.14。
-
路径相同时先声明者优先
先声明指的是dependency标签的声明顺序
统一管理依赖版本
-
使用properties标签内使用自定义标签统一声明版本号
注意:properties标签不只是只能用于声明依赖的版本号,如编码格式UTF-8,凡是需要统一声明后再引用的场合都可以使用。
-
在需要统一版本的位置,使用“${自定义标签名}”引用声明的版本号
示例:
properties标签中声明了lombok.version标签,声明了project.build.sourceEncoding标签
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <lombok.version>1.18.6</lombok.version> </properties>
dependency标签中使用“${lombok.version}”引用了lombok.version标签中的值
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> <scope>provided</scope> </dependency>
仓库
仓库的分类
- 本地仓库:当前电脑上部署的仓库目录,为当前电脑上所有Maven工程服务
- 远程仓库:
- 私服:搭建在局域网环境中,为局域网范围内所有Maven工程服务
- 中央仓库:架设在Internet上,为全世界所有Maven工程服务
- 中央仓库镜像:为了分担中央仓库的流量,提升用户访问速度
仓库中保存的内容:Maven工程
- Maven自身所需要的插件
- 第三方框架或工具的jar包
- 我们自己开发的Maven工程
生命周期/插件/目标
生命周期
- 各个构建环节的执行顺序:不能打乱顺序,必须按照既定的顺序来执行
- Maven的核心程序中定义了抽象的生命周期,生命周期中各个阶段的具体任务是由插件来完成的。
- Maven核心程序为了更好的实现自动化构建,按照下面描述的特点执行生命周期中的各个阶段:不论现在要执行生命周期中的哪一个阶段,都是从这个生命周期最初的位置开始执行。
插件和目标
-
生命周期的各个阶段仅仅定义了要执行的任务是什么。
-
各个阶段和插件的目标是对应的。
-
相似的目标由特定的插件来完成。
生命周期阶段 插件目标 插件 compile compile maven-compilee-plugin test-compile testCompile maven-compilee-plugin -
可以将目标看做“调用插件功能的命令”
继承
-
现状
对于过个模块中的依赖,如junt,1号模块中使用了4.0版本,2号模块中使用4.0版本,但是3号模块中使用了4.9版本,由于test范围的依赖不能传递,所以必然会分散在各个模块中,很容易造成版本不一致。
-
需求
统一管理各个模块工程中对junit依赖的版本
-
解决思路
将junit依赖统一提取到“父“工程中,在子工程中声明junit依赖时不指定版本,以父工程中统一设定的为准,同时也便于修改
-
操作步骤
- 创建一个Maven工程作为父工程。注意:打包的方式pom
- 在子工程中声明对父工程的引用
- 将子工程的坐标中与父工程坐标中的重复内容删除
- 在父工程中统一管理junit的依赖
- 在子工程中删除junit依赖的版本号部分
-
注意
配置继承后,执行安装命令时要先安装父工程。
聚合
-
作用:一键安装各个模块工程
-
配置方式:在一个“总的聚合工程”中配置各个参与聚合的模块。
<!-- 配置聚合 --> <modules> <!-- 指定子工程 --> <module>config</module> <module>gateway</module> <module>filesystem</module> </modules>
-
使用方式:在聚合工程的pom.xml 执行 mvn install。