标准化
在maven中,约定优于配置。规定好的标准,可以促进项目团队的标准化,减少写作冲突,在项目切换时免去了学习成本。这些标准具体包括:
项目目录结构
、测试用例命名方式等内容都有既定规则
。规范了jar包的获取方式
(maven方式),从而使得获取的jar包内容也更加规范。之前,jar包的获取方式五花八门,使得获取的jar包的内容也有差异。并且,统一集中式管理jar包的方式,使得jar包共享,实现了jar包和项目分离
,减轻了项目体积。标准化工程构建过程
。提供了一个可复用、易维护的工程模型,从而让项目中各个工程可以更加方便地整合和交互,让团队更加方便协作自动化、智能化
无需依赖IDE工具
即可实现)maven本质上是一个项目管理工具,提供了模板
和工具
来帮助开发人员快速了解项目并加速开发:
- 使用maven项目开发
模板
(包括项目架构
和构建过程
等),开发人员可以在了解一个项目的架构后,迅速了解和操作多个实际的项目。- 使用maven提供的项目管理
工具
,开发人员可以加速项目开发和管理。
maven是Apache开发的一款开源的服务于Java
平台的自动化构建
工具,完成重复性工作。2004年就产生了。
具体步骤包括(不限于):
- 工程目录的创建:标准化工程目录
- 包的导入:同一个项目所有工程使用同一个自动导入包和包的依赖(快照)
- 工程构建:本项目以及相关项目的自动化构建(清理、编译、测试、生成报告、打包、部署)
- 创建工程文档
maven安装目录
假设Maven_HOME为Maven的安装目录,该安装目录的内部目录包含:
bin boot conf lib LICENSE.txt NOTICE.txt README.txt
settrings.xml
用于配置maven的全局行为。maven本地仓库目录
maven默认的本地仓库目录为C:\Users\用户名\.m2目录
定义
maven对项目构建过程
的抽象和统一,从理论上
定义了maven的工作内容和工作过程。通过插件
实现。
内容
maven定义了三套生命周期
:clean
、default
、site
,各生命周期相互独立
。
每个生命周期都包含了一些阶段(phase
)【3套生命周期中phase详解】,每个生命周期中各phase执行时,必须从该生命周期第一个
phase开始,按照既定顺序
执行到要执行的phase。
clean:清理项目
default:部署项目(即通过“原材料”得到一个可运行项目的过程)
主要(不是全部)包括:
site:生成项目站点(为工程相关信息生成一个HTML)
定义
java程序(jar包),通过maven命令调用运行。
作用
为实现maven定义的抽象的声明周期而生。每个插件包含多个插件目标(goal
),goal和phase绑定
,在使用maven命令
实现某个phase时,实际上调用的是插件的goal。
执行语法
mvn [plugin-name]:[goal-name]
例子:
mvn compiler:comile //编译
实现方法
maven中每个插件可以实现多个功能(goal
),通过将插件中的goal
和phase
进行绑定
,来实现maven的生命周期。maven对一些生命周期的phase绑定了默认插件目标,用户也可以在pom.xml中自定义绑定,实现自己定制的声明周期的实现。
位置
在maven仓库中
补充说明
用户可以根据需求,创建自己的maven插件。
依赖,作为名词,指的是工程代码中直接用到的别人已经写好的工程代码(.class文件)。作为动词,指一个工程代码对另外一个工程的代码的引用。
<groupId>com.didispacegroupId>
<artifactId>chapter1-1artifactId>
<version>0.0.1-SNAPSHOTversion>
<type>jartype>
<scope>compilescope>
<optional>optional>
<exclusions>exclusions>
<properties>
<属性名>属性值属性名>
properties>
依赖范围即依赖产生作用的时期,maven有三个classpath文件,分别在编译
、测试
和运行
时用到。各依赖对应的.class文件,通过依赖被引入到对应classpath中,依赖范围对应依赖被引入到哪个classpath。除了表中的依赖范围之外,还有一个import依赖范围,其只在dependencyManagement元素中使用,用于导入其他dependencyManagement的配置。
依赖范围 | 含义 | 编译 | 测试 | 运行 | 例子 |
---|---|---|---|---|---|
compile | 编译时用到的依赖,依赖的默认值 | Y | Y | Y | spring-core |
test | 仅测试时用到的依赖 | Y | JUnit | ||
provided | 容器已提供的依赖 | Y | Y | servlet-api | |
runtime | 运行时用到了依赖 | Y | Y | JDBC驱动实现 | |
system | 操作系统提供的依赖 | Y | Y | 本地的,maven仓库外的类库文件 |
maven通过pom文件中,在标签工程的直接依赖,如果也使用pom文件来声明自己的直接依赖,直接依赖的直接依赖也是同样,那么如此循环下去,工程的直接依赖以及所有间接依赖就都可以通过传递性获知。因此,每个工程只需要在自己的pom文件中声明好自己直接依赖即可
。
依赖的传递性和依赖的作用范围有关
。下表中,最左边一列表示工程的第一直接依赖范围,第一行表示工程的第二直接依赖范围(即工程直接依赖的直接依赖),中间的交叉单元格表示传递性依赖范围(为空表示依赖不会传递,即不存在依赖关系)。
1 2 | compile | test | provided | runtime |
---|---|---|---|---|
compile | compile | runtime | ||
test | test | test | ||
provided | provided | provided | provided | |
runtime | runtime | runtime |
父子继承关系
的项目的依赖,不论什么范围(compile、test、provided、runtime)都
可以由父项目传递(继承)
下给子项目。因此可以利用父工程pom文件,实现所有子工程依赖“一改全改”。
路径近者优先
A–>B–>C–>D–>X(1.6)
A–>E–>D–>X(2.0)
X(2.0)距离项目A更近,项目A使用X(2.0)
先声明者优先
A–>B–> X(1.6)
A–>C–> X(2.0)
路径相同时,B先于C声明,则项目A使用X(1.6)
可选依赖和排除依赖都是阻断依赖传递
的方法。可选依赖阻断的是依赖本项目的项目对本项目的依赖之间的依赖关系,排除依赖阻断的是本项目和间接依赖之间的依赖关系。
项目B的某些依赖不推荐被依赖B的项目所使用
时,需要将这些依赖声明成可选依赖。可选依赖不会被传递
,即X和Y不会被A依赖。如果项目A想使用X作为依赖,则需要在自己的pom文件中重新声明。
排除依赖
项目A不想使用他的某些间接依赖
时使用。如项目A所的依赖没有正确的设置它们的依赖集。被排除的依赖不会被传递
,即依赖项目A的项目,不会依赖被A排除的依赖。
pom文件中,某些重复出现的常量值可能需要同步变动
,如需要统一的版本号。此时,为实现pom文件一改全改
的需求,就需要使用\ 标签,声明常量名和常量值,并在常量出现的地方,使用${常量名}的方式引用常量。如:
<properties>
<springframework.version>属性值springframework.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>${springframework,version}version>
dependency>
dependencies>
定义
Project Object Model:项目对象模型。是 Maven 项目
的核心
和基本工作单元
。
放在工程根
目录下,文件命名为 pom.xml
,包含了关于maven项目
的项目构建
和配置
信息,主要包括项目自身的信息,项目的依赖,项目运行所需环境信息(如:jdk,tomcat)。
maven是根据 pom.xml 来识别maven工程的
pom.xml在打包以后就会变成.pom文件
在maven中执行maven命令:在 pom.xml 上右键
所有的 POM 都继承自一个父 POM,用于继承默认设置,帮助开发者在 pom.xml 中做尽可能少的配置,当然这些配置可以被重写。
pom文件没有显示声明继承关系时,Maven有一个默认POM作为 Super POM
。
Maven 使用 effective pom
(Super pom + 工程自己的 pom)来执行相关的目标。
父 POM 通过
<parent>
<groupId>com.mycompany.appgroupId>
<artifactId>my-appartifactId>
<version>1version>
parent>
maven的标准项目结构如下,当然也可以通过更改pom.xml来配置适合自己的项目结构。
project (项目根目录)
构件(项目的依赖
,插件
,以及该项目的构建输出
)的完全限定名,用于在maven的各种仓库中,唯一地定位
一个构件。
构件在maven仓库中对应的目录
为groupId/artifactId/version
。如下面例子对应的构件的文件夹为:com/didispace/charpter1-1/0.0.1-SNAPSHOT。
构件名字为artifactId-version[-classifier].packaging
。如下面例子对应的文件的名字
为 charpter1-1-0.0.1-SNAPSHOT.jar。
<groupId>com.didispacegroupId>
<artifactId>chapter1-1artifactId>
<version>0.0.1-SNAPSHOTversion>
<packaging>jarpackaging>
除了groupId,artifactId,version,packaging外,还有一个元素classifier:
该元素用来帮助定义项目构建输出的一些附属构件。附属构件和主构件对应,包括项目的Java文档和源代码等。附属构件不是项目直接默认生成的,需要单独用一些插件来生成,因此不能像 groupId等元素一样直接定义。
分类
项目仓库
:项目内文件夹中的依赖包
需要在pom.xml中配置proper
<--! 格式 -->
<repositories>
<repository>
<id>仓库唯一标识符id>
<name>仓库的描述name>
<url>仓库的路径url>
repository>
repositories>
<--! 例子 -->
<repositories>
<repository>
<id>in-projectid>
<name>In Project Reponame>
<url>file:///${project.basedir}\libsurl>
repository>
repositories>
其中,${project.basedir}
是pom.xml在系统中的路径。file:///
的含义
当然,本地仓库和远程仓库也可以通过上述标签配置
,只需将仓库的项目的URL改成项目地址。
本地仓库
:当前电脑上部署的仓库目录,为当前电脑上所有maven工程服务。
默认的仓库位置为:
[系统当前用户home目录]/.m2/repository
修改本地库位置:在MAVEN_HOME/conf/setting.xml
文件中修改
远程仓库
:
私服
:搭建在局域网环境
中,为局域网范围内所有maven工程服务,主流使用Nexus。
有本地主机需要的jar包时,为本地主机提供jar包;没有本地主机需要的jar包时,代替本地主机从中央仓库下载需要的jar包。
中央仓库
:Maven社区提供的,为全世界所有maven工程服务。maven的默认远程仓库,安装时自带配置,需要联网访问。
其他公共库
:需要在POM中手动配置。
外部依赖
由于一些原因,存在于某个不是本地仓库和远程仓库下的依赖。例子
<dependencies>
<dependency>
<groupId>ldapjdkgroupId>
<artifactId>ldapjdkartifactId>
<version>1.0version>
<scope>systemscope>
<systemPath>${basedir}\src\lib\ldapjdk.jarsystemPath>
dependency>
dependencies>
内容
maven仓库中所有内容都按照统一方式管理和查找。仓库中的内容(即构件
)包括:
插件
依赖
自己开发的项目的模块
:需要执行 mvn install 命令,才能将包打入到仓库使用顺序
本地仓库–>私服–>中央仓库–>其他远程仓库
上一个没有,去下一个查找,连接私服和中央仓库均需要联网
需要依赖处于不断更新状态
的的版本的依赖(快照)时,Maven 会在每次构建时检查快照最新版本。快照版本通过在版本号后面加SNAPSHOT
或者日期
和常规版本进行区分。
<dependencies>
<dependency>
<groupId>data-servicegroupId>
<artifactId>data-serviceartifactId>
<version>1.0-SNAPSHOTversion>
<scope>testscope>
dependency>
dependencies>
定义:
多个模块的pom存在很多相同配置
时,为减少重复代码,统一配置信息,maven通过将相同配置信息写到一个父pom文件中,这些模块的pom文件作为子pom文件,继承父POM文件中的配置(即,可以不用显示声明父pom中已经存在的相关配置信息)。
使用:
声明一个父模块,父模块的打包方式为pom
(通过在父pom文件中,设置只需要定义好pom.xml中的依赖
即可,无需编写其他代码。在父模块中的pom文件中,写入所有子模块的统一配置信息,在所有子模块的
如果子模块中需要使用和父模块中不一样的配置,则子模块应该显式声明。子模块会继承所有父模块相关的依赖配置(包括compile、test、provided、runtime)。
可继承的pom元素
groupId
version
description:项目的描述信息
organization:项目的组织信息
inceptionYear:项目的创始年份
url:项目的URL地址
developers:项目的开发者信息
contributions:项目的贡献者信息
distributionManagement:项目的部署配置
issueManagement:项目的缺陷跟踪系统信息
ciManagement:项目的持续集成系统信息
scm:项目的版本控制系统信息
mailingLists:项目的邮件列表信息
properties:自定义的Maven属性
dependencies:项目的依赖配置
dependencyManagement:项目的依赖管理配置
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>2.0version>
dependency>
<dependency>
<groupId>com.juvenxu.mvnbook.accountgroupId>
<artifactId>account-parentartifactId>
<version>1.0-SHAPSHOPversion>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
repositories:项目的仓库配置
build:项目的源码目录配置、输出目录配置、插件配置、插件管理配置等
reporting:项目的报告输出目录配置、报告插件配置等
定义:
通过一个打包方式为pom
的maven项目中,声明任意数量的module元素
来实现一次性构建多个模块
。当被构建的各个模块存在依赖关系时,maven会自动识别各个模块间的依赖关系,先构建被依赖的模块。
使用:
为了方便用户构建项目,通常将聚合模块放在项目目录最顶层,其他模块最为聚合模块的子模块。
module元素的值对应被构建模块和当前POM的相对目录。
为了帮助程序员快速创建一个项目结构,maven提供了archetype(原型/项目模板)插件。
执行mvn命令时,需要调用bin目录下的脚本,大多数maven命令都需要依赖插件
才能执行。
maven的命令跨平台
(因为是java脚本),在Windows、Linux、Mac都是一样的命令。
执行和声明周期过程有关的maven命令,必须在pom.xml所在目录
。
每套生命周期
对应一个接口/抽象类
,生命周期中的每个阶段(phase
)对应一个方法声明
。生命周期定义了phase的顺序,但是没有实现方法。插件目标goal
可以看做是生命周期各个phase对应方法的实现
,为复用代码,多个相似功能的goal组合成一个插件。使用maven命令
执行到生命周期某个phase时,是通过将该phase和对应插件goal绑定
实现的。maven的插件高度易扩展,可以自定义配置,插件和phase间的绑定关系也可以自定义。
构建(build
)对应的就是maven的三个生命周期,其中核心是default
构件包括构建项目时使用的依赖、插件,以及该项目的构建完成后的输出。
构件通过坐标定位,根据坐标在仓库中取得。
maven命令的执行,使用的是maven安装目录下的bin目录中的脚本。
大部分maven命令的执行,需要依赖插件,即bin目录中的脚本会调用相关插件实现特定功能。
maven的配置文件包括:
pom.xml
某个项目范围内有效
%USER_HOME%/.m2/settings.xml
某个用户范围内有效
${maven.home}/conf/settings.xml
全局范围有效
其他:
artifact是maven中的一个概念,对应的是被打包文件的名字,也就对应一个被打包的文件。在IntelliJ IDEA中,module是编译、运行、测试和调试的单位,也是打包的单位。因此IDEA中使用maven时,一个module对应一个artifact包。
https://blog.csdn.net/wangdong5678999/article/details/72848044 maven生命周期
https://www.cnblogs.com/luotaoyeah/p/3819001.html maven的生命周期和插件
https://www.runoob.com/maven/maven-tutorial.html maven 菜鸟教程
https://www.cnblogs.com/tooy/p/7364303.html 可选依赖和排除依赖
https://blog.csdn.net/weixin_42112635/article/details/87465997 外部依赖
https://www.runoob.com/maven/maven-snapshots.html 快照
https://blog.csdn.net/xiaoniaox/article/details/79029130 artifact 《Maven实战》
https://blog.csdn.net/zlgydx/article/details/51130627 maven 仓库配置 pom中repositories属性 - CSDN
https://blog.csdn.net/zhangbeizhen18/article/details/91353832 使用IntelliJ IDEA创建基于maven的父工程与子工程