ApacheMaven使用POM定义项目结构
官方文档:https://maven.apache.org/guides/introduction/introduction-to-the-pom.html
POM简介
一个项目对象模型或POM是Maven中的基本工作单元。它是一个XML文件,包含Maven用于构建项目的有关项目和配置细节的信息。它包含大多数项目的默认值。例如构建目录默认为 target
; 源目录默认为src/main/java
;源测试目录默认为 src/main/java
等。在执行任务或目标时,Maven会在当前目录中查找POM。它从POM中获取所需的配置信息,用于执行目标。
可以在POM中指定的一些配置包括项目依赖项、可执行的插件或目标、构建概要文件等等。还可以指定项目版本、描述、开发人员、邮件列表等其他信息。
超级POM
超级POM是Maven的默认POM。除非显式地设置,否则所有POMs都将扩展超级POM,这意味着在超级POM中指定的配置将被所有项目创建的POMs继承。下面的代码片段是Maven 3.5.4的超级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
对于POM内容的最小要求如下:
- project 根标签
- modelVersion - 应该设置为4.0.0
- groupId - 项目组的id(很多时候使用公司域名)
- artifactId - 工件的id(用于指定项目组下的某一个功能)
- version - 指定工件的版本
<project> <modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</project>
POM需要配置它的groupId、artifactId和version 。这三个值构成了项目的工件的完整名称。它的形式是<groupId>:<artifactId>:<version>。对于上面的例子,它的完整工件名称是“com.mycompany.app:my-app:1”。
如果没有指定配置细节,Maven将使用它们的默认值。其中一个默认值是打包类型,如果POM中没有指定它,那么将使用默认值“jar”。
您可以看到在最小的POM中没有指定存储库。如果使用最小POM构建项目,它将继承超级POM中的存储库配置。因此当Maven看到最小POM中的依赖项时,它将知道这些依赖项将从https://repo.maven.apache.org/maven2下载,这是在超级POM中指定的。
项目继承
合并后的POM中的元素如下:
- 依赖关系
- 开发者与参与者
- 插件列表 (引用报告)
- 对应id的插件执行
- 插件配置
- 资源
超级POM是项目继承的一个例子,但是您也可以通过在POM中指定父元素来引入您自己的父POM,如下面的例子所示。
例子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
| `-- pom.xml
`-- pom.xml
根目录pom.xml是com.mycompany.app:my-app:1的POM文件,而my-module目录下的pom.xml是com.mycompany.app:my-module:1的POM文件。
如果我们需要让com.mycompany.app:my-app:1作为com.mycompany.app:my-module:1的父工件,我们需要如下配置:
<project> <parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>
</project>
如果我们希望模块的groupId或version与它们的父模块相同,那么可以在POM中删除他们。
<project> <parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-module</artifactId>
</project>
例子2
如果父项目已经安装在我们的本地存储库中,或者在那个特定的目录结构中(父项目pom.xml比模块的pom.xml高一个目录),那么上例是可以的。
但是如果父目录还没有安装,并且目录结构与下面的示例一样该怎么办呢?
. |-- my-module
| `-- pom.xml
`-- parent
`-- pom.xml
要处理这个目录结构(或任何其他目录结构),必须将<relativePath>
元素添加到父部分,来指定父pom的位置。
<project> <parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-module</artifactId>
</project>
顾名思义,它是从模块的pom.xml到父模块的pom.xml的相对路径。
项目聚合
项目聚合类似于项目继承。但是他是通过在父POM中指定子模块来实现的(可以指定多个子模块)。这样父项目现在知道了它的所有子模块,如果对父项目调用Maven命令,那么Maven命令也将对父项目的所有子模块执行。
项目聚合需要两个条件:
- 将父POM中的 < packaging >打包标签设为“pom”。
- 在父POM中通过 modules 来指定子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>
<modules>标签用于指定当前pom到达指定子模块pom的相对路径。
项目继承与项目聚合共存
如果您有多个Maven项目,而且它们都具有类似的配置,那么您可以通过提取那些类似的配置并创建一个父项目来重构您的项目。您所要做的就是让Maven项目继承父项目,然后将这些配置应用于所有的项目。
如果您有一组需要一起构建或处理的项目,您可以创建一个父项目,并让该父项目将这些项目声明为其模块。通过这样做您只需要构建父项目,其余的将会被一起构建。
当然您可以同时拥有项目继承和项目聚合。您可以让您的模块指定一个父项目,同时让那个父项目指定那些Maven项目作为它的模块。你只需要应用这三个规则:
- 在每个子POM中指定其父POM是谁。
- 将父POMs包装更改为值“pom”。
- 在父POM中指定其模块的目录(子POMs)
目录结构
. |-- my-module
| `-- pom.xml
`-- parent
`-- pom.xml
父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>
子pom
<project> <parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-module</artifactId>
</project>
项目插值与变量
Maven鼓励的一个实践是不要重复自己。但在某些情况下需要在几个不同的位置使用相同的值。为了确保值只指定一次,Maven允许您在POM中使用您自己预定义的变量。
例如项目版本变量:
<version>${project.version}</version>
需要注意的是,如果父项目和子项目同时定义了一个变量。那么在子项目中使用的时候将会覆盖父项目变量。
项目模块变量
pom中任何单个值元素的字段都可以作为变量引用。例如,${project.groupId}
, ${project.version}
, ${project.build.sourceDirectory}
等等。要查看完整的属性列表,可以查看POM参考文献(https://maven.apache.org/pom.html)。
这些变量都由前缀“project.
”引用。您可能还会看到带有pom的引用作为前缀,或完全省略前缀-这些形式现在是不赞成的,不应该使用。
特殊变量
project.basedir
当前项目所在目录。
project.baseUri
当前项目所在的目录,用URI表示。从Maven 2.1.0开始
maven.build.timestamp
表示构建(UTC)开始的时间戳。从Maven 2.1.0-M1开始
可以通过声明属性maven.build.timestamp自定义构建时间戳的格式。格式如下例所示:
<project> ...
<properties>
<maven.build.timestamp.format>yyyy-MM-dd"T"HH:mm:ss"Z"</maven.build.timestamp.format>
</properties>
...
</project>
格式必须符合SimpleDateFormat API文档中给出的规则。如果属性不存在,则格式默认为示例中已经给出的值。
属性
您还可以将项目中定义的任何属性引用为变量。参考下面的例子:
<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>
以上是 ApacheMaven使用POM定义项目结构 的全部内容, 来源链接: utcz.com/z/513813.html