04-POM简介

文章目录

Introduction to the POM

What is a POM?

A Project Object Model【项目对象模型】 or POM is the fundamental unit of work in Maven. It is an XML file that contains information about the project and configuration details used by Maven to build the project. It contains default values for most projects. Examples for this is the build directory, which is target; the source directory, which is src/main/java; the test source directory, which is src/test/java; and so on. When executing a task or goal, Maven looks for【查找】 the POM in the current directory. It reads the POM, gets the needed configuration information, then executes the goal.

Some of the configuration that can be specified【明确规定;详细说明】 in the POM are the project dependencies, the plugins or goals that can be executed, the build profiles, and so on. Other information such as the project version, description, developers, mailing lists and such can also be specified.

[top]

Super POM【超级POM】

The Super POM【超级POM,父POM -> Super Class 超类,父类】 is Maven’s default POM. All POMs extend the Super POM unless explicitly set, meaning the configuration specified in the Super POM is inherited by the POMs you created for your projects.

You can see the Super POM for Maven 3.6.3 in Maven Core reference documentation.

[top]

Minimal POM

The minimum requirement for a POM are the following:

  • project root
  • modelVersion - should be set to 4.0.0
  • groupId - the id of the project’s group.
  • artifactId - the id of the artifact (project)
  • version - the version of the artifact under the specified group

Here’s an example:

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

A POM requires that its groupId, artifactId, and version be configured. These three values form the project’s fully qualified【完全限定】 artifact name. This is in the form of ::. As for the example above, its fully qualified artifact name is “com.mycompany.app:my-app:1”.

Also, as mentioned in the first section, if the configuration details are not specified, Maven will use their defaults. One of these default values is the packaging type. Every Maven project has a packaging type. If it is not specified in the POM, then the default value “jar” would be used.

Furthermore, you can see that in the minimal POM the repositories were not specified. If you build your project using the minimal POM, it would inherit the repositories configuration in the Super POM. Therefore when Maven sees the dependencies in the minimal POM, it would know that these dependencies will be downloaded from https://repo.maven.apache.org/maven2 which was specified in the Super POM.

[top]

Project Inheritance【子POM继承】

Elements in the POM that are merged are the following:

  • dependencies
  • developers and contributors
  • plugin lists (including reports)
  • plugin executions with matching ids
  • plugin configuration
  • resources

The Super POM is one example of project inheritance, however you can also introduce your own parent POMs by specifying the parent element in the POM, as demonstrated in the following examples.

Example 1

The Scenario

As an example, let us reuse our previous artifact, com.mycompany.app:my-app:1. And let us introduce another artifact, 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>

And let us specify their directory structure as the following:

.
 |-- my-module
 |   `-- pom.xml
 `-- pom.xml

Note: my-module/pom.xml is the POM of com.mycompany.app:my-module:1 while pom.xml is the POM of com.mycompany.app:my-app:1

The Solution

Now, if we were to turn【将…转变;变为】 com.mycompany.app:my-app:1 into a parent artifact of com.mycompany.app:my-module:1,we will have to modify com.mycompany.app:my-module:1’s POM to the following configuration:

com.mycompany.app:my-module:1’s 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>

Notice that we now have an added section, the parent section. This section allows us to specify which artifact is the parent of our POM. And we do so by specifying the fully qualified artifact name of the parent POM. With this setup, our module can now inherit some of the properties of our parent POM.

Alternatively, if you want the groupId or the version of your modules to be the same as their parents, you can remove the groupId or the version identity of your module in its POM.

<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>

This allows the module to inherit the groupId or the version of its parent POM.

[top]

Example 2

The Scenario

However, that would work if the parent project was already installed in our local repository or was in that specific directory structure (parent pom.xml is one directory higher than that of the module’s pom.xml).

But what if the parent is not yet installed and if the directory structure is as in the following example?

.
 |-- my-module
 |   `-- pom.xml
 `-- parent
     `-- pom.xml
The Solution

To address this directory structure (or any other directory structure), we would have to add the <relativePath> element to our parent section.

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

As the name suggests, it’s the relative path from the module’s pom.xml to the parent’s pom.xml.

Project Aggregation【父POM聚合】

Project Aggregation is similar to Project Inheritance. But instead of specifying the parent POM from the module, it specifies the modules from the parent POM. By doing so, the parent project now knows its modules, and if a Maven command is invoked against the parent project, that Maven command will then be executed to the parent’s modules as well. To do Project Aggregation, you must do the following:

  • Change the parent POMs packaging to the value “pom”.
  • Specify in the parent POM the directories of its modules (children POMs).

[top]

Example 3

The Scenario

Given the previous original artifact POMs and directory structure:

com.mycompany.app:my-app:1’s POM

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

com.mycompany.app:my-module:1’s POM

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

directory structure

.
 |-- my-module
 |   `-- pom.xml
 `-- pom.xml
The Solution

If we are to aggregate my-module into my-app, we would only have to modify my-app.

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

In the revised【修改的;改进的】 com.mycompany.app:my-app:1, the packaging section and the modules sections were added. For the packaging, its value was set to “pom”, and for the modules section, we have the element <module>my-module</module>. The value of <module> is the relative path from the com.mycompany.app:my-app:1 to com.mycompany.app:my-module:1’s POM (by practice, we use the module’s artifactId as the module directory’s name).

Now, whenever a Maven command processes com.mycompany.app:my-app:1, that same Maven command would be ran against com.mycompany.app:my-module:1 as well. Furthermore, some commands (goals specifically) handle project aggregation differently.

[top]

Example 4

The Scenario

But what if we change the directory structure to the following:

.
 |-- my-module
 |   `-- pom.xml
 `-- parent
     `-- pom.xml

