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。
 



















