Maven POM文件介绍

摘要:
从官方网站上看,Maven的最新版本是3.8.11.1SuperPOMSuperPOM,这是一个特殊的POM文件,也是Maven默认的POM。如果未指定,则所有POM都继承自SuperPOM。如果设置。修改xml文件时,将读取xml文件中的配置。注意:您必须解压缩mavenmodelbuilder-3.8.1.jar文件以获得进一步的路径。示例1在前面的示例中,com。我的公司。app:我的app:1被提到了。假设我们介绍另一个项目,com。我的公司。app:我的模块:1<project><modelVersion>4.0.0</modelVersion<groupId>com。mycompany应用程序我的模块1要从我的应用程序继承我的模块,我的模块可以使用以下POM文件4.0.0com。我的公司。应用我的应用1com。我的公司。这里介绍了应用程序我的模块1。此标记表示当前项目的父级。这样,我们的项目可以使用parentPOM的一些东西。

本文链接: https://www.cnblogs.com/hchengmx/p/15085639.html

1. POM文件是什么

pom是 Project Object Module(项目对象模型)的缩写,是Maven中的项目文件。这个文件很多 默认值。

官方网站 参考,目前Maven最新版本为 3.8.1

1.1 Super POM

Super POM 是一个特殊的POM文件,也是 Maven默认的 POM。

要是不指定的话,所有的 POM 都是继承于 Super POM,要是修改了 setting.xml文件,就会 读取xml文件中的配置。

这个POM文件可以在 [Maven Super Pom](Maven Model Builder – Super POM) 找到。

也可以在 本地这个路径找到 $MAVEN_HOME/lib/maven-model-builder-3.8.1.jar!/org/apache/maven/model/pom-4.0.0.xml

注:必须解压 maven-model-builder-3.8.1.jar 这个文件后,才可以得到得到进一步的路径。

以3.8.1 为例,Super POM 里面主要定义了一些基本的配置,

1. repositories

定义了一个名叫 central的repository,value是 'https://repo.maven.apache.org/maven2',可以从这个地址拉下来dependency。

2. pluginRepositories

默认 plugin的 repositories

3. build

设置了一些默认的路径,其中还定义了 几个插件,不过Maven官方也提醒,未来的版本会去掉。

<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) -->
    .....
</pluginManagement>

1.2 Minimal POM

对于一个POM来说,至少需要以下几个标签

  • project:root
  • modelVersion: 4.0.0
  • groupId: project所在组
  • artifactId: artifact(project)的id
  • version: artifact的版本

e.g.

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
</project>

注:groupId + artifactId + version 需要时唯一的。在仓库中的名字为 com.mycompany.app:my-app:1

运行 mvn package 就可以得到一个 JAR文件。

1.3 Effective POM

mvn help:effective-pom

会在控制台中输出,相当于 super pom + 当前项目的 pom。

3. 项目继承 和 项目聚合

2.1 Project Inheritance 项目继承

上例提到Super POM是一种特殊的 项目继承。同时,你也可以 自定义 你的项目要继承于哪个。

Example 1

在之前的例子中,提到了 com.mycompany.app:my-app:1,假如我们又引入了另外一个项目 com.mycompany.app:my-module:1

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-module</artifactId>
  <version>1</version>
</project>

想要 my-module继承于 my-app,my-module就可以用以下的POM文件

<project>
  <modelVersion>4.0.0</modelVersion>
 
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
  </parent>
 
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-module</artifactId>
  <version>1</version>
</project>

在这里引入了 ,这个标签就指明了说,我们当前的project的 parent是哪个。这样我们的项目就可以用 parent POM的一些东西了。

btw: 你项目的groupId 或者 version 要是和 parent的相同的话,你可以删除掉两行,看起来简练一点。

<project>
  <modelVersion>4.0.0</modelVersion>
 
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
  </parent>
 
  <artifactId>my-module</artifactId>
</project>

2.2 Project Aggregation 项目聚合

