1.Maven是什么?
工具和软件
2.Maven为什么服务?
Java项目
3.Maven的主要功能?
构建管理:**Maven 可以管理项目的编译、测试、打包、部署等构建过程。**通过实现标准的构建生命周期,Maven 可以确保每一个构建过程都遵循同样的规则和最佳实践。同时,Maven 的插件机制也使得开发者可以对构建过程进行扩展和定制。主动触发构建,只需要简单的命令操作即可。
依赖管理:Maven 可以管理项目的依赖,包括自动下载所需依赖库、自动下载依赖需要的依赖并且保证版本没有冲突、依赖版本管理等。通过 Maven,我们可以方便地维护项目所依赖的外部库,而我们仅仅需要编写配置即可。
4.构建过程:
项目构建是指将源代码、配置文件、资源文件等转化为能够运行或部署的应用程序或库的过程。
Java 源代码 .java ->打包运行代码.class,部署到对应位置。
:::info
使用Maven之前,是由IDEA帮忙构建。
1)maven构建触发方便: 命令 mvn package
2)构建时有要求的项目结构: 由于不同的开发工具构建,构建的项目格式要求不同,这些项目格式不能通用比较麻烦。
**构建工具可以选择maven配合开发工具进行代码提示和代码测试。 **
:::
二、基于IDEA的Maven工程创建
2.1梳理Maven工程GAVP属性
Maven工程相对之前的工程,多出一组gavp属性,gav需要我们在创建项目的时指定,p有默认值,后期通过配置文件修改。既然要填写的属性,我们先行了解下这组属性的含义!
Maven 中的 GAVP 是指 GroupId、ArtifactId、Version、Packaging 等四个属性的缩写,其中前三个是必要的,而 Packaging 属性为可选项。这四个属性主要为每个项目在maven仓库总做一个标识,类似人的《姓-名》。有了具体标识,方便maven软件对项目进行管理和互相引用!
GAVP遵循以下规则:
1) GroupID 格式:com.{公司/BU }.业务线.[子业务线],最多 4 级。
说明:{公司/BU} 例如:alibaba/taobao/tmall/aliexpress 等 BU 一级;子业务线可选。
正例:com.taobao.tddl 或 com.alibaba.sourcing.multilang com.atguigu.java
2) ArtifactID 格式:产品线名-模块名。语义不重复不遗漏,先到仓库中心去查证一下。
正例:tc-client / uic-api / tair-tool / bookstore
3) Version版本号格式推荐:主版本号.次版本号.修订号 1.0.0
1) 主版本号:当做了不兼容的 API 修改,或者增加了能改变产品方向的新功能。
2) 次版本号:当做了向下兼容的功能性新增(新增类、接口等)。
3) 修订号:修复 bug,没有修改方法签名的功能加强,保持 API 兼容性。
例如: 初始→1.0.0 修改bug → 1.0.1 功能调整 → 1.1.1等
Packaging定义规则:
指示将项目打包为什么类型的文件,idea根据packaging值,识别maven项目类型!
:::info
打包类型代表了不同的工程 **
:::
packaging 属性为 jar(默认值),代表普通的Java工程**,打包以后是.jar结尾的文件。
packaging 属性为 war,代表Java的web工程,打包以后.war结尾的文件。
举例:一个开发项目的迭代
2.2 Maven工程项目创建
如何手动创建web项目?
1.创建一个Javase maven工程
2.补全文件结构
main
webapp
WEB-INF
web.xml
3.pom.xml
war
packaging 属性为 pom,代表不会打包,用来做继承的父工程。
4.刷新
(主要)也可利用插件去构建?Maven的Web工程 (JBLJavaToWeb插件)
2.3 Maven工程项目结构说明
Maven 是一个强大的构建工具,它提供一种标准化的项目结构,可以帮助开发者更容易地管理项目的依赖、构建、测试和发布等任务。以下是 Maven Web 程序的文件结构及每个文件的作用:
|-- pom.xml # Maven 项目管理文件
|-- src
|-- main # 项目主要代码
| |-- java # Java 源代码目录
| | `-- com/example/myapp # 开发者代码主目录
| | |-- controller # 存放 Controller 层代码的目录
| | |-- service # 存放 Service 层代码的目录
| | |-- dao # 存放 DAO 层代码的目录
| | `-- model # 存放数据模型的目录
| |-- resources # 资源目录,存放配置文件、静态资源等
| | |-- log4j.properties # 日志配置文件
| | |-- spring-mybatis.xml # Spring Mybatis 配置文件
| | `-- static # 存放静态资源的目录
| | |-- css # 存放 CSS 文件的目录
| | |-- js # 存放 JavaScript 文件的目录
| | `-- images # 存放图片资源的目录
| `-- webapp # 存放 WEB 相关配置和资源
| |-- WEB-INF # 存放 WEB 应用配置文件
| | |-- web.xml # Web 应用的部署描述文件
| | `-- classes # 存放编译后的 class 文件
| `-- index.html # Web 应用入口页面
`-- test # 项目测试代码
|-- java # 单元测试目录
`-- resources # 测试资源目录
- pom.xml:Maven 项目管理文件,用于描述项目的依赖和构建配置等信息。
- src/main/java:存放项目的 Java 源代码。
- src/main/resources:存放项目的资源文件,如配置文件、静态资源等。
- src/main/webapp/WEB-INF:存放 Web 应用的配置文件。
- src/main/webapp/index.html:Web 应用的入口页面。
- src/test/java:存放项目的测试代码。
- src/test/resources:存放测试相关的资源文件,如测试配置文件等。
2.4 第三方依赖信息声明
1.导入依赖信息:
<!--
通过编写依赖jar包的gav必要属性,引入第三方依赖!
scope属性是可选的,可以指定依赖生效范围!
依赖信息查询方式:
1. maven仓库信息官网 https://mvnrepository.com/
2. mavensearch插件搜索
-->
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--gavp属性-->
<!--不会改变-->
<groupId>com.atzelong</groupId>
<artifactId>maven-javase-project-01</artifactId>
<!--构建过程中在部署时-修改-->
<version>1.0-SNAPSHOT</version>
<!--默认jar 另外,还有war和pom-->
<packaging>war</packaging>
<!--第三方依赖信息声明-->
<dependencies>
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
</dependency>
</dependencies>
</project>
2.扩展功能
1.声明变量。提取版本号,统一管理。
2.引入依赖时有可选属性scope 引入依赖的作用域
默认 :compile 在main 在test 在打包和运行时都可以使用
test 仅在test中使用 Junit 单元测试 @Test
runtime运行时有效 main中不会使用,test中不会使用,打包和运行时会使用(通常用于在运行时需要但编译时不需要的依赖。)
举例:反射 注册mysql的驱动 Class.forName(“com.mysql.cj.jdbc.Driver”)
provided 在main 、 test 中用 但打包和运行时不用
举例:Servlet 因为tomcat本身提供了Servlet
总结:一种锦上添花的手段,掌握不好就全默认值
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zelong</groupId>
<artifactId>maven-javaee-project-02</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--
声明一个变量,能在其他地方引用
建议两层以上命名:技术.version
-->
<jackson.version>2.15.2</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<!--方便version的管理-->
<scope>compile</scope>
</dependency>
</dependencies>
</project>
三、Maven核心功能依赖和构建管理
3.1 Maven的依赖传递与依赖冲突
Maven的依赖传递与依赖冲突
1)什么是依赖传递?
只有compile级别才能传递依赖!
依赖传递的作用是:
- 减少重复依赖:当多个项目依赖同一个库时,Maven 可以自动下载并且只下载一次该库。这样可以减少项目的构建时间和磁盘空间。
- 自动管理依赖: Maven 可以自动管理依赖项,使用依赖传递,简化了依赖项的管理,使项目构建更加可靠和一致。
- 确保依赖版本正确性:通过依赖传递的依赖,之间都不会存在版本兼容性问题,确实依赖的版本正确性!
2)什么是依赖冲突?
1:
2:优点或目的:避免循环依赖!
3:依赖冲突的解决原则
拿到A F B 1.0
3.2 依赖导入失败场景和解决方案
在使用 Maven 构建项目时,可能会发生依赖项下载错误的情况,主要原因有以下几种:
- 下载依赖时出现网络故障或仓库服务器宕机等原因,导致无法连接至 Maven 仓库,从而无法下载依赖。(当前自己学习的,只有本地仓库和阿里镜像)
- 依赖项的版本号或配置文件中的版本号错误,或者依赖项没有正确定义,导致 Maven 下载的依赖项与实际需要的不一致,从而引发错误。
- 本地 Maven 仓库或缓存被污染或损坏,导致 Maven 无法正确地使用现有的依赖项,并且也无法重新下载!
解决方案:
- 检查网络连接和 Maven 仓库服务器状态。
- 确保依赖项的版本号与项目对应的版本号匹配,并检查 POM 文件中的依赖项是否正确。
- 清除本地 Maven 仓库缓存(lastUpdated 文件),因为只要存在lastupdated缓存文件,刷新也不会重新下载。本地仓库中,根据依赖的gav属性依次向下查找文件夹,最终删除内部的文件,刷新重新下载即可!
3.3 扩展构建管理和插件配置
构建概念:
项目构建是指将源代码、依赖库和资源文件等转换成可执行或可部署的应用程序的过程,在这个过程中包括编译源代码、链接依赖库、打包和部署等多个步骤。
主动触发场景:
- 重新编译 : 编译不充分, 部分文件没有被编译!
- 打包 : 独立部署到外部服务器软件,打包部署
- 部署本地或者私服仓库 : maven工程加入到本地或者私服仓库,供其他工程使用
触发构建的方式
命令方式构建:1)命令在执行时,需要我们进入项目的根路径,与pom.xml平级的位置
2)要部署必须是jar包形式
语法: mvn 构建命令 构建命令…
构建命令周期介绍:
构建生命周期可以理解成是一组固定构建命令的有序集合,触发周期后的命令,会自动触发周期前的命令!也是一种简化构建的思路!
- 清理周期:主要是对项目编译生成文件进行清理
包含命令:clean - 默认周期:定义了真正构件时所需要执行的所有步骤,它是生命周期中最核心的部分
包含命令:compile - test - package - install / deploy - 报告周期
包含命令:site
打包: mvn clean package 本地仓库: mvn clean install
打包: mvn clean package
重新编译: mvn clean compile
本地部署: mvn clean install
周期,命令和插件:
周期→包含若干命令→包含若干插件!
使用周期命令构建,简化构建过程!
最终进行构建的是插件!
自己不用周期不用命令触发插件很麻烦
最终进行构建的是插件!
插件配置:
<build>
<!-- jdk17 和 Maven自带打成war包的插件版本不匹配 -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
</plugins>
</build>
四、Maven继承和聚合特性
4.1 Maven工程继承关系
- 继承概念
**Maven 继承是指在 Maven 的项目中,让一个项目从另一个项目中继承配置信息的机制。**继承可以让我们在多个项目中共享同一配置信息,简化项目的管理和维护工作。
- 继承作用
作用:在父工程中统一管理项目中的依赖信息,进行统一版本管理!
它的背景是:
- 对一个比较大型的项目进行了模块拆分。
- 一个 project 下面,创建了很多个 module。
- 每一个 module 都需要配置自己的依赖信息。
它背后的需求是: - 多个模块要使用同一个框架,它们应该是同一个版本,所以整个项目中使用的框架版本需要统一管理。
- 使用框架时所需要的 jar 包组合(或者说依赖信息组合)需要经过长期摸索和反复调试,最终确定一个可用组合。这个耗费很大精力总结出来的方案不应该在新的项目中重新摸索。
通过在父工程中为整个项目维护依赖信息的组合既保证了整个项目使用规范、准确的 jar 包;又能够将以往的经验沉淀下来,节约时间和精力。
- 继承语法
- 父工程
<groupId>com.atguigu.maven</groupId>
<artifactId>pro03-maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 当前工程作为父工程,它要去管理子工程,所以打包方式必须是 pom -->
<packaging>pom</packaging>
- 子工程
<!-- 使用parent标签指定当前工程的父工程 -->
<parent>
<!-- 父工程的坐标 -->
<groupId>com.atguigu.maven</groupId>
<artifactId>pro03-maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<!-- 子工程的坐标 -->
<!-- 如果子工程坐标中的groupId和version与父工程一致,那么可以省略 -->
<!-- <groupId>com.atguigu.maven</groupId> -->
<artifactId>pro04-maven-module</artifactId>
<!-- <version>1.0-SNAPSHOT</version> -->
- 父工程依赖统一管理
- 父工程声明版本
<!-- 使用dependencyManagement标签配置对依赖的管理 -->
<!-- 被管理的依赖并没有真正被引入到工程 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
- 子工程引用版本
<!-- 子工程引用父工程中的依赖信息时,可以把版本号去掉。 -->
<!-- 把版本号去掉就表示子工程中这个依赖的版本由父工程决定。 -->
<!-- 具体来说是由父工程的dependencyManagement来决定。 -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
</dependencies>
4.2 Maven工程聚合关系
- 聚合概念
Maven 聚合是指将多个项目组织到一个父级项目中,通过触发父工程的构建,统一按顺序触发子工程构建的过程!! - 聚合作用
- 统一管理子项目构建:通过聚合,可以将多个子项目组织在一起,方便管理和维护。
- 优化构建顺序:通过聚合,可以对多个项目进行顺序控制,避免出现构建依赖混乱导致构建失败的情况。(模块之前有相互引用问题,这样可以自动进行合理顺序的构建)
- 聚合语法
父项目中包含的子项目列表。
<project>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<packaging>pom</packaging>
<version>1.0.0</version>
<modules>
<module>child-project1</module>
<module>child-project2</module><!--配置聚合哪些子工程-->
</modules>
</project>
- 聚合演示
通过触发父工程构建命令、引发所有子模块构建!产生反应堆!
五、Maven实战案例:搭建微服务Maven工程架构
5.1 项目需求和结构分析
需求案例:搭建一个电商平台项目,该平台包括用户服务、订单服务、通用工具模块等。
项目架构:
- 用户服务:负责处理用户相关的逻辑,例如用户信息的管理、用户注册、登录等。
- 订单服务:负责处理订单相关的逻辑,例如订单的创建、订单支付、退货、订单查看等。
- 通用模块:负责存储其他服务需要通用工具类,其他服务依赖此模块。
服务依赖:
- 用户服务 (1.0.1)
- spring-context 6.0.6
- spring-core 6.0.6
- spring-beans 6.0.6
- jackson-databind / jackson-core / jackson-annotations 2.15.0
- 订单服务 (1.0.1)
- shiro-core 1.10.1
- spring-context 6.0.6
- spring-core 6.0.6
- spring-beans 6.0.6
- 通用模块 (1.0.1)
- commons-io 2.11.0