How would the parent POM specify its modules?

The Solution

The answer? - the same way as Example 3, by specifying the path to the module.

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

Project Inheritance vs Project Aggregation

If you have several Maven projects, and they all have similar configurations, you can refactor your projects by pulling out those similar configurations and making a parent project. Thus, all you have to do is to let your Maven projects inherit that parent project, and those configurations would then be applied to all of them.

And if you have a group of projects that are built or processed together, you can create a parent project and have that parent project declare those projects as its modules. By doing so, you’d only have to build the parent and the rest will follow.

But of course, you can have both Project Inheritance and Project Aggregation. Meaning, you can have your modules specify a parent project, and at the same time, have that parent project specify those Maven projects as its modules. You’d just have to apply all

three rules【三个规则】:

  • Specify in every child POM who their parent POM is.
  • Change the parent POMs packaging to the value “pom” .
  • Specify in the parent POM the directories of its modules (children POMs)

[top]

Example 5

The Scenario

Given the previous original artifact POMs again,

com.mycompany.app:my-app:1’s POM

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

com.mycompany.app:my-module:1’s POM

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

and this directory structure

.
 |-- my-module
 |   `-- pom.xml
 `-- parent
     `-- pom.xml
The Solution【三个规则的实际运用】

To do both project inheritance and aggregation, you only have to apply all three rules.

com.mycompany.app:my-app:1’s POM

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

com.mycompany.app:my-module:1’s POM

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

NOTE: Profile inheritance the same inheritance strategy as used for the POM itself.

[top]

Project Interpolation and Variables

One of the practices that Maven encourages is don’t repeat yourself. However, there are circumstances where you will need to use the same value in several different locations. To assist in ensuring the value is only specified once, Maven allows you to use both your own and pre-defined variables in the POM.

For example, to access the project.version variable, you would reference it like so:

  <version>${project.version}</version>

One factor to note is that these variables are processed after inheritance as outlined above【如上所述】. This means that if a parent project uses a variable, then its definition in the child, not the parent, will be the one eventually used【最终使用的那个】.

Available Variables【可用变量】

Project Model Variables

Any field of the model that is a single value element can be referenced as a variable. For example, ${project.groupId}, ${project.version}, ${project.build.sourceDirectory} and so on. Refer to the POM reference to see a full list of properties.

These variables are all referenced by the prefix “project.. You may also see references with pom. as the prefix, or the prefix omitted entirely【完全省略】 - these forms are now deprecated and should not be used.

Special Variables
project.basedirThe directory that the current project resides in.
project.baseUriThe directory that the current project resides in, represented as an URI. Since Maven 2.1.0
maven.build.timestampThe timestamp that denotes the start of the build (UTC). Since Maven 2.1.0-M1

The format of the build timestamp can be customized by declaring the property maven.build.timestamp.format as shown in the example below:

<project>
  ...
  <properties>
    <maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'</maven.build.timestamp.format>
  </properties>
  ...
</project>

The format pattern has to comply with the rules given in the API documentation for SimpleDateFormat. If the property is not present, the format defaults to the value already given in the example.

Properties

You are also able to reference any properties defined in the project as a variable. Consider the following example:

<project>
  ...
  <properties>
    <mavenVersion>3.0</mavenVersion>
  </properties>
 
  <dependencies>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-artifact</artifactId>
      <version>${mavenVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-core</artifactId>
      <version>${mavenVersion}</version>
    </dependency>
  </dependencies>
  ...
</project>

[top]

.flattened-pom.xml是一个文件,它在项目打包过程中由IDEA自动生成。它的作用是提供一个扁平化的pom.xml文件,供项目打包时读取依赖信息。 这个文件通常位于项目目录下,可以通过修改或删除它来解决一些问题。例如,当项目升级后,.flattened-pom.xml文件中的版本号可能会过时或错误,这时可以手动修改该文件中的版本号,以保持正确的依赖关系。或者,如果不需要该文件,也可以直接删除它。 如果你想查看一个具体的.flattened-pom.xml文件示例,你可以参考以下链接:<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [idea 打包引入版本不对问题](https://blog.csdn.net/hcc_new_one_object/article/details/130984295)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [【SpringBoot】Maven 版本管理与 flatten-maven-plugin 插件的使用及分析](https://blog.csdn.net/weixin_42201180/article/details/127204351)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值