跟 Project Inheritance 类似,但是 Project Inheritance是在 子项目中 指明 父项目 是谁? Project Aggregation 是在父项目中,指代子项目都有谁

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
    <packaging>pom</packaging>

    <module>my-app-service-api</module>
    <module>my-app-infrastructure</module>
    <module>my-app-service</module>
    <module>my-app-start</module>
</project>

2.3 总结

要是有很多Maven projects,他们都拥有相似的 配置,就建议把 相似的配置提出来,放到 parent project里面。
要是有一些project,他们互相依赖,那就建议 用 Module的形式。

3. Dependency

3.1 Dependency Scope

在引用 dependency的时候,scope有两个作用,1 限制dependency的传递;2. 标明这个dependency 在何时有效。

比如

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.76</version>
</dependency>

compile

默认的scope。compile dependency在 项目的整个生命周期中都适用,同样,也会传递到依赖的项目中。

provided

跟compile相似,但是标明dependency 由 jdk或者容器提供,比如 Servlet AP 和 Java EE APIS,没有传递性。

runtime

编译的时候不用,执行的时需要,比如 JDBC。

test
只用于测试中,不用于运行时。比如 JUnit Mockito。

system
跟 provided相似,但是在系统中要以外部包的形式提供,maven不会在repository中查找它。所有它必须要有一个 systemPath 的标签

<dependencies>
  <dependency>
   <groupId>javax.sql</groupId>
   <artifactId>jdbc-stdext</artifactId>
   <version>2.0</version>
   <scope>system</scope>
   <systemPath>${java.home}/lib/rt.jar</systemPath>
  </dependency>
</dependencies>

import

import只适用于 里面,它是为了解决 maven只支持单继承的问题。比如公司有自己的项目,所以parent必须是公司的项目,但是又想继承于 spring boot,就可以用以下这种写法,标明将 spring-boot-dependencies中的 dependencyManagement的 dependencies,全部引入当前工程的 dependencyManagement

3.2 Transitive Dependencies 传递依赖

举个例子,要是 project A 依赖于 Project BProject B 又依赖于 project C,那么就有了依赖传递,这个时候 project A 依赖于 project C

  A
  ├── B
  │   └── C

那这个时候就有个问题,dependency scope是怎么传递的呢? 比如 上例中,引用Project B 的scope是 test,引用Project C的时候是 compile的,那A引用C的时候是什么 scope的呢?

就可以参考下面的对照关系,列是就是上例中的 project A 引用 project B的 scope,行就是上例中的 project B 引用 Project C的scope ,要是没有值的话,就代表这个dependency会被忽略掉。

compileprovidedruntimetest
compilecompile-runtime-
providedprovided-provided-
runtimeruntime-runtime-
testtest-test-

3.2.1 Optional dependencies

含义:可以主动不把 可以传递的依赖 传递下去。

例子:如果 B 引用 了C,并且把 Z表明为 Optional。

那么当 A 引用 B的时候,A就只会引用 B,不会引用 C,即使B和C的scope都是 compile。


<dependencies>
<!-- declare the dependency to be set as optional -->
    <dependency>
        <groupId>sample.ProjectC</groupId>
        <artifactId>Project-C</artifactId>
        <version>1.0</version>
        <scope>compile</scope>
        <optional>true</optional> <!-- value will be true or false only -->
    </dependency>
</dependencies>

3.2.2 Excluded denpendencies

如果 X 引用了Y,Y引用了Z,但是X又不想引用Z,就可以在引用Y的时候,Excluded Z。

3.2.3 Nearest Definition 最短路径原则

Example

  A
  ├── B
  │   └── C
  │       └── D 2.0
  └── E
      └── D 1.0

在以上的例子中,对于引用D有两种路径 A -> B -> C -> D 2.0 或者 A -> E -> D 1.0,Maven认为 AED 比 ABCD 短,所以实际引用D的版本号为 1.0。

Example

在以上的例子中,要是我们确实想引用 D2.0的话,就可以再加上一个dependency,把整个项目的引用关系变为如下

 A
  ├── B
  │   └── C
  │       └── D 2.0
  ├── E
  │   └── D 1.0
  │
  └── D 2.0 

此时 A -> D 2.0就变成最短的了。

注:要是路径长度长度相同,就选择第一个出现的版本。

