Maven学习笔记

Maven学习

前言:
2020年,在部署项目上线时,遇到一些Maven问题,浪费了很多时间,决定系统学习一下每天都在用的Maven。
Maven视频地址

1、Maven之前项目问题
  1. 一个项目就是一个工程

    • 如果项目庞大,需要划分模块
    • Maven可以将一个项目拆分多个工程
  2. 项目中需要的jar包必须手动导入到WEB-INF/ilb目录下

    • 同样的jar包出现在不同的项目工程中,浪费存储空间,也让项目臃肿
    • maven可以将jar统一保存在“仓库”中,需要使用时,引用即可
  3. jar需要别人为我们准备好,或者到官网下载

    • 不同技术的官网下载jar不一致
    • 下载内容可能存在风险
    • Maven以规范的方式下载jar包,第三方工具jar按照规范存放在了Maven中央仓库中
  4. 一个jar包依赖的其他jar包需要自己手动加入到项目中

    FileUpload组件–>IO组件。依赖其他。

2、Maven是什么
  • 服务于java平台的自动化构建工具。

    Make–>Ant–>Maven–>Gradle

  • 构建

    • 概念:以“java源文件”、“配置文件”、“jsp”、”HTML“、“图片”等资源为原材料,去生产一个可以运行的项目过程。
      • 编译:javac
      • 部署:一个动态Web工程运行并不是本身,而是web工程的“编译结果”
      • 搭建:
3、Maven运行时环境(rt.jar–>runtime.jar)
4、自动化构建和构建环节

构建过程

  1. 清理:将之前编译旧的class字节码文件删除
  2. 编译:javac生产新的class字节码文件
  3. 测试:自动测试,自动调用junit程序
  4. 报告:测试程序执行的结构
  5. 打包:Web工程打war包,java打jar包
  6. 安装:Maven特点概念—将打包得到文件复制到“仓库”中的制定位置
  7. 部署:将war包复制到Servlit容器知道目录下,使之可运行

自动化构建

5、Maven核心概念
  1. 约定的目录结构

    原因

    • 知道需要的文件的位置
    • 自定义框架或工具知道
      • 以配置的方式明确告诉框架
      • 遵守框架内部已存在的约定
    • 约定>配置>编码
  2. POM

  3. 坐标

  4. 依赖

  5. 仓库

  6. 生命周期/插件/目标

  7. 继承

  8. 聚合

6、常用Maven命令
  1. 注意:执行与构建过程相关的Maven命令(编译、测试、打包),必须进入pom.xml所在的目录

  2. 常用命令

    • mvn clean:清理
    • mvn compile:编译主程序
    • mvn test-compile:编译测试程序
    • mvn text:执行测试
    • mvn package:打包
    • mvn install:安装
    • mvn site:生产站点
7、联网问题
  • Maven核心程序仅定义了抽象的生命周期,但具体工作必须有特定的插件完成,插件并不属于核心程序。
  • 执行Maven插件时,优先在本地仓库查找
  • 本地仓库位置:【系统用户加目录】\m2\repository
  • Maven核心程序如果不存在需要的插件,那么它会自动连接外网,到中央仓库下载
  • 无网络,则构建失败
8、POM
  • 概念:Porject Object Model 项目对象模型
  • Pom时Maven项目的核心配置文件,与构建过程相关的一切设置都在这个文件中进行配置
9、坐标
  • 坐标作用:数学唯一定位一个点

  • Maven坐标(gav)

    使用下面三个向量在仓库中唯一定位一个Maven工程

    • groupid:公司或者组织名倒叙+项目名
    • artifactid:模块名称
    • version:版本号
  • maven工程坐标与仓库中路径的对应关系

10、仓库
  • 本地仓库:idea设置的目录
  • 远程仓库:
    • 私服(Nexus):搭建在局域网中,为局域网范围内的所有Mavengc服务
    • 中央仓库:架设在Internet上,为全世界所有Maven工程服务
    • 中央仓库镜像:为了分担中央仓库流量,提升用户访问速度
  • 仓库保存内容:Maven工程
    • Maven自身所需要的插件
    • 第三方架构或工具类jar包
    • 自己开发的Maven工程
11、依赖

自己maven项目的使用

  1. Maven解析依赖信息时会到本地仓库查找被依赖的jar包
  2. 自己开发的Maven工程使用Install命令安装后,进入仓库

依赖的范围

  • compile:编译
  • test:测试 junit
  • provided:提供 servlet-api.jar
Maven命令对主程序有效对测试程序有效参与打包
compile有效有效参与
test无效有效不参与
provided有效有效不参与

依赖的传递性

  • 好处:可以传递的依赖不必在每个模块工程中都重复声明,在"父类"的工程中依赖一次即可
  • 注意:非compile范围的无法传递

依赖的排除

  • 将通过依赖传递性传入的依赖排除出本工程

  • 实现:

  • <exclusions>
       <exclusion>
          <groupId>org.junit.vintage</groupId>
          <artifactId>junit-vintage-engine</artifactId>
       </exclusion>
    </exclusions>
    

依赖的原则

  • 作用:解决模块之间jar包冲突问题
  • 优先级别:jar版本由于依赖冲突时,就近依赖先声明优先

统一管理依赖版本

  • 配置方式

    1. 使用properties标签内使用自定义标签统一声明版本号
    2. 在需要统一版本的位置,使用$(自定义标签名)引用声明的版本号
    <properties>
       <java.version>1.8</java.version
    </properties>
    
