Maven基础(二)

目录

一、Maven常用命令

二、Maven依赖

[1. 概念](#1. 概念)

[2. 依赖管理](#2. 依赖管理)

[3. 依赖范围](#3. 依赖范围)

[4. 依赖传递性](#4. 依赖传递性)

[5. 依赖排除](#5. 依赖排除)

[6. 依赖的原则](#6. 依赖的原则)

[7. 使用自定义标签统一版本](#7. 使用自定义标签统一版本)

三、Maven生命周期

[1. 概念](#1. 概念)

[2. Maven内置三套相互独立的生命周期](#2. Maven内置三套相互独立的生命周期)

四、Maven继承

[1. 概念](#1. 概念)

[2. Maven继承的语法](#2. Maven继承的语法)

五、Maven聚合

[1. 概念](#1. 概念)

[2. 聚合的语法](#2. 聚合的语法)

六、Web工程的自动部署

[1. 自动部署配置](#1. 自动部署配置)


一、Maven常用命令

(1) mvn clean

删除target目录,清理构建文件。‌‌

(2) mvn compile

编译主代码,生成class文件到target/classes目录。‌‌

(3) mvn test-compile

编译测试代码,生成class文件。

(4) mvn test

执行单元测试,验证代码正确性。‌‌

(5) mvn package

打包项目为JAR/WAR文件,输出到target目录。‌‌

(6) mvn install

将包安装到本地仓库,供其他项目引用(放入的位置是通过gav决定)。

(7) mvn site

生成站点。

说明:

  1. 执行与构建过程相关的Maven命令时,必须进入pom.xml所在的目录,如:编译、测试、打包等。

  2. 第一次执行命令时,因为需要下载执行该命令的基础环境,所以会从中央仓库下载该环境到本地仓库。

二、Maven依赖

1. 概念

Maven解析依赖信息时会到本地仓库中查找被依赖的jar包。对于自己开发的Maven工程,使用install命令安装后就可以进入仓库。

2. 依赖管理

Maven通过<dependency>元素在pom.xml中管理项目依赖。它支持自动依赖解析和冲突解决,减少了手动管理依赖的复杂性。

A中的某些类需要使用B中的某些类,则称为A依赖于B。在maven项目中,如果要使用一个当时不存在的jar包或模块,则可以通过依赖实现(去仓库中寻找并下载)。

如果A.jar依赖B.jar,当通过pom.xml引入A.jar时,Maven会自动引入B.jar

3. 依赖范围

说明:

(1) 默认范围是:‌compile

(2) system依赖范围与provided一样,但必须显式提供本地JAR文件的路径。这

种依赖不会被包含在最终的部署包中。

4. 依赖传递性

依赖的传递性指的是一个项目A的依赖可以被另一个依赖于项目A的项目B间接使用。如果有项目C依赖于项目B,则项目C也可以间接使用项目A的依赖。

如果: 项目C-->项目B-->项目A-->spring-core.jar
**则:**项目C和项目B可以间接使用spring-core.jar

(1) 依赖传递性的工作原理

**① ‌声明依赖‌:**在项目的pom.xml文件中,你可以通过<dependencies>标签声明

项目直接依赖的库。

**② 解析依赖‌:**Maven会解析这些直接依赖,并查找这些库的pom.xml文件,以确

定它们自己的依赖。这个过程是递归的,Maven会继续解析每个依赖的依赖,直到所

有必要的依赖都被解析出来。

**③ ‌冲突解决‌:**在解析过程中,如果两个或多个依赖引入了相同库的不同版本,

Maven会使用其策略(例如,最近者优先、最短路径优先等)来决定使用哪个版本。

**④ ‌传递性依赖的管理‌:**一旦所有依赖都被解析和解决,Maven会将所有必要的

库打包到项目中,使得可以在代码中直接使用这些库。

说明:

非compile范围的依赖不能传递。

5. 依赖排除

(1) 使用依赖排除的背景

如果A.jar依赖B.jar,当通过pom.xml引入A.jar时,Maven会自动引入B.jar\nA.jar

包含(x1.java、x2.java等),B.jar包含(y1.java、y2.java等),A.jar与B.jar之间有依

赖关系的实际是x2.java依赖y2.java。如果我们不需要使用A.jar包中的x2.java文件,则

可以通过依赖排除不引入B.jar。

(2) 使用<exclusions>标签

在pom.xml文件中,可以在<dependency>标签内使用<exclusions>标签来排除

特定的传递性依赖。

例:

复制代码
<dependency>
    <groupId>org.example</groupId>
    <artifactId>example-artifact</artifactId>
    <version>1.0</version>
	<!-- 排除依赖 -->
    <exclusions>
        <exclusion>
            <groupId>com.excluded</groupId>
            <artifactId>excluded-artifact</artifactId>
        </exclusion>
    </exclusions>
</dependency>

(3) 使用<dependencyManagement>标签

如果想要在多个项目中重复使用相同的排除设置,可以在

<dependencyManagement>部分定义这些排除,然后在需要的地方引用。这样做的

好处是可以保持pom.xml的整洁,并避免在每个依赖中重复定义排除规则。

例:

复制代码
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>example-artifact</artifactId>
            <version>1.0</version>
            <exclusions>
                <exclusion>
                    <groupId>com.excluded</groupId>
                    <artifactId>excluded-artifact</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</dependencyManagement>

(4) 使用mvn dependency:tree命令分析依赖树

有时候,排除一个依赖是因为它导致了版本冲突。在这种情况下,应该首先尝试

解决冲突而不是简单地排除它。可以通过查看mvn dependency:tree的输出结果来识别

和解决冲突。Maven的dependency:tree命令可以帮助理解项目的依赖树,这样就可以

看到哪些依赖被传递性地引入了。

例:下面这个命令会显示所有包含com.excluded:excluded-artifact的依赖路径

复制代码
mvn dependency:tree -Dverbose -Dincludes=com.excluded:excluded-artifact

6. 依赖的原则

(1) 最短路径优先原则

当存在多个依赖路径时,Maven 会优先选择路径最短的版本。

例如:

若项目同时依赖 A-B-C-X(1.0) 和 A-D-X(2.0),由于 X(2.0) 路径更短,Maven 将选择 X(2.0)。

(2) 声明顺序优先原则

当依赖路径长度相同时,Maven 根据 pom.xml 中声明的顺序选择依赖。

例如:

若同时声明 A-B-X(1.0) 和 A-C-X(2.0),若 B 在 C 之前声明,则选择 X(1.0)。

(3) 子项目优先原则

子项目(子 POM)中声明的依赖优先级高于父项目(父 POM)中的依赖。

例如:

若父 POM 依赖 A-B,子 POM 依赖 A-D,则最终使用 A-D。

7. 使用自定义标签统一版本

(1) 统一jar包的版本号

① 在properties标签内使用自定义标签统一声明版本号

复制代码
<properties>
	<自定义标签.version>4.0.0</自定义标签.version>
</properties>

② 在需要统一版本的位置,使用${自定义标签名}引用声明的版本号

复制代码
<version>${自定义标签.version}</version>

(2) 说明

凡是需要统一声明后再引用的场合都可以使用自定义标签的方式,使用

${自定义标签名}进行引用。

复制代码
<properties>
	<自定义标签1.version>4.0.0</自定义标签1.version>
	<自定义标签2.encoding>UTF-8</自定义标签2.encoding>
</properties>

(3) 设置JDK版本

① 全局配置:

修改Maven安装目录下的settings.xml文件(位于conf文件夹):

复制代码
<profile>
	<id>jdk-1.8</id>
	<activation>
		<activeByDefault>true</activeByDefault>
		<jdk>1.8</jdk>
	</activation>
	<properties>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
	</properties>
</profile>

② 项目级配置:

在项目pom.xml文件中添加:

复制代码
<profiles>
	<profile>
		<id>jdk-1.8</id>
		<activation>
		  <activeByDefault>true</activeByDefault>
		  <jdk>1.8</jdk>
		</activation>
		<properties>
		  <maven.compiler.source>1.8</maven.compiler.source>
		  <maven.compiler.target>1.8</maven.compiler.target>
		  <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
		</properties>
	</profile>
</profiles>

三、Maven生命周期

1. 概念

Maven生命周期是项目构建过程的抽象化定义,将复杂的构建步骤划分为有序的阶段,确保自动化执行。

2. Maven内置三套相互独立的生命周期

(1)清理生命周期(Clean Lifecycle):

用于清理构建过程中产生的文件,包含以下阶段:

pre-clean:执行一些准备工作,例如环境检查等。

clean:清理上一次构建生成的文件。

post-clean:清理之后的操作。

(2)默认生命周期(Default Lifecycle):

构建的核心流程,包含编译、测试、打包等任务:

validate:校验项目配置信息。

initialize:初始化构建状态

generate-sources:生成源代码

process-sources:处理源代码

generate-resources:生成资源文件

process-resources:处理资源文件
compile:编译项目的源代码

process-classes:处理编译生成的类文件

generate-test-sources:生成测试源代码

process-test-sources:处理测试源代码

generate-test-resources:生成测试资源文件

process-test-resources:处理测试资源文件
test-compile:编译测试源代码。

process-test-classes:处理编译生成的测试类文件
test:使用适当的单元测试框架(如JUnit)运行测试。

prepare-package:应用打包前的准备工作
package:将编译后的代码打包,如jar、war等。

pre-integration-test:集成测试的前置阶段

integration-test:集成测试

post-integration-test:运行集成测试后的清理工作或额外处理

verify:运行所有检查来验证包是有效的并且符合质量标准。
install:将包安装到本地仓库,以让其他项目依赖。
deploy:将最终的包复制到远程仓库。

(3)站点生命周期(Site Lifecycle):

生成项目报告和站点信息,通常用于文档生成:

pre-site:执行一些准备工作,例如环境检查等。

site:生成项目的站点文档。

post-site:站点生成后的操作,并且为部署做准备。

site-deploy:将生成的站点部署到服务器上。

说明:

(1) 这些生命周期和阶段可以被组合使用,以满足不同的构建需求。例如,一个常见的构建顺序是先进行validate、compile、test、package,然后是install或deploy。Maven的生命周期管理使得构建过程更加标准化和可重复。

(2) Maven定义了一组标准构建生命周期(如clean, compile, test, package, install, deploy),并且提供了大量的插件来支持这些生命周期的各个阶段。开发者可以通过简单的配置使用这些插件,而不需要深入了解每个插件的内部机制。

(3) Maven核心程序为了更好的实现自动化构建,按照这一的特点执行生命周期中的各个阶段,不论现在要执行生命周期中的哪一个阶段,都是从这个生命周期最初的位置开始执行。

四、Maven继承

1. 概念

在Maven项目中,继承允许一个项目(称为父项目)定义一些共有的配置和依赖,这些配置和依赖可以被多个子项目(称为子模块)继承。这种方式有助于减少重复配置,提高项目的可维护性和一致性。

2. Maven继承的语法

(1) 创建一个父项目,这个项目将包含一些共有的配置和依赖。

例:

复制代码
<!-- 父项目的坐标 -->
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0</version>
<!-- 修改打包方式为pom -->
<packaging>pom</packaging>

说明:

父项目的打包方式配置为pom(Maven工程的默认打包方式为jar),因为父项目

不打包也不写代码。

(2) 父项目中使用<dependencyManagement>标签配置对依赖的管理。

例:

复制代码
<!-- 管理依赖的版本 -->
<dependencyManagement>
	<dependencies>
		<dependency>
		  <groupId>org.springframework</groupId>
		  <artifactId>spring-core</artifactId>
		  <version>4.0.0.RELEASE</version>
		</dependency>
	</dependencies>
</dependencyManagement>

说明:

被管理的依赖并没有真正被引入到工程,这里只是声明依赖版本。

(3) 子项目中使用<parent>标签指定继承父项目的gav属性。

例:

复制代码
<!-- 子项目坐标 -->
<!-- <groupId>com.example</groupId> -->
<artifactId>child-project</artifactId>
<!-- <version>1.0.0</version> -->

<!-- 指定父项目坐标 -->
<parent>
	<groupId>com.example</groupId>
	<artifactId>parent-project</artifactId>
	<version>1.0.0</version>
	<!-- 以当前文件为基准的父项目pom.xm1文件的相对路径 -->
	<relativePath>../parent-project/pom.xml</relativePath>
</parent>

说明:

1)当子项目的 <groupId>、<version> 与父项目相同时,在子项目中就可以将子

项目的 <groupId>、<version> 省略。

2)<relativePath>标签用相对路径指定父项目pom.xml文件的位置,如果父项目

已经安装在本地或远程仓库中,那么 <relativePath> 可以省略。

3)<relativePath> 声明后,其寻找父项目的路径为 relativePath -> 本地仓库 -> 远

程仓库。

(4) 子项目引用父项目的依赖版本。

例:

复制代码
<!-- 引入依赖,不需要指定version信息 -->
<dependencies>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
	</dependency>
</dependencies>

说明:

1)子项目引用父项目中的依赖信息时,可以把版本号去掉。把版本号去掉就表示

子项目中这个依赖的版本由父项目的dependencyManagement来决定。如果在子项目

中写上版本号,则会覆盖父项目中的版本信息(不建议)。

2)子项目 <dependencies> 中的声明才是真正的把依赖引入进来,子项目如果不

主动引入依赖,那么父项目 <dependencyManagement> 节点下声明的依赖就不会被真

正的引入。

3)子项目配置继承后,执行安装命令时要先安装父项目。

五、Maven聚合

1. 概念

聚合就是将多个子模块作为一个项目进行构建。它可以帮助你管理和构建整个项目的不同部分。

2. 聚合的语法

创建一个父项目pom.xml文件。这个文件将包含所有子模块的配置,并定义聚合。

例:

复制代码
<!-- 修改打包方式为pom -->
<packaging>pom</packaging>
<!-- 指定各个子模块的相对路径 -->
<modules>
  <module>../module-test1</module>
  <module>../module-test2</module>
  <module>../module-test3</module>
</modules>

说明:

1)打包方式需要配置为pom。

2)<modules>标签列出了所有子模块的相对路径。

3)继承和聚合都需要单独写一个父项目,且pom.xml中打包方式都需要配置

为pom,实际开发中一般会将两种关系写到同一个pom.xml文件中。

六、Web工程的自动部署

1. 自动部署配置

复制代码
<!--配置当前工程构建过程中的特殊设置-->
<build>
	<finalName>TestWeb</finalName>
	<!-- 配置构建过程中需要使用的插件 -->
	<plugins>
		<plugin>
			<!-- cargo是一家专门从"启动Servlet容器"的组织-->
			<groupId>org.codehaus.cargo</groupId>
			<artifactId>cargo-maven2-plugin</artifactId>
			<version>1.2.3</version>
			<!--针对插件进行的配置-->
			<configuration>
				<!-- 配置当前系统中容器的位置-->
				<container>
					<containerId>tomcat6x</containerId>
					<home>D:\tomcat\apache-tomcat-6.0.43</home>
				</container>
				<configuration>
					<type>existing</type>
					<home>D;\tomcat\apache-tomcat-6.0.43</home>
					<!-- 如果Tomcat端口为默认值8080则不必设置该属性-->
					<!-- <properties>
						<cargo.servlet.port>8081</cargo.servlet.port>
					</properties> -->
				</configuration>
			</configuration>
			<!-- 配置播件在什么情况下执行-->
			<executions>
				<execution>
					<id>cargo-run</id>
					<!-- 生命周期的阶段-->
					<phase>install</phase>
					<goals>
						<!-- 插件的目标 -->
						<goal>run</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>
相关推荐
杨武博2 小时前
关于maven中pom依赖冲突问题记录
java·maven
我是李武涯2 小时前
从`std::mutex`到`std::lock_guard`与`std::unique_lock`的演进之路
开发语言·c++
史不了3 小时前
静态交叉编译rust程序
开发语言·后端·rust
陈果然DeepVersion3 小时前
Java大厂面试真题:Spring Boot+Kafka+AI智能客服场景全流程解析(十)
java·spring boot·ai·kafka·面试题·向量数据库·rag
读研的武4 小时前
DashGo零基础入门 纯Python的管理系统搭建
开发语言·python
Andy4 小时前
Python基础语法4
开发语言·python
但要及时清醒4 小时前
ArrayList和LinkedList
java·开发语言