关于 Maven,这几个一定要会的知识点,你真的了解吗?
各个生命周期预设的定义如下:
运行任何一个阶段,都会从其所在生命周期的第一个阶段开始,顺序执行到指定的阶段,如:
mvn package(本义:执行 default 周期的 package 阶段,maven 会自动从 process-resources 阶段开始运行到 package 阶段结束)
4. maven 的插件
插件 plugin 是绑定到生命周期,承担实际功能的组件。mvn 运行时,自动关联插件来运行
下图是 maven 默认的各阶段对应的插件列表:
六、常用 Maven 命令
mvn clean 清理
mvn compile 编译主程序
mvn package 打包
mvn install 安装 jar 到本地库
使用 maven 命令生成项目(idea 和 eclipse 生成项目最终也是依赖 maven 插件生成的):
mvn archetype:generate -DgroupId=enjoy -DartifactId=simple -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0
mvn archetype:generate -DgroupId=enjoy -DartifactId=simple-web -DarchetypeArtifactId=maven-archetype-webapp -Dversion=1.0
七、Maven 插件开发
可以自定义插件,来扩展 maven 的功能。插件的开发步骤如下:
1. 引入 maven api 依赖
2. 编写简单 Mojo 类(继承 AbstractMojo)
![image.png](https://upload-images.jianshu.io/upload_images/2461310
1-d8c9e348d8de5b34.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
3. 执行插件
mvn com.enjoy:enjoy-plugin:1.0:log
4. 关联插件到生命周期来执行
构建项目对应的生命周期
八、Maven 坐标与依赖
1. 坐标
--------在数学中, 任何一个坐标可以唯一确定一个“点”
Maven 中坐标是 Jar 包的唯一标识
坐标元素包括 groupId、artifactId、version、packaging:
2. 依赖
依赖即:A->B,B->C,C->D 这种项目间的依存关系。
在 java 的 jvm 内,依赖的最终表现是,项目 A 启动时,其依赖的 jar 包必须都对应放入其 classpath 路径内。
3. 依赖传递
上述过程中,项目 Mall 归结起来,依赖的 fastjson 会有三个版本。
而我们的 jvm 最终肯定只能接受一个版本的 jar,所以必须有所取舍。
maven 默认的取舍规则是:
1、路径最短原则:product 和 customer 里的 fastjson 引用路径较短,路径为两步;pay 项目里的 fastjson 引用路径较长,路径为三步。因此 pay 中的 fastjson 被淘汰;
2、同路径长度下,谁先声明谁优先:product 和 customer 中的 fastjson 路径相同,那么就看在 pom 中是先声明 product 还是先声明 customer,谁先用谁的。
4. 依赖冲突及解决
在依赖传递里,我们看到,maven 根据自己的规则为我们取舍出了一个版本的 jar,但此 jar 版本选择可能会与我们的项目预期不符:
例如:我们最终想的版本是 fastjson:1.2.30 版本(但它在第一步即被淘汰掉了)
当出现此类情况时,我们项目运行可能会出错(项目中使用到了 1.2.30 版本的特性),此问题即是我们常遇到的 jar 包冲突问题。
补救方式:使用 exclusions 将 product 和 customer 中的 fastjson 包排除掉,用法如下图:
当发生 jar 冲突程序报错时,可以使用 mvn 命令查出项目最终依赖的 jar 包树,看版本是否是我们预期的:
命令:mvn dependency:tree
5. 依赖范围 scope
mvn 在运行时,生命周期的不同阶段,会有不同的依赖范围,一般有以下依赖范围 scope:
compile:默认范围,用于编译(依赖的 jar 在打包时会包含进去)
provided:类似于编译,但支持你期待 jdk 或者容器提供,类似于 classpath(依赖的 jar 在打包时不会包含进去)
runtime:在执行时需要使用(依赖的 jar 在打包时会包含进去)
test:用于 test 任务时使用(依赖的 jar 在打包时不会包含进去)
system:需要外在提供相应的元素。通过 systemPath 来取得(一般禁止使用)
每个 scope 实际上是配置了一个不同的 classpath,jvm 根据选择不同的 classpath 来达到依赖不同
九、环境激活-profiles 使用
在 springmvc 项目中,开发/测试/线上三个不同环境,配置文件往往也不同。
打包时需要对配置文件做出选择(maven 提供了 profiles 机制供我们使用)。
1. profiles 的场景
[图片上传失败...(image-d072b5-1606207243473)]
这个选择,实际发生在 default 生命周期的 resource 阶段(maven-resources-plugin 执行过程里)
2. 定义 profiles
为了指导插件将对应的 resource 文件打入 classpath 里,先定出 profiles
此定义即指,当 mvn 命令执行时,我们需要通过 -P dev 或者-P test 方式传入我们的意图:
dev/test 选择,会导致 properties 里的变量值含义不同,我们主要关注 package.environment 变量
3. 资源插件的配置指定
配置 maven-resources-plugin 插件执行时,要复制的目录资源
4. mvn 约定的资源中需要过滤掉环境目录
需要将 mvn 约定的资源目录里,过滤掉环境目录
5. 小属性更轻便的用法
对于简单的属性,我们可以选择更轻便的用法
① 直接在环境中定义属性值
② 项目属性文件配置
③ 约定的资源启用替换过滤
最后有对 pom.xml 里面各标签有疑惑的小伙伴,下面附上 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/maven-v4_0_0.xsd ">
<!-- 产生的构件的文件名,默认值是{version}。 --><finalName></finalName>
评论