Maven简介
Maven是一个项目管理和构建工具,专门用于Java项目的构建、依赖管理和项目生命周期管理。通过Maven,开发人员可以轻松地管理项目地结构、构建过程和依赖关系,提高项目地可维护性和可重用性。
依赖管理
:Maven可以自动下载所需的依赖库,自动下载依赖需要的依赖并且保证版本没有冲突等。通过Maven可以方便地维护项目所依赖地外部库,避免版本冲突和转换错误等。构建管理
:Maven可以管理项目地编译、测试、打包、部署等构建过程,通过实现标准的构建生命周期,Maven可以确保每个构建过程都遵循同样的规则和最佳实践。
Maven官网:maven.apache.org/
Maven的安装配置
Maven的安装
Maven的目录说明:
bin
:含有Maven的运行脚本boot
:含有plexus-classworlds类加载器框架conf
:含有Maven的核心配置文件lib
:含有Maven运行时所需要的Java类库LICENSE、NOTICE、README.txt
:针对Maven版本,第三方软件等简要介绍
Maven需要本机安装Java环境、同时必须包含JAVA_HOMT环境变量
Maven环境配置
- 配置环境变量
- 配置Path变量
- 命令测试
sh
# 输出版本信息则说明配置成功
mvn -v
Maven的功能配置
在conf目录下的settings.xml配置文件中进行配置
- 配置本地仓库地址
xml
<!-- 55行左右 -->
<localRepository>D:\maven-repository</localRepository>
- 配置国内阿里镜像
xml
<!--在mirrors节点(标签)下添加中央仓库镜像 160行附近-->
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
- 配置jdk8版本项目构建
xml
<!--在profiles节点(标签)下添加jdk编译版本 268行附近-->
<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>
IDEA配置本地Maven软件
idea工具默认自带maven配置软件,但是因为没有修改配置,建议替换成本地配置好的maven。
IDEA创建Maven工程
Maven工程的GAVP
Maven项目的GAVP属性是指GroupId、ArtifactId、Version、和Packaging,这些属性一起构成了Maven项目的坐标信息,用于唯一标识和定位一个项目。
GroupId
:组织或者项目的唯一标识,格式一般为 com.公司.业务线.子业务线,最多4级。比如 com.taobao.tddl、com.alibaba.sourcing.multilang。ArtifactId
:项目的名称,格式一般为 产品线名-模块名。比如 tc-client、uic-api、tair-tool。Version
:项目的版本号,格式一般为 主版本号.次版本号.修订号。- 主版本号:当做了不兼容的API修改,或者增加了能改变产品方向的新功能。
- 次版本号:当做了向下兼容的功能性新增(新增类、接口等)。
- 修订号:当修复bug,没有修改方法签名的功能加强,保持API兼容性。
Packaging
:指定项目打包类型,IDEA根据packaging值,识别Maven项目类型。- jar(默认值):代表普通的Java工程,打包后是jar文件。
- war:代表web工程,打包后是war文件。
- pom:代表不会打包,用来做继承的父工程。
IDEA构建JavaSE工程
IDEA构建JavaWeb工程
手动创建
- 创建一个maven的JavaSE工程
- 修改pom.xml文件打包方式
xml
<groupId>com.wenxuan</groupId>
<artifactId>maven-web</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 修改模块的打包方式 -->
<packaging>war</packaging>
- 设置web资源路径和web.xml路径
- 测试和校验:当web目录出现小蓝点说明创建成功
插件创建
- 安装插件JBLJavaToWeb
- 创建一个maven的JavaSE工程
- 右键模块,使用插件快速补全web项目
原型创建
IDEA部署JavaWeb工程
- 工程配置
- 添加本地Tomcat
- 添加web工程
Maven工程目录结构
bash
|-- 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 # 测试资源目录
IDEA构建Maven工程
构建概念和构建过程
项目构建是指将源代码、依赖库和资源文件等转换成可执行或可部署的应用程序的过程,在这个过程中包括编译源代码、链接依赖库、打包和部署等多个步骤。
项目构建的命令
命令 | 描述 |
---|---|
mvn clean | 清理编译或打包后的项目结构 |
mvn compile | 编译项目主要代码,生成target文件 |
mvn test-compile | 编译项目测试代码,生成target文件 |
mvn test | 执行测试源码 |
mvn package | 打包项目,生成jar或war文件 |
mvn install | 打包后上传到maven本地仓库 |
mvn deploy | 打包后上传到maven私服仓库 |
mvn site | 生成站点 |
注意:war包打包插件和jdk版本不匹配:pom.xml 添加以下代码即可
xml
<build>
<!-- jdk17 和 war包版本插件不匹配 -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
</plugins>
</build>
构建过程的生命周期
Maven构建过程的生命周期分为三个主要阶段:
- 清理clean:Maven将会清理项目,删除之前生成的构建结果,以便重新进行构建。
- 编译compile:Maven将会编译项目的源代码,生成可执行的Java字节码文件。
- 打包package:Maven将编译后的代码打包成特定的格式(jar、war)。
每个阶段中可能会有多个插件执行相应的目标,用于实现不同的功能和需求。通过定义和配置这些插件和目标,可以定义Maven构建过程。
构建过程的生命周期对应若干命令,对应若个插件,使用周期命令构建,最终构建的是插件。
IDEA进行Maven依赖管理
依赖管理概念
Maven依赖管理是指通过Maven工具来管理项目所依赖的第三方库,以便项目能够顺序构建、编译和运行。在Maven中,项目依赖通常被定义在项目的pom.xml
文件中,通过配置依赖信息来告诉Maven需要下载哪些库,并且在构建项目时自动引入这些库。
Maven工程核心配置信息
Maven工程核心配置信息通过在pom.xml
文件中定义。
xml
<!-- 模型版本 -->
<modelVersion>4.0.0</modelVersion>
<!-- 公司或组织的唯一标识 -->
<groupId>com.wenxuan.maven</groupId>
<!-- 项目的唯一ID -->
<artifactId>project</artifactId>
<!-- 版本号 -->
<version>1.0.0</version>
<!--
打包方式:默认jar
jar:普通Java项目打包凡是
war:web项目打包方式
pom:项目不会打包,表示该项目作为父工程,被其他工程聚合或者继承
-->
<packaging>jar</packaging>
<!-- 描述信息 -->
<description>Maven工程</description>
<properties>
<!-- 译源代码时使用的 Java 版本 -->
<maven.compiler.source>1.8</maven.compiler.source>
<!-- 成的 Java 字节码文件的目标 Java 版本 -->
<maven.compiler.target>1.8</maven.compiler.target>
<!-- 源文件的编码格式为 UTF-8 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 输出报告文件的编码格式为 UTF-8 -->
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 定义一个变量,添加依赖时可以通过 ${junit.version} 方式获取值 -->
<junit.version>4.12</junit.version>
</properties>
<dependencies>
<!-- 引入具体的依赖包 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<!-- 依赖范围 -->
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<!--引用properties声明版本 -->
<version>${junit.version}</version>
</dependency>
</dependencies>
<build>
<!-- 自定义打包名称 -->
<fileName>打包名称</fileName>
<!--设置要打包的资源位置-->
<resources>
<resource>
<!--设置资源所在目录-->
<directory>src/main/java</directory>
<includes>
<!--设置包含的资源类型-->
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<!-- 配置插件 -->
<plugins>
<!-- tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<path>/</path>
<uriEncoding>UTF-8</uriEncoding>
<server>tomcat7</server>
</configuration>
</plugin>
</plugins>
</build>
Maven工程依赖范围
Maven工程的依赖范围通过设置scope来指定,可以设置对应jar包的作用范围:编译环境、测试环境、运行环境。
依赖范围 | 描述 |
---|---|
compile | 编译依赖范围,scope默认值。表示编译、测试、运行过程中依赖都生效。例如log4j在编译、测试和运行过程都是必须的。 |
test | 测试依赖范围。表示只对测试生效。例如junit依赖只有在测试阶段才需要。 |
provided | 已提供依赖范围。表示只在编译和测试过程中生效。例如servlet-api依赖对于编译、测试阶段是需要的,但是在运行阶段由于外部容器(Tomcat)已经提供,所以不需要Maven重复引入。 |
runtime | 运行依赖范围。表示只对测试和运行范围生效。例如JDBC驱动依赖,在编译时只需JDK提供的JDBC接口即可,但是在测试和运行阶段需要实现了JDBC接口的驱动。 |
import | 导入依赖范围。该依赖范围只能与 dependencyManagement 元素配合使用,其功能是将目标 pom.xml 文件中 dependencyManagement 的配置导入合并到当前 pom.xml 的 dependencyManagement 中。 |
system | 系统依赖范围。表示只在编译和测试过程中生效。用于添加非Maven仓库的本地依赖,通过依赖元素dependency中的systemPath元素指定本地依赖的路径,由于使用会导致项目的可移植性降低,一般不建议使用。 |
Maven依赖下载失败原因
发生依赖下载失败的情况,主要原因分为以下几种:
- 下载依赖时出现网络故障或仓库服务器宕机等原因,导致无法连接Maven仓库,从而无法下载依赖。
- 依赖项的版本号或配置文件中版本号错误,或者依赖项没有正确定义,导致Maven下载的依赖项Maven仓库中找不到,从而无法下载依赖。
- 本地Maven仓库或缓存被污染或损坏,导致Maven无法正确使用现有的依赖项,而且不会下载正确的依赖项。
解决方案:
- 检查网络连接和Maven仓库服务器状态。
- 确保依赖项的版本号与项目对应的版本号匹配,并检查POM文件中依赖项是否正确。
- 清除本地Maven仓库缓存(lastUpdated文件),因为只要存在lastUpdated文件,刷新项目也不会重新下载。
编写脚本批量清除lastUpdated文件:将本地仓库路径修改为自己Maven仓库路径,同时文件必须为bat文件。比如文件名 clearLastUpdated.bat
bat
cls
@ECHO OFF
SET CLEAR_PATH=D:
SET CLEAR_DIR=D:\maven-repository(本地仓库路径)
color 0a
TITLE ClearLastUpdated For Windows
GOTO MENU
:MENU
CLS
ECHO.
ECHO. * * * * ClearLastUpdated For Windows * * * *
ECHO. * *
ECHO. * 1 清理*.lastUpdated *
ECHO. * *
ECHO. * 2 查看*.lastUpdated *
ECHO. * *
ECHO. * 3 退 出 *
ECHO. * *
ECHO. * * * * * * * * * * * * * * * * * * * * * * * *
ECHO.
ECHO.请输入选择项目的序号:
set /p ID=
IF "%id%"=="1" GOTO cmd1
IF "%id%"=="2" GOTO cmd2
IF "%id%"=="3" EXIT
PAUSE
:cmd1
ECHO. 开始清理
%CLEAR_PATH%
cd %CLEAR_DIR%
for /r %%i in (*.lastUpdated) do del %%i
ECHO.OK
PAUSE
GOTO MENU
:cmd2
ECHO. 查看*.lastUpdated文件
%CLEAR_PATH%
cd %CLEAR_DIR%
for /r %%i in (*.lastUpdated) do echo %%i
ECHO.OK
PAUSE
GOTO MENU
Maven依赖的传递性
Maven的依赖传递特性是指当一个Maven项目依赖于其他项目或库时,Maven能够自动解析并下载这些依赖项需要的其他依赖项,从而构建一个完整的依赖树。
例如:项目A依赖于项目B,项目B依赖于项目C,Maven在构建项目A时会自动检测到项目B的依赖关系,并自动下载加载项目B所需的项目C。
依赖传递原则
- 只有使用compile范围的依赖可以传递,其他依赖范围(test、provided)不能传递。
- 使用了optional标签的依赖不能传递。
xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.15</version>
<optional>true</optional>
</dependency>
- 传递的依赖已经存在,会产生依赖冲突不能传递。
Maven依赖的冲突性
Maven的依赖冲突特性是指当一个Maven项目中存在多个依赖项,且这些依赖项之间存在相同依赖的版本冲突。
解决依赖冲突的策略:
- 依赖最近者原则:当多个依赖项需要同一个库的不同版本时,Maven会选择距离当前项目最近的依赖项所指定的版本。最近的依赖项会覆盖较远的依赖项。
- 依赖声明优先原则:如果多个依赖项指定同一个库的不同版本,且依赖距离相同,则会选择pom.xml文件中优先声明的依赖。
- 手动排除依赖项:可以在项目的pom.xml文件中手动排除某个依赖项的传递特性,通过 <exclusions> 标签排除指定依赖项。
xml
<dependency>
<groupId>com.wenxuan.maven</groupId>
<artifactId>maven-java</artifactId>
<version>1.0.0</version>
<!-- 使用excludes标签配置依赖的排除 -->
<exclusions>
<!-- 在exclude标签中配置一个具体的排除 -->
<exclusion>
<!-- 指定要排除的依赖的坐标(不需要写version) -->
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</exclusion>
</exclusions>
</dependency>
Maven工程的继承和聚合关系
Maven工程的继承和聚合关系:项目之间可以通过继承和聚合关系来共享配置和依赖,Maven工程之间的继承关系通过父子工程来实现。也就是说一个Maven工程可以作为另一个Maven工程的父工程,而另一个工程则成为子工程。
Maven工程继承和聚合的作用:
配置的重用
:将公共的配置信息、插件配置、依赖管理等集中放在父工程中,子工程可以直接继承并使用这些配置,避免重复配置,提高项目的一致性和可维护性。依赖的管理
:父工程可以统一管理项目中所需的依赖项,子工程只需要指定自己特定的依赖,而共享的依赖可以在父工程中声明。构建设置的统一
:父工程中可以定义一些共享的构建设置,如编译器版本、资源过滤器配置、打包方式等。项目结构的组织
:可以将大型项目拆分成多个子模块,每个子模块对应一个子工程,便于项目的组织和管理。不同模块间可以共享配置信息,同时实现各自的特定功能。
继承和聚合的语法:
- 父工程:
xml
<groupId>com.wenxuan.maven</groupId>
<artifactId>maven-parent</artifactId>
<version>1.0.0</version>
<!-- 父工程打包方式设置为pom -->
<packaging>pom</packaging>
<!-- 将子工程聚合到父工程,注意maven-son不是工程名称,而是工程路径 -->
<modules>
<module>maven-son</module>
</modules>
<!--
使用dependencyManagement标签配置对依赖的管理,被管理的依赖并没有真正被引入到工程,
1、如果父工程中的依赖通过dependencies标签定义,则该依赖会直接被子工程继承;
2、如果父工程中的依赖通过dependencyManagement标签定义,则该依赖不会直接被子工程继承,需要子工程手动引入,但不需要指定版本号,而是直接复用父工程的版本号。
-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.21</version>
</dependency>
</dependencies>
</dependencyManagement>
- 子工程
xml
<!-- 通过parent标签继承父工程 -->
<parent>
<groupId>com.wenxuan.maven</groupId>
<artifactId>maven-parent</artifactId>
<version>1.0.0</version>
</parent>
<!-- 子工程引用父工程中的依赖信息时,只需要指定artifactId -->
<artifactId>maven-son</artifactId>
<dependencies>
<!-- 子工程引用父工程中的依赖信息时,可以把版本号去掉,版本由父工程的dependencyManagement标签定义 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
</dependencies>
Maven私服
Maven私服简介
Maven私服是用于管理和存储项目依赖库的工具,提供一个私有的中央存储库,供团队成员或组织内部开发人员共享和访问依赖项。
用户获取Maven私服依赖时,请求下载的顺序:
- 请求本地仓库,若本地仓库不存在所需依赖时,则跳转到第2步;
- 请求Maven私服,将所需依赖下载到本地仓库,若私服中不存在所需依赖,则跳转到第3步;
- 请求外部的远程仓库,将所需依赖下载并缓存到Maven私服,若外部远程仓库不存在所需构建,则Maven直接报错。
Maven开发人员也可以从本地将依赖上传到Maven私服中供其他人使用。
Maven私服的优势:
- 构建速度更快:Maven私服可以缓存依赖库,当项目需要依赖的库已经存在于私服中时,无需再次从外部中央仓库下载,可以直接从Maven私服中下载,提高构建速度。
- 保证构建的稳定性:私服存储了团队需要使用的所有依赖库,即使外部中央仓库出现宕机或者网络故障,也不会影响项目的构建,可以保证构建的稳定性和可靠性。
- 控制依赖版本:团队可以在私服中管理自己需要的依赖库的版本,避免不同开发环境使用不同版本的依赖库而导致的问题,确保项目的一致性。
- 提高安全性:通过私服,团队可以控制依赖库的来源和完整性,避免因下载未经验证的依赖库而带来的潜在安全风险。
- 依赖共享和权限管理:私服可以用来共享内部依赖库,团队成员可以方便地访问和使用共享依赖库,同时私服也支持权限控制,可以设置不同地访问权限,保护敏感地依赖库不被未授权地人访问。
常见的Maven私服产品
- Nexus Repository Manager:Sonatype公司推出的一款强大的Maven私服产品,支持Maven、npm、Docker等多种包管理工具。
- Artifactory:JFrog公司推出的一款知名的Maven私服产品,支持多种包管理工具,具有灵活的配置和强大的安全特性。
- Archiva:Apache基金会的一个项目,提供了一个轻量级的Maven仓库管理工具。
- ProGet:提供企业级的应用程序包管理解决方案,支持多种包管理工具。
- Angel:阿里云推出的Maven私服产品,提供了稳定的服务和安全的存储,使用于阿里云的用户和企业用户。
Nexus下载安装
nexus下载地址:help.sonatype.com/repomanager...
nexus下载完毕之后解压,进入nexus安装目录下的bin目录执行下面命令启动nexus:
bat
nexus /run
nexus启动后浏览器访问:http://localhost:8081/
Nexus初始设置
- 点击Sign in登录
- 输入用户名和密码登录
- 用户名:admin
- 密码:在admin.password文件中
- 修改密码
- 禁止匿名登录
Nexus仓库介绍
Nexus中Maven相关仓库如下
仓库名称 | 介绍 |
---|---|
maven-central | Nexus 对 Maven 中央仓库的代理 |
maven-public | Nexus 默认创建,供开发人员下载使用的组仓库 |
maven-releases | Nexus 默认创建,供开发人员部署自己 jar 包的宿主仓库 要求 releases 版本 |
maven-snapshots | Nexus 默认创建,供开发人员部署自己 jar 包的宿主仓库 要求 snapshots 版本 |
Nexus中Maven相关仓库类型如下
仓库类型 | 说明 |
---|---|
proxy | 代理仓库,存储某个远程仓库的代理 |
group | 组仓库,存放通过 Nexus 获取的第三方 jar 包 |
hosted | 存放本团队其他开发人员部署到 Nexus 的 jar 包 |
Nexus下载jar包
修改Maven配置,将Maven远程仓库设置为Nexus:
- 修改mirror标签,设置Maven远程仓库
xml
<mirror>
<id>nexus-mine</id>
<mirrorOf>central</mirrorOf>
<name>Nexus mine</name>
<url>http://localhost:8081/repository/maven-public/</url>
</mirror>
URL获取来源:
- 如果nexus设置禁用匿名访问,还需要设置账号密码信息
xml
<server>
<id>nexus-mine</id>
<username>admin</username>
<password>123456</password>
</server>
注意:server标签的id名必须和mirror标签的id相同。
- 设置nexus的中央仓库为阿里云镜像地址
将下面的URL修改为:maven.aliyun.com/nexus/conte... ,然后保存即可。
将jar包部署到Nexus中
在工程的pom.xml配置文件中添加以下配置,然后执行mvn deploy
即可:
xml
<distributionManagement>
<snapshotRepository>
<id>nexus-mine</id>
<name>Nexus Snapshot</name>
<url>http://localhost:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
注意:snapshotRepository标签的ID必须和maven配置文件中mirror标签ID名相同。
引入Nexus中别人部署的jar包
在工程的pom.xml配置文件中添加以下配置即可
xml
<repositories>
<repository>
<id>nexus-mine</id>
<name>nexus-mine</name>
<url>http://localhost:8081/repository/maven-snapshots/</url>
<!-- 表示可以使用快照版本的依赖 -->
<snapshots>
<enabled>true</enabled>
</snapshots>
<!-- 表示可以使用正式版本的依赖 -->
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
注意:repository标签的ID必须和maven配置文件中mirror的ID相同。