- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
POM代表“项目对象模型”。它是一个名为 pom.XML 的文件中保存的Maven项目的XML表示.
这是一个直接位于POM项目元素下的元素列表。 请注意, modelVersion 包含4.0.0。这是目前唯一支持的POM版本,并且始终是必需的.
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- The Basics -->
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<packaging>...</packaging>
<dependencies>...</dependencies>
<parent>...</parent>
<dependencyManagement>...</dependencyManagement>
<modules>...</modules>
<properties>...</properties>
<!-- Build Settings -->
<build>...</build>
<reporting>...</reporting>
<!-- More Project Information -->
<name>...</name>
<description>...</description>
<url>...</url>
<inceptionYear>...</inceptionYear>
<licenses>...</licenses>
<organization>...</organization>
<developers>...</developers>
<contributors>...</contributors>
<!-- Environment Settings -->
<issueManagement>...</issueManagement>
<ciManagement>...</ciManagement>
<mailingLists>...</mailingLists>
<scm>...</scm>
<prerequisites>...</prerequisites>
<repositories>...</repositories>
<pluginRepositories>...</pluginRepositories>
<distributionManagement>...</distributionManagement>
<profiles>...</profiles>
</project>
<?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.study</groupId>
<artifactId>kafka-meter</artifactId>
<version>1.0</version>
<description>Kafka plugin for JMeter</description>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<apache.jmeter.core>5.4.1</apache.jmeter.core>
<org.log4j>2.11.1</org.log4j>
<sf.kafka.api.core.version>1.18.2</sf.kafka.api.core.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_core</artifactId>
<version>${apache.jmeter.core}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${org.log4j}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${org.log4j}</version>
</dependency>
<dependency>
<groupId>com.sf.kafka</groupId>
<artifactId>sf-kafka-api-core</artifactId>
<version>${sf.kafka.api.core.version}</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
</project>
POM包含关于项目的所有必要信息,以及构建过程中要使用的插件的配置.
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-project</artifactId>
<version>1.0</version>
</project>
上面定义的POM是Maven允许的最小配置。 groupId:artifactId:version 都是必需字段(不过,如果从父级继承 groupId 和 version ,则不需要显式定义它们-稍后将详细介绍继承)。这三个字段的作用非常像一个地址和时间戳。这标志着仓库中的一个特定位置,就像Maven项目的坐标系一样:
groupId
org.apache.Maven
下。 groupId
不一定使用点符号,例如junit项目。请注意,点标记的 groupId
不必与项目包含的包结构相对应。然而,这是一个很好的做法。当存储在仓库中时,该组的行为与操作系统中的Java包结构非常相似。点被操作系统特定的目录分隔符(如Unix中的“/”)所取代,后者成为Base仓库的相对目录结构。在给定的示例中, org.codehaus.mojo
组位于目录 $M2_REPO/org/codehaus/mojo
中。 artifactId
通常是项目的名称。尽管 groupId
很重要,但组内的人很少在讨论中提到 groupId
(他们通常都是同一个ID,例如 MojoHaus 项目groupId: org.codehaus.mojo
)。 artifactId
和 groupId
一起创建了一个Key,将这个项目与世界上其他所有项目区分开来(至少,它应该 😃)。 artifactId
和 groupId
完全定义了工件在仓库中的存储区。在上述项目中, my-project
位于 $M2_REPO/org/codehaus/mojo/my-project
。 my-project
版本 1.0文件位于目录结构 $M2_REPO.org/codehaus/mojo/my-project/1.0
中。 上面给出的三个元素指向一个项目的特定版本,让Maven知道我们在与谁打交道,以及在其软件生命周期中我们需要它们的时间.
现在我们有了 groupId:artifactId:version 的地址结构,还有一个标准标签可以给我们一个真正完整的东西:那就是项目的 packaging 。上述示例中定义的 org.codehaus.mojo:my project:1.0 的示例POM将被打包为一个 jar 文件。我们可以通过定义不同的 packaging 将其变成一个 war 文件:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<packaging>war</packaging>
...
</project>
当没有声明任何 packaging 时,默认为 jar 。当前的核心 packaing 值为: pom 、 jar 、 maven-plugin 、 ejb 、 war 、 ear 、 rar 。这些定义了在特定包结构的每个相应构建生命周期阶段执行的目标的默认列表:请参阅 Plugin Bindings for default lifecycle Reference 详细信息.
POM的基石是其 依赖性 列表。大多数项目都依赖于其他项目来正确构建和运行。即便Maven为你所做的只是管理这个列表,你也受益很多了。Maven在编译以及执行其它需要它们的插件目标时下载并链接依赖。此外,Maven会自动引入这些依赖项的依赖项(传递依赖项),使你的列表可以只关注项目所需的依赖项.
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<type>jar</type>
<scope>test</scope>
<optional>true</optional>
</dependency>
...
</dependencies>
...
</project>
groupId,artifactId,version 。
你会经常看到这些元素。这三位一体用于计算特定项目的Maven坐标,将其界定为该项目的依赖项。此计算的目的是选择一个与所有依赖声明匹配的版本(由于可传递依赖,同一工件可能有多个依赖声明)。这些值应为:
groupId , artifactId :直接对应依赖关系的坐标, 。
version : 依赖版本需求说明 ,用于计算依赖的有效版本.
由于依赖关系是由Maven坐标描述的,你可能会想:“这意味着我的项目只能依赖于Maven工件!”答案是,“当然,但这是一件好事。”这迫使你只能依赖Maven可以管理的依赖关系.
不幸的是,有时项目无法从central Maven 仓库库下载。例如,一个项目可能依赖于 。
例如,一个项目可能依赖于一个拥有封闭源代码许可证的jar,该许可证阻止它位于central仓库中。有三种方法可以处理这种情况.
使用安装插件在本地安装依赖项。该方法是最简单的推荐方法。例如
mvn install:install-file -Dfile=non-maven-proj.jar -DgroupId=some.group -DartifactId=non-maven-proj -Dversion=1 -Dpackaging=jar
请注意,地址仍然是必需的,只是这次使用命令行,安装插件将为您创建一个具有给定地址的POM 。
创建自己的仓库并发布依赖。这是拥有内联网的公司最喜欢的方法,需要能够让每个人都保持同步。Maven有一个名为 deploy:deploy-file 的目标,它类似于 install:install-file 目标.
将依赖关系范围设置为 system 并定义 systemPath 。但是,不建议这样做 。
classifier 。
classifier区分从相同POM构建但内容不同的工件。它是一些可选的任意字符串,如果有值的话,它会被附加到工件名称中版本号后面.
以项目为例来说明这个元素的动机。假设有个项目,该项目提供了一个以Java 11为目标的工件,但同时也提供了仍然支持Java 1.8的工件。第一个工件可以配备有 classifier jdk11 ,第二个工件配备 jdk8 ,这样客户端可以选择使用哪一个.
classifier 的另一个常见用法是将次要工件附加到项目的主要工件上。如果浏览Maven center仓库库,你会注意到 classifier sources 和 javadoc 用于部署项目源代码和API文档以及打包的类文件 。
type 。
对应于所选的依赖项类型。默认为 jar 。虽然它通常表示依赖项文件名上的扩展名,但情况并非总是如此:一个类型可以映射到不同的扩展名和classifier。类型通常与所使用的packaging相对应,尽管情况并非总是如此。类型的一些示例值 jar , ejb-client 和 test-jar :请参见 默认工件处理程序 以获取列表。新类型可以由将 extensions 设置为 true 的插件定义,因此这不是一个完整的列表 。
scope 。
这个元素指的是手头任务(编译和运行时、测试等)的类路径,以及如何限制依赖项的传递性。有五个作用域可用:
provided
。只是你必须提供显式包含它的JAR。工件始终可用,并且不会在仓库中查找 systemPath 。
仅依赖项 scope 为 system 时使用。否则,如果设置了此元素,则将构建失败。此路径必须是绝对路径,因此建议使用属性来指定特定于机器的路径(查看下文的 properties 获取更多 ),例如 ${java.home}/lib 。由于假设系统作用域依赖项是事先安装的,因此Maven不会检查项目的仓库,而是检查以确保文件存在,如果不存在,Maven将构建失败,并建议你手动下载并安装它.
optional 。
当此项目本身是依赖项时,将依赖项标记为可选。例如,假设一个项目 A 依赖于项目 B 来编译一部分可能在运行时不使用的代码,那么我们可能不需要所有项目都使用项目 B 。因此,如果项目 X 添加项目 A 作为自己的依赖项,那么Maven根本不需要安装项目 B 。象征性地,如果 => 表示必需的依赖项,而 --> 表示可选,构建 A 时有 A=>B ,但构建 X 时则是 X=>A-->B .
简而言之, optional 让其他项目知道,当你使用此项目时,不需要此依赖项也能正常工作.
依赖项 version 元素定义了用于计算依赖项版本的版本要求。软需求可以被依赖关系图中其他地方相同工件的不同版本所取代。硬需求要求特定的一个或多个版本,并凌驾于软需求之上。如果没有满足该工件所有硬需求的依赖项版本,则构建失败.
版本需求具有以下语法
1.0 : 要求1.0版本(软需求)。如果依赖关系树的早期版本中未出现其他版本,则使用1.0.
[1.0] : 要求1.0版本。使用且仅使用1.0(硬需求) 。
(,1.0] : 要求<=1.0的任意版本(硬需求) 。
[1.2,1.3] : 要求1.2至1.3(含1.2和1.3)之间的任意版本(硬需求).
[1.0,2.0) : 1.0 <= x < 2.0; 要求1.0到2.0之间(含1.0,不含2.0)的任意版本(硬需求).
[1.5,) : 要求大于等于1.5的任意版本(硬需求) 。
(,1.0],[1.2,) : 要求小于或等于1.0、大于或等于1.2但不等于1.1的任意版本(硬需求)。多个需求用逗号分隔.
(,1.1),(1.1,) : 要求除1.1以外的任意版本(硬需求);假设因为1.1存在严重漏洞.
Maven选择每个项目的最高版本,以满足该项目依赖项的所有硬性要求。如果没有一个版本能够满足所有的硬性要求,那么构建就会失败.
如果版本字符串为语法正确的 Semantic Versioning 1.0.0 版本号,那么在几乎所有情况下,版本比较都遵循该规范中概述的优先级规则。这些版本是常见的字母数字ASCII字符串,如2.15.2-alpha。更准确地说,如果要比较的版本号都与语义版本规范中BNF语法中的“有效semver”生成相匹配,则情况也是如此。Maven不考虑该规范所隐含的任何语义.
重要 :这仅适用于Semantic Versioning 1.0.0。Maven版本顺序算法与Semantic version 2.0.0 不兼容。特别是,Maven没有对加号进行特殊处理,也没有考虑构建标识符.
当版本字符串不遵循Semantic Versioning时,需要一组更复杂的规则。Maven坐标被分割为点之间的标记(' . '),hyphe 。
Maven坐标按点(' . ')、连字符(' - '),数字和字符之间的过渡之间的标记(token)进行拆分。分隔符将被记录并将对顺序产生影响。数字和字符之间的过渡相当于连字符。空的标记将替换为“ 0 ”。这给出了一系列带有“ . ”或“ - ”前缀的版本号(数字标记)和版本限定符(非数字标记)(官方原文:The Maven coordinate is split in tokens between dots (' . '), hyphens (' - ') and transitions between digits and characters. The separator is recorded and will have effect on the order. A transition between digits and characters is equivalent to a hyphen. Empty tokens are replaced with " 0 ". This gives a sequence of version numbers (numeric tokens) and version qualifiers (non-numeric tokens) with " . " or " - " prefixes) 。
拆分和替换示例:
1-1.foo-bar1baz-.1
-> 1-1.foo-bar-1-baz-0.1
然后,从版本的末尾开始,对后面的“null”值( 0 , "" ," final "," ga ")进行修剪。在每一个剩余的连字符上从头到尾重复此过程.
修剪示例
1.0.0
-> 1
1.ga
-> 1
1.final
-> 1
1.0
-> 1
1.
-> 1
1-
-> 1
1.0.0-foo.0.0
-> 1-foo
1.0.0-0.0.0
-> 1
版本顺序是这个带前缀的token序列上的“词典顺序”,带有匹配前缀的较短token,填充了足够多的的“null”值,与较长的token长度相同。填充的“null”值取决于其他版本的前缀:0表示“.”,"" 代表 '-'。带前缀的token顺序为:
如果前缀相同,则比较token
字标型token按自然顺序排序.
非数字型token(“限定符”)按字母顺序排序,除了下token按此顺序排列在前:
" alpha " < " beta " < " milestone " < " rc " = " cr " < " snapshot " < "" = " final " = " ga " < " sp " 。
alpha
", " beta
" 和" milestone
"可以分别缩写为"a", "b"和"m" 否 " .qualifier " = " -qualifier " < " -number " < " .number " 。
alpha = a << > = b <<<milestone>> = m < > = cr <<<snapshot>> '<<<>>' = final = ga = release < sp 。
建议遵循semver规则,不建议使用某些修饰:
alpha
', ' beta
', 和' milestone
' 修饰符优先于 ' ea
' 和' preview
'. 1.0.0-RC1
'' 优先于' 1.0.0.RC1
'. CR
'限定符,改用' RC
'。 final
', ' ga
'和' release
' 限定符 SP
' 限定符。增加补丁版本号(patch version) 最终结果示例
" 1 " < " 1.1 " (数字填充) 。
" 1-snapshot " < " 1 " < " 1-sp " (限定符填充) 。
" 1-foo2 " < " 1-foo10 " (正确自动的"切换"为数字顺序) 。
" 1.foo " = " 1-foo " < " 1-1 " < " 1.1 " 。
" 1.ga " = " 1-ga " = " 1-0 " = " 1.0 " = " 1 " (移除末尾"null"值) 。
" 1-sp " > " 1-ga " 。
" 1-sp.1 " > " 1-ga.1 " 。
" 1-sp-1 " < " 1-ga-1 " = " 1-1 " (每个连字符后面的"null"值) 。
" 1-a1 " = " 1-alpha-1 " 。
注意:与一些设计文档中所述的相反,对于版本顺序,snapshot与release或任何其他限定符没有区别对待.
注意:由于 2.0-rc1 < 2.0 ,版本要求 [1.0,2.0) 不包括 2.0 但包括 2.0-rc1 ,这与大多数人的预期相反。此外,Gradle对它的解释不同,导致同一POM的依赖树不同。如果打算将其限制为1.*版本,则更好的版本号要求是 [1,1.9999999) .
限制依赖项的可传递依赖项有时很有用。依赖项可能具有错误指定的作用域,或者与项目中的其他依赖项冲突的依赖项。 exclusions 告诉Maven不要在classpath中包含指定的工件,即使它是该项目的一个或多个依赖项的依赖项(传递依赖项)。例如, maven-embedder 依赖于 maven-core 。假设您想依赖 maven-embedder ,但不想在classpath中包含 maven-core 或其依赖项,那么在声明依赖 maven-embedder 的元素中添加 maven-core 作为 exclusion :
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>3.9.3</version>
<exclusions>
<exclusion>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
</exclusion>
</exclusions>
</dependency>
...
</dependencies>
...
</project>
这只会从这个依赖项中删除指向 maven-core 的路径。如果 maven-core 在POM的其他地方作为直接或传递依赖出现,那么它仍然可以添加到classpath径中.
通配符排除,很容易排除依赖项的所有可传递依赖项。在以下情况中,假设你正在使用 maven-embedder ,并且你希望管理你使用的依赖项,因此你排除了所有传递依赖项:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>3.8.6</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
...
</dependencies>
...
</project>
exclusions
包含一个或多个 exclusion
元素,每个元素都包含表示要排除的依赖项的 groupId
和 artifactId
。与可能安装和使用,也可能不安装和使用的 optional
不同, exclusions
会主动从依赖树中移除工件。 Maven为构建管理带来的一个强大的补充是项目继承的概念.
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-parent</artifactId>
<version>2.0</version>
<packaging>pom</packaging>
</project>
Now we may add values to the parent POM, which will be inherited by its children. Most elements from the parent POM are inherited by its children, including 。
对于 parent 和 aggregation (多模块)项目,要求 packaging 类型为 pom 。这些类型定义了绑定到一组生命周期阶段的目标。例如,如果 packaging 类型是 jar ,那么 packaging 阶段将执行 jar:jar 目标。现在,我们可以为 parent 添加值,该值将由其子代继承。 parent 的大多数元素由其子代继承,包括
值得注意是以下元素不被继承
artifactId 。
name 。
prerequisites 。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-parent</artifactId>
<version>2.0</version>
<relativePath>../my-parent</relativePath>
</parent>
<artifactId>my-project</artifactId>
</project>
注意 relativePath 元素,这不是必需的,但可以作为Maven的一个意符,实现在搜索本地和远程仓库之前,首先搜索为父项目提供的路径,即 relativePath 设置的值.
类似于面向对象编程中的对象继承,扩展父POM的POM从该父POM继承某些值。此外,正如Java对象最终继承自 java.lang.Object 一样,所有项目对象模型都继承自一个基本的Super POM。下面的片段是Maven 3.5.4的Super POM 。
<project>
<modelVersion>4.0.0</modelVersion>
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
<build>
<directory>${project.basedir}/target</directory>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<finalName>${project.artifactId}-${project.version}</finalName>
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>${project.basedir}/src/test/resources</directory>
</testResource>
</testResources>
<pluginManagement>
<!-- NOTE: These plugins will be removed from future versions of the super POM -->
<!-- They are kept for the moment as they are very unlikely to conflict with lifecycle mappings (MNG-4453) -->
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
</plugin>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<reporting>
<outputDirectory>${project.build.directory}/site</outputDirectory>
</reporting>
<profiles>
<!-- NOTE: The release profile will be removed from future versions of the super POM -->
<profile>
<id>release-profile</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<inherited>true</inherited>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<updateReleaseInfo>true</updateReleaseInfo>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
你可以通过创建一个最小化的 pom.xml 并在命令行上执行: mvn help:effective-pom 来了解Super POM如何影响你的项目对象模型 。
除了继承某些顶级元素外, parent 还拥有一些元素,可以为子POM和传递依赖项配置值。其中一个要素是 dependencyManagement .
dependencyManagement :由POM用来帮助管理其所有子级的依赖关系信息。如果 my-parent 使用 dependencyManagement 定义对 junit:junit:4.12 的依赖,那么从这个项目继承的POM设置他们的依赖项时可以仅提供 groupId=junit 和 artifactId=junit , version 将被Maven填充为父项目设置的版本。这种方法的好处是显而易见的。可以集中在一个中心位置设置依赖关系详细信息,并传播到所有继承的POM.
请注意,从可传递依赖项合并的工件的版本和作用域也由依赖项管理部分中的版本规范控制。这可能会导致意想不到的后果。考虑一个项目使用两个依赖项 dep1 和 dep2 的情况。 dep2 反过来也使用dep1,并且需要特定的最低版本才起作用。如果随后使用 dependencyManagement 指定较旧版本, dep2 将被迫使用较旧版本,因此失败。因此,您必须小心检查整个依赖树,以避免出现此问题; mvn dependency:tree 很有帮助.
A project with modules is known as a multi-module, or aggregator project. Modules are projects that this POM lists, and are executed as a group. A pom packaged project may aggregate the build of a set of projects by listing them as modules, which are relative paths to the directories or the POM files of those projects. 。
包含模块的项目称为多模块或聚合项目。模块是本POM列出的项目,并作为一个组执行。 pom 打包项目可以通过将一系列项目列为模块(项目目录或pom文件的相对路径)来聚合构建.
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-parent</artifactId>
<version>2.0</version>
<packaging>pom</packaging>
<modules>
<module>my-project</module>
<module>another-project</module>
<module>third-project/pom-example.xml</module>
</modules>
</project>
在列出模块时,你不需要自己考虑模块间的依赖关系;也就是说,由POM给出的模块的排序并不重要。Maven将对模块进行拓扑排序,这样依赖关系总是在依赖模块之前构建.
Properties are the last required piece to understand POM basics. Maven properties are value placeholders, like properties in Ant. Their values are accessible anywhere within a POM by using the notation ${X} , where X is the property. Or they can be used by plugins as default values, for example
properties 是理解POM基础知识所需的最后一部分。Maven properties 是值占位符,类似于Ant中的 properties 。通过使用符号 ${X} ,可以在POM中的任何位置访问 properties 的值,其中 X 是 property 。或许它们可以被插件用作默认值,例如:
<project>
...
<properties>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<!-- Following project.-properties are reserved for Maven in will become elements in a future POM definition. -->
<!-- Don't start your own properties properties with project. -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
...
</project>
properties 具有5种不同的风格
env.X :在属性变量前加前缀 env. 将返回shell环境变量。例如, ${env.PATH} 将返回 PATH 环境变量值.
注意:虽然环境变量本身在Windows上不区分大小写,但 properties 的查找是区分大小写的。换句话说,虽然Windows shell为 %PATH% 和 %Path% 返回相同的值,但Maven区分 ${env.PATH} 和 ${env.Path} 。为了可靠性, 将环境变量的名称都标准化为大写 .
project.x : POM中点分路径将包含相应元素的值。例如:通过 ${project.version} 获取 version 属性值 1.0 。
settings.x : settings.xml 点分路径将包含相应元素的值。例如:通过 ${settings.offline} 获取 offline 属性值 false 。
Java系统属性:所有可通过 Java.lang.System.getProperties() 访问的属性都可用作POM属性,比如 ${java.home} 。
x : 在POM中的 元素内设置。 <properties><someVar>value</someVar></properties> 的值 value 可以用作 ${someVar} .
根据POM 4.0.0 XSD, build 元素在概念上分为两个部分:一个是 BaseBuild 类型,它包含两个 build 元素共有的一系列元素( project 下的顶级 build 元素和 profiles 下的 build 元件,如下所述);另一个是 Build 类型,包含 BaseBuild 元素集以及用于顶层定义的更多元素.
注意:这些不同的 build 元素可以表示为“Project Build”和“Profile Build” 。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<!-- "Project Build" contains more elements than just the BaseBuild set -->
<build>...</build>
<profiles>
<profile>
<!-- "Profile Build" contains a subset of "Project Build"s elements -->
<build>...</build>
</profile>
</profiles>
</project>
BaseBuild :POM中两个 build 元素之间的基本元素集.
<build>
<defaultGoal>install</defaultGoal>
<directory>${basedir}/target</directory>
<finalName>${artifactId}-${version}</finalName>
<filters>
<filter>filters/filter1.properties</filter>
</filters>
...
</build>
defaultGoal : 如果什么都没有给定时,默认执行的目标(goal)或阶段(phase)。如果给定了一个目标,那么应该和在命令行中一样定义它(例如 jar:jar )。如果定义了一个阶段(例如install),情况也是如此.
directory : 这是构建将转储其文件,或者用Maven的术语,其构建目标的目录。它恰当地默认为 ${basedir}/target .
finalName : 这是绑定项目最终被构建的名称(没有文件扩展名,例如: my-project-1.0.jar )。默认为 ${artifactId}-${version} 。然而,术语 finalName 有点用词不当,因为构建绑定项目的插件完全有权忽略、修改这个名称(通常不会)。例如,如果 maven-jar-plugin 被配置为给某个jar一个 test 的 classifier ,那么上面定义的jar实际将被构建为 my-project-1.0-test.jar .
filter :定义 *.properties 文件,该文件包含应用于接受其设置的资源的属性列表(如下所述)。换句话说, filter 文件中定义的 " name=value "对将在构建时替换资源中的 ${name} 字符串。上面的示例定义了位于 filters/ 目录下的 filter1.properties 文件。Maven的默认filter目录为 ${basedir}/src/main/filters/ .
要更全面地了解filter是什么以及它们可以做什么,请查看 快速入门指南 。
For a more comprehensive look at what filters are and what they can do, take a look at the quick start guide . 。
*.properties
files that contain a list of properties that apply to resources which accept their settings (covered below). In other words, the " 。
name=value
" pairs defined within the filter files replace 。
${name}
strings within resources on build. The example above defines the 。
filter1.properties
file under the 。
filters/
directory. Maven's default filter directory is 。
${basedir}/src/main/filters/
. 。
For a more comprehensive look at what filters are and what they can do, take a look at the quick start guide . 。
build 元素的另一个功能是指定项目中资源的位置。资源不是(通常)代码。它们不被编译,但是需要捆绑在项目中或用于其它各种需要(如代码生成).
例如,某个Plexus项目需要一个位于 META-INF/plexus 目录中的 configuration.xml 文件(该文件指定容器的组件配置)。尽管我们可以很容易地将此文件放置在 src/main/resources/META-INF/plexus 中,但我们希望为plexus提供自己的 src/main/plexus 目录。为了让JAR插件正确地绑定资源,你可以指定类似于以下资源
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<build>
...
<resources>
<resource>
<targetPath>META-INF/plexus</targetPath>
<filtering>false</filtering>
<directory>${basedir}/src/main/plexus</directory>
<includes>
<include>configuration.xml</include>
</includes>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
<testResources>
...
</testResources>
...
</build>
</project>
targetPath
默认为基目录(base目录)。通常为将打包在JAR中的资源指定的 targetPath
为 META-INF
。 true
或者 false
, 表示是否要为此资源启用过滤。请注意,过滤器 *.properties
文件不定义也可进行过滤-资源也可以使用默认情况下在POM中定义的 properties
(如 ${project.version}
),使用 -D
标志(例如," -Dname
= value
")传递到命令行或由 properties
元素显式定义的属性。 ${basedir}/src/main/resources
.此元素的值定义了资源的查找位置。构建的默认目录是 ${basedir}/src/main/resources
。 *
作为通配符 includes
的结构相同,不过用于指定要忽略的文件。如果 include
和 exclude
之间如果存在冲突,则 exclude
“获胜”。 testResources
元素块包含 testResource
元素。它们的定义类似于 resource
元素,不过是在测试阶段使用。一个区别是,项目的默认(Super POM定义的)测试资源目录是 ${basedir}/src/test/resources
。测试资源不被发布。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<extensions>false</extensions>
<inherited>true</inherited>
<configuration>
<classifier>test</classifier>
</configuration>
<dependencies>...</dependencies>
<executions>...</executions>
</plugin>
</plugins>
</build>
</project>
除了标准坐标 groupId:artifactId:version 之外,还有一些元素可以配置插件或与插件交互的构建.
extensions : true 或者 false ,是否加载此插件的扩展。默认情况下为 false .
inherited : true 或者 false ,这个插件配置是否应该应用于继承自这个插件的POM。默认 true . 。
configuration : 这是特定于单个插件的。插件Mojo可能期望的任何属性(这些是Java Mojo bean中的getter和setter)都可以在这里指定。在上面的例子中,我们将 maven-jar-plugin Mojo中 classifier 属性设置为test。值得注意的是,所有配置元素,无论它们在POM中的哪个位置,都旨在将值传递给另一个底层系统,例如插件。换句话说:POM模式从来没有明确要求 configuration 元素中的值,但插件目标完全有权要求 configuration 值.
如果你的POM声明了一个parent,它将从parent的 build/plugins 或 pluginManagement 部分继承插件配置.
默认配置继承 :
为了进行说明,假设有来自父POM的以下配置:
<plugin>
<groupId>my.group</groupId>
<artifactId>my-plugin</artifactId>
<configuration>
<items>
<item>parent-1</item>
<item>parent-2</item>
</items>
<properties>
<parentKey>parent</parentKey>
</properties>
</configuration>
</plugin>
假设以下为某个项目的插件配置,该项目使用上述POM作为其parent 。
<plugin>
<groupId>my.group</groupId>
<artifactId>my-plugin</artifactId>
<configuration>
<items>
<item>child-1</item>
</items>
<properties>
<childKey>child</childKey>
</properties>
</configuration>
</plugin>
默认行为是根据元素名称合并 configuration 元素的内容。如果子POM具有特定元素,则其值将成为有效值。如果子POM没有元素,但父POM有,则父值将成为有效值。请注意,这纯粹是对XML的操作;不涉及插件本身的代码或配置,只涉及元素,而不是它们的值.
将这些规则应用到示例中,得到以下配置:
<plugin>
<groupId>my.group</groupId>
<artifactId>my-plugin</artifactId>
<configuration>
<items>
<item>child-1</item>
</items>
<properties>
<childKey>child</childKey>
<parentKey>parent</parentKey>
</properties>
</configuration>
</plugin>
combine.children
和 combine.self
可以通过向 configuration 元素的子元素添加属性-- combine.children 和 combing.self ,来控制子POM如何从父POM继承配置。在子POM中使用这些属性可以控制Maven如何将父级的插件配置与子级的显式配置相结合.
以下是带有这两个属性示例的子POM配置 。
<configuration>
<items combine.children="append">
<!-- combine.children="merge" is the default -->
<item>child-1</item>
</items>
<properties combine.self="override">
<!-- combine.self="merge" is the default -->
<childKey>child</childKey>
</properties>
</configuration>
现在,有效的结果如下:
<configuration>
<items combine.children="append">
<item>parent-1</item>
<item>parent-2</item>
<item>child-1</item>
</items>
<properties combine.self="override">
<childKey>child</childKey>
</properties>
</configuration>
combine.children="append" 将按顺序连接父元素和子元素。而 combine.self="override" 则完全抑制父配置。不能在元素上同时使用 combine.self="override" 和 combine.children="append" ,如果同时配置了则 combine.self="override" .
注意,这些属性只应用于它们声明的配置元素,而不会传递到嵌套元素。也就是说,如果子POM中的 item 元素的内容是一个复杂的结构,而不是文本,那么它的子元素仍将受到默认合并策略的约束,除非它们本身用属性标记.
子POM会从父POM继承 combine.* 属性。将这些属性添加到父POM时要小心,因为这可能会影响子POM或子孙POM.
dependencies : 在POM中可以看到很多依赖项,它们是所有 plugins 元素块下的一个元素。依赖项具有与base build 下相同的结构和功能。这种情况下的主要区别在于,它们不再作为项目的依赖项应用,而是作为所属插件的依赖项来应用。这样做的功能是更改插件的依赖项列表,可能是通过 exclusions 删除未使用的运行时依赖项,或者更改所需依赖项的版本.
executions :记住,一个插件可能有多个目标。每个目标可能有一个单独的配置,甚至可能将插件的目标绑定到不同的阶段 executions 配置插件目标的 execution .
例如,假设你想将 antrun:run 目标绑定到 verify 阶段。我们希望任务回显构建目录,并通过将 inherited 设置为 false 来避免将此配置传递给其子级(假设它是父级)。你将会得到这样的 execution :
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>echodir</id>
<goals>
<goal>run</goal>
</goals>
<phase>verify</phase>
<inherited>false</inherited>
<configuration>
<tasks>
<echo>Build Dir: /home/jenkins/82467a7c/workspace/aven_maven-box_maven-site_master/target</echo>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
id : 此 execution 块唯一标识。当阶段运行时,它将以 [plugin:target-execution:id] 的形式显示。在本例中: [antrun:run execution:echodir] 。
goals : 包含一个单数元素( goal )列表。在这种情况下,由这个 execution 块指定的插件 goals 列表 。
phase :设置目标列表将在其中执行的阶段。这是一个非常强大的选项,允许将任何目标绑定到构建生命周期中的任何阶段,从而改变Maven的默认行为 。
inherited : 类似上面的 inherited 元素,设置为 false 将禁止Maven将此 execution 传递给其子级。此元素仅对父POM有意义 。
configuration : 与上面的 configuration 相同,除了将配置限制在这个特定的目标列表中,而不是插件下的所有目标 。
plugins
几乎相同的方式包含插件元素,只是它不是为这个特定的项目构建配置插件信息,而是旨在配置从这个项目构建继承的项目构建。然而,这只配置在子POM或当前POM中 plugins
元素实际引用的插件。子POM们完全有权覆盖 pluginManagement
定义。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<build>
...
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>pre-process-classes</id>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>pre-process</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
...
</build>
</project>
如果我们将这些规范添加到 plugins 元素中,它们将仅适用于单个POM。然而,如果我们在 pluginManagement 元素下应用它们,那么这个POM和所有将 maven-jar-plugin 添加到构建中的继承POM也将获取 pre-process-classes execution 。因此,与其在每个子 pom.xml 中包含上述的混乱,只需要以下内容:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
</plugins>
...
</build>
</project>
目录元素集位于父级 build 元素中,该元素作为一个整体为POM设置了各种目录结构。由于它们不存在于 profiles build 中,因此 profiles 无法更改这些内容.
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<build>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
<outputDirectory>${basedir}/target/classes</outputDirectory>
<testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>
...
</build>
</project>
如果上面 *Directory 元素的值设置为绝对路径,则使用该路径。否则使用相对于基构建目录: ${basedir} 的路径。 注意, scriptSourceDirectory 未在Maven中使用,并且已经过时 .
扩展为要在此构建中使用的工件列表。它们将包含在正在运行的构建的classpath中。它们可以对构建过程开启扩展(例如为Wagon传输机制添加ftp提供商),并使插件处于活动状态,从而更改构建生命周期。简而言之,扩展是在构建过程中激活的工件。扩展实际上不必做任何事情,也不必包含Mojo。因此,扩展非常适合指定通用插件接口的多个实现中的一个.
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<build>
...
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ftp</artifactId>
<version>1.0-alpha-3</version>
</extension>
</extensions>
...
</build>
</project>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<reporting>
<outputDirectory>${basedir}/target/site</outputDirectory>
<plugins>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>2.0.1</version>
<reportSets>
<reportSet></reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
...
</project>
...... 。
更多配置参考,请查阅官方文档 。
https://maven.apache.org/pom.html 。
最后此篇关于JavaMavenPOM配置参考的文章就讲到这里了,如果你想了解更多关于JavaMavenPOM配置参考的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我是一名优秀的程序员,十分优秀!