3.3 dependencyManagement

这样的好处是:子项目无需再指定dependency的版本号,子项目的dependency的所有版本号 由 parent统一管理。

用以下这个POM引用举例子

  A
  ├── B
  │   └── C
  │       └── D
  └── E
      └── D

假如有一天,D升级了版本,这个时候需要做的事情是 C 和 E都需要更新升级版本,C升级的话,B也要升级,最终A也要被动升级版本。这样会遇到一个问题,子项目升级版本以后,需要父项目被动的升级版本,项目多的话很可能就传输信息错误了。那么能不能所有的版本管理,由父项目统一管理呢,每次版本更新,只需要更新父项目,变成主动的更新。

所以对于上面的例子,A项目就可以维护一个 的 section,维护B、C、D、E的版本号。这样 B、C、D、E被引用的时候就不用声明版本号了。

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.my-app</groupId>
            <artifactId>project-b</artifactId>
            <version>${project.b.version}</version>
        </dependency>
        <dependency>
            <groupId>com.my-app</groupId>
            <artifactId>project-c</artifactId>
            <version>${project.c.version}</version>
        </dependency>
        ......
    </dependencies>
</dependencyManagement>

假如 C引用D的时候,没有版本号,此时

MAVEN的逻辑是:

  • 要是指定了 Version,那就取指定 Version的dependency。
  • 要是没有指定 Version,就去parent里面的 tag下找,有无这个dependency的声明,有的话取这个版本的 dependency,没有的话报错。

参考链接

1. Maven - Ref links
2. maven/pom-4.0.0.xml · apache/maven
3. Maven – Introduction to the POM
4. Maven – POM Reference
5. Maven: The Complete Reference - The Nexus

免责声明:文章转载自《Maven POM文件介绍》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇JAVA中3种将byte转换为String的方法【Unity】伪线框渲染Shader的实现下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

maven打包出现unable to find main class问题

搜了好久,有人提到需要spring-boot-maven-plugin这个插件。 添加以后,有的可以了,有的不行。 最后发现是插件必须配置<skip>true</skip>这个节点。 完整来说,就是在pom文件(或者父pom中),有这样一个配置: <build> <plugins> <plu...

springboot整合kafka实现消息推送

前言 本篇文章主要介绍的是springboot整合kafka。 安装kafka 1.使用docker安装kafka,移步 https://www.cnblogs.com/lixianguo/p/13254950.html 创建工程 1.创建一个名为springboot-kafka的pom项目作为父工程,将main和resource文件夹都删除,pom文件添...

【Spring Boot】Spring Boot之两种引入spring boot maven依赖的方式

一、方式一:spring-boot-starter-parent   <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifa...

maven 配置多模块项目 pom modules

所有用Maven管理的真实的项目都应该是分模块的,每个模块都对应着一个pom.xml。它们之间通过继承和聚合(也称作多模块,multi-module)相互关联。那么,为什么要这么做呢?我们明明在开发一个项目,划分模块后,导入Eclipse变成了N个项目,这会带来复杂度,给开发带来不便。 为了解释原因,假设有这样一个项目,很常见的JavaWeb应用。在这个应...

maven项目的继承

多个maven项目之间难免有重复的pom配置,重复的配置没必要重复写,maven提供了父子继承的关系,重复的依赖直接放在父项目的pom中。 所以不希望每个开发者随意定义maven版本依赖,可以在父项目中进行说明,然后子项目沿用即可。 idea创建父项目(这是一个父项目,也是一个空项目,只需要pom.xml,编写相关的依赖, 父项目必须用pom打包的方式):...

Spring Boot 多模块与 Maven 私有仓库

前言 系统复杂了,抽离单一职责的模块几乎是必须的;若需维护多个项目,抽离公用包上传私有仓库管理也几乎是必须的。其优点无需赘述,以下将记录操作过程。 1. 多模块拆分 在.NET 中由于其统一性,实现上更自然一点。Spring Boot 通过 Maven 构建多模块工程也不麻烦,假如我的项目中包含以下几个包: 我需要将他们分别拆分成独立模块,首先要修改的是根...