12、生命周期
  1. 各个构建环节的顺序:按照正确的顺序执行
  2. Maven核心程序定义了抽象的生命周期,生命周期中各个阶段的具体任务是由插件来完成的
  3. Maven核心程序,为了更好实现自动化构建,按照这一的特点执行生命周期中的各个阶段:无论现在要执行生命周期的哪一阶段,都要从生命周期最初的位置开始执行。

插件和目标

  • 生命周期的各个阶段仅仅定义了要执行的任务是什么
  • 各个阶段和目标时对应的
  • 相似的目标有特定的插件来完成

依赖范围

生命周期阶段插件目标插件
compilecompilemaven-compiler-plugin
test-compiletestcompilemaven-compiler-plugin

依赖的Scope

scope定义了类包在项目的使用阶段。项目阶段包括: 编译,运行,测试和发布。

分类说明
compile
默认scope为compile,表示为当前依赖参与项目的编译、测试和运行阶段,属于强依赖。打包之时,会达到包里去。
test
该依赖仅仅参与测试相关的内容,包括测试用例的编译和执行,比如定性的Junit。
runtime
依赖仅参与运行周期中的使用。一般这种类库都是接口与实现相分离的类库,比如JDBC类库,在编译之时仅依赖相关的接口,在具体的运行之时,才需要具体的mysql、oracle等等数据的驱动程序。
此类的驱动都是为runtime的类库。
provided
该依赖在打包过程中,不需要打进去,这个由运行的环境来提供,比如tomcat或者基础类库等等,事实上,该依赖可以参与编译、测试和运行等周期,与compile等同。区别在于打包阶段进行了exclude操作。
system
使用上与provided相同,不同之处在于该依赖不从maven仓库中提取,而是从本地文件系统中提取,其会参照systemPath的属性进行提取依赖。
import
这个是maven2.0.9版本后出的属性,import只能在dependencyManagement的中使用,能解决maven单继承问题,import依赖关系实际上并不参与限制依赖关系的传递性。
systemPath
当maven依赖本地而非repository中的jar包,sytemPath指明本地jar包路径,例如:

<dependency>
    <groupid>org.hamcrest</groupid>
    <artifactid>hamcrest-core</artifactid>
    <version>1.5</version>
    <scope>system</scope>
    <systempath>${basedir}/WebContent/WEB-INF/lib/hamcrest-core-1.3.jar</systempath>
</dependency>

dependency中的type
引入某一个依赖时,必须指定type,这是因为用于匹配dependency引用和dependencyManagement部分的最小信息集实际上是{groupId,artifactId,type,classifier}。在很多情况下,这些依赖关系将引用没有classifier的jar依赖。这允许我们将标识设置为{groupId,artifactId},因为type的默认值是jar,并且默认classifier为null。
type的值一般有jar、war、pom等,声明引入的依赖的类型

dependency中的classifier
Classifier可能是最容易被忽略的Maven特性,但它确实非常重要,我们也需要它来帮助规划坐标。设想这样一个情况,有一个jar项目,就说是 dog-cli-1.0.jar 吧,运行它用户就能在命令行上画一只小狗出来。现在用户的要求是希望你能提供一个zip包,里面不仅包含这个可运行的jar,还得包含源代码和文档,换句话说,这是比较正式的分发包。这个文件名应该是怎样的呢?dog-cli-1.0.zip?不够清楚,仅仅从扩展名很难分辨什么是Maven默认生成的构件,什么是额外配置生成分发包。如果能是dog-cli-1.0-dist.zip就最好了。这里的dist就是classifier,默认Maven只生成一个构件,我们称之为主构件,那当我们希望Maven生成其他附属构件的时候,就能用上classifier。常见的classifier还有如dog-cli-1.0-sources.jar表示源码包,dog-cli-1.0-javadoc.jar表示JavaDoc包等等。

classifier它表示在相同版本下针对不同的环境或者jdk使用的jar,如果配置了这个元素,则会将这个元素名在加在最后来查找相应的jar,例如:

jdk17
jdk18

13、继承

统一各个模块工程中junit依赖的版本(依赖传递无法传递test范围的依赖,造成版本不一致)

解决:将junit依赖统一提到“父”工程中,子工程声明junit依赖时不指定版本,以父工程中设定为准,同时也便于修改。

具体实现

  1. 创建一个Maven工程作为父工程
  2. 在子工程中声明对父工程的引用
  3. 将子工程的坐标与父工程坐标中重复的内容删除
  4. 在父工程中统一junit的依赖
<dependencyManagement>
   <dependencies>
      
   </dependencies>
</dependencyManagement>
  1. 在子工程中删除junit依赖的版本号部分

14、聚合

问题:继承后,父工程丢失

作用:一键安装各个模块工程

配置方式:在一个总的聚合工程中配置各个参与聚合的模块

<modules>
   <module></module>
</modules>
15、web工程自动部署
<build>	<build>
		<!--工程打包的包名-->
		<finalName>test</finalName>
		<!--配置构建过程中需要使用到的插件-->
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<!--什么时候运行-->
				<executions></executions>
			</plugin>
		</plugins>
	</build>
   <plugins>
      <plugin>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-maven-plugin>
         </artifactId>
      </plugin>
   </plugins>
</build>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值