POM继承关系
超级POM的内容
- 项目中的pom.xml默认会继承超级pom的内容,也可以覆盖继承的内容及加入自己独有的内容。
默认的超级pom位于${install.direcotry}\lib\maven-model-builder-3.6.3.jar!org\apache\maven\model\pom-4.0.0.xml
超级pom中定义了远程仓库的地址,插件仓库的地址,项目源码和资源的输出目录,项目的构建信息等。
<?xml version="1.0" encoding="UTF-8"?>
<!-- START SNIPPET: superpom -->
<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>
<!-- END SNIPPET: superpom -->
有效POM的内容
- 使用
mvn help:effective-pom
命令查看实际项目的pom文件(包括默认继承的内容)。
根据超级pom的定义,我们知道maven约定的目录结构为
src/main/java: 主源码目录
src/main/resources: 主资源目录
src/test/java: 测试源码目录
src/test/resources: 测试资源目录
<?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>org.example</groupId>
<artifactId>maven-simple</artifactId>
<version>1.0-SNAPSHOT</version>
</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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>maven-simple</artifactId>
<version>1.0-SNAPSHOT</version>
<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
</pluginRepository>
</pluginRepositories>
<build>
<sourceDirectory>C:\Users\Alex\IdeaProjects\maven-simple\src\main\java</sourceDirectory>
<scriptSourceDirectory>C:\Users\Alex\IdeaProjects\maven-simple\src\main\scripts</scriptSourceDirectory>
<testSourceDirectory>C:\Users\Alex\IdeaProjects\maven-simple\src\test\java</testSourceDirectory>
<outputDirectory>C:\Users\Alex\IdeaProjects\maven-simple\target\classes</outputDirectory>
<testOutputDirectory>C:\Users\Alex\IdeaProjects\maven-simple\target\test-classes</testOutputDirectory>
<resources>
<resource>
<directory>C:\Users\Alex\IdeaProjects\maven-simple\src\main\resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>C:\Users\Alex\IdeaProjects\maven-simple\src\test\resources</directory>
</testResource>
</testResources>
<directory>C:\Users\Alex\IdeaProjects\maven-simple\target</directory>
<finalName>maven-simple-1.0-SNAPSHOT</finalName>
<pluginManagement>
<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>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>default-clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>default-testResources</id>
<phase>process-test-resources</phase>
<goals>
<goal>testResources</goal>
</goals>
</execution>
<execution>
<id>default-resources</id>
<phase>process-resources</phase>
<goals>
<goal>resources</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<executions>
<execution>
<id>default-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<executions>
<execution>
<id>default-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>default-install</id>
<phase>install</phase>
<goals>
<goal>install</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>default-deploy</id>
<phase>deploy</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.3</version>
<executions>
<execution>
<id>default-site</id>
<phase>site</phase>
<goals>
<goal>site</goal>
</goals>
<configuration>
<outputDirectory>C:\Users\Alex\IdeaProjects\maven-simple\target\site</outputDirectory>
<reportPlugins>
<reportPlugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
</reportPlugin>
</reportPlugins>
</configuration>
</execution>
<execution>
<id>default-deploy</id>
<phase>site-deploy</phase>
<goals>
<goal>deploy</goal>
</goals>
<configuration>
<outputDirectory>C:\Users\Alex\IdeaProjects\maven-simple\target\site</outputDirectory>
<reportPlugins>
<reportPlugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
</reportPlugin>
</reportPlugins>
</configuration>
</execution>
</executions>
<configuration>
<outputDirectory>C:\Users\Alex\IdeaProjects\maven-simple\target\site</outputDirectory>
<reportPlugins>
<reportPlugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
</reportPlugin>
</reportPlugins>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<outputDirectory>C:\Users\Alex\IdeaProjects\maven-simple\target\site</outputDirectory>
</reporting>
</project>
Maven生命周期和插件
生命周期及各个阶段
clean生命周期的目的是清理项目,default生命周期的目的是构建项目,而site生命周期的目的是建立项目站点。
每个生命周期包含一些阶段(phase),这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段,用户和Maven最直接的交互方式就是调用这些生命周期阶段。较之于生命周期阶段的前后依赖关系,三套生命周期本身是相互独立的,用户可以仅仅调用clean生命周期的某个阶段,或者仅仅调用default生命周期的某个阶段,而不会对其他生命周期产生任何影响。
官网介绍: https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
Clean Lifecycle
Phase | Description |
---|---|
pre-clean | execute processes needed prior to the actual project cleaning |
clean | remove all files generated by the previous build |
post-clean | execute processes needed to finalize the project cleaning |
Default Lifecycle
Phase | Description |
---|---|
validate | validate the project is correct and all necessary information is available. |
initialize | initialize build state, e.g. set properties or create directories. |
generate-sources | generate any source code for inclusion in compilation. |
process-sources | process the source code, for example to filter any values. |
generate-resources | generate resources for inclusion in the package. |
process-resources | copy and process the resources into the destination directory, ready for packaging. |
compile | compile the source code of the project. |
process-classes | post-process the generated files from compilation, for example to do bytecode enhancement on Java classes. |
generate-test-sources | generate any test source code for inclusion in compilation. |
process-test-sources | process the test source code, for example to filter any values. |
generate-test-resources | create resources for testing. |
process-test-resources | copy and process the resources into the test destination directory. |
test-compile | compile the test source code into the test destination directory |
process-test-classes | post-process the generated files from test compilation, for example to do bytecode enhancement on Java classes. |
test | run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed. |
prepare-package | perform any operations necessary to prepare a package before the actual packaging. This often results in an unpacked, processed version of the package. |
package | take the compiled code and package it in its distributable format, such as a JAR. |
pre-integration-test | perform actions required before integration tests are executed. This may involve things such as setting up the required environment. |
integration-test | process and deploy the package if necessary into an environment where integration tests can be run. |
post-integration-test | perform actions required after integration tests have been executed. This may including cleaning up the environment. |
verify | run any checks to verify the package is valid and meets quality criteria. |
install | install the package into the local repository, for use as a dependency in other projects locally. |
deploy | done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects. |
Site Lifecycle
Phase | Description |
---|---|
pre-site | execute processes needed prior to the actual project site generation |
site | generate the project’s site documentation |
post-site | execute processes needed to finalize the site generation, and to prepare for site deployment |
site-deploy | deploy the generated site documentation to the specified web server |
官网提供的插件列表
- Maven的生命周期是抽象的,这意味着生命周期本身不做任何实际的工作,在Maven的设计中,实际的任务(如编译源代码)都交由插件来完成。常用的插件官方都有提供,如下所示。
插件的官网地址: http://maven.apache.org/plugins/index.html
默认的插件绑定
Maven的生命周期与插件相互绑定,用以完成实际的构建任务。具体而言,是生命周期的阶段与插件的目标相互绑定,以完成某个具体的构建任务。Maven对生命周期的不同阶段有绑定默认的插件目录,如下所示。
默认的插件绑定规则位于${install.directory}\lib\maven-core-3.6.3.jar!META-INF\plexus\default-bindings.xml
Clean Lifecycle Bindings
Phase | plugin:goal |
---|---|
pre-clean | |
clean | clean:clean |
post-clean |
Default Lifecycle Bindings
Phase | jar | war | pom | maven-plugin |
---|---|---|---|---|
validate | ||||
initialize | ||||
generate-sources | ||||
process-sources | ||||
generate-resources | plugin:descriptor | |||
process-resources | resources:resources | resources:resources | resources:resources | |
compile | compiler:compile | compiler:compile | compiler:compile | |
process-classes | ||||
generate-test-sources | ||||
process-test-sources | ||||
generate-test-resources | ||||
process-test-resources | resources:testResources | resources:testResources | resources:testResources | |
test-compile | compiler:testCompile | compiler:testCompile | compiler:testCompile | |
process-test-classes | ||||
test | surefire:test | surefire:test | surefire:test | |
prepare-package | ||||
package | jar:jar | war:war | jar:jar and plugin:addPluginArtifactMetadata | |
pre-integration-test | ||||
integration-test | ||||
post-integration-test | ||||
verify | ||||
install | install:install | install:install | install:install | install:install |
deploy | deploy:deploy | deploy:deploy | deploy:deploy | deploy:deploy |
Site Lifecycle Bindings
Phase | plugin:goal |
---|---|
pre-site | |
site | site:site |
post-site | |
site-deploy | site:deploy |
自定义插件绑定
除了内置绑定以外,用户还能够自己选择将某个插件目录绑定到生命周期的某个阶段上,这种自定义绑定方式能让Maven项目在构建过程中执行更多更富特色的任务。一个常见的例子是创建项目的源码jar包,内置的插件绑定关系中并没有涉及这一任务,因此需要用户自行配置。maven-source-plugin可以帮助我们完成该任务,它的jar-no-fork目标能够将项目的主代码打包成jar文件,可以将其绑定到default生命周期的verify阶段上,在执行集成测试后和安装构件之前创建源码jar包。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
上述配置中,除了基本的插件坐标声明外,还有插件执行配置,executions下每个execution子元素可以用来配置执行一个任务。该例中配置了一个id为attach-sources的任务,通过phrase配置,将其绑定到verify生命周期阶段上,再通过goals配置指定要执行的插件目标。
列举插件配置
-
命令行插件配置
例如,maven-surefire-plugin提供了一个maven.test.skip参数,当其值为true的时候,就会跳过执行测试。于是,在运行命令的时候,加上如下-D参数就能跳过测试:mvn install -Dmaven.test.skip=true
-
POM中插件全局配置
用户可以声明插件的时候,对此插件进行一个全局的配置。也就是说,所有基于该插件目标的任务,都会使用这些配置。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
- POM中插件任务配置
除了为插件配置全局的参数,用户还可以为某个插件任务配置特定的参数。以maven-antrun-plugin为例,它有一个目标run,可以用来在Maven中调用Ant任务。用户将maven-antrun-plugin:run绑定到多个生命周期阶段上,再加以不同的配置,就可以让Maven在不同的生命阶段执行不同的任务。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>ant-validate</id>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo>I'm bound to validate phase.</echo>
</target>
</configuration>
</execution>
<execution>
<id>ant-verify</id>
<phase>verify</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo>I'm bound to verify phase.</echo>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
描述插件信息
- 在线查看插件信息,从官网的插件列表中找出要查看的插件,双击进去就可以看到该插件提供的所有目标。选择指定的插件目录后双击进去就可以看到该目标的所有可用配置
- 除了访问在线的插件文档之外,还可以借助maven-help-plugin来获取插件的详细信息
<!-- 输入完整的GAV坐标信息 -->
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-compiler-plugin:3.1
<!-- 如果不指定版本,自动获取最新版本 -->
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-compiler-plugin
<!-- 使用插件目录前缀替换坐标 -->
mvn help:describe -Dplugin=compiler
<!-- 如果想仅仅描述某个插件目录的信息,可以加上goal参数 -->
mvn help:describe: -Dplugin=compiler -Dgoal=compile
<!-- 如果想让maven-help-plugin输出更详细的信息,可以加上detail参数 -->
mvn help:describe -Dplugin=compiler -Ddetail
<!-- 以上第一个命令的执行结果如下所示 -->
Name: Maven Compiler Plugin
Description: The Compiler Plugin is used to compile the sources of your project.
Group Id: org.apache.maven.plugins
Artifact Id: maven-compiler-plugin
Version: 3.1
Goal Prefix: compiler
This plugin has 3 goals:
compiler:compile
Description: Compiles application sources
compiler:help
Description: Display help information on maven-compiler-plugin.
Call mvn compiler:help -Ddetail=true -Dgoal=<goal-name> to display
parameter details.
compiler:testCompile
Description: Compiles application test sources.
For more information, run 'mvn help:describe [...] -Ddetail'
命令行调用插件
- 如果在命令行运行
mvn -h
来显示mvn命令帮助,就可以看到如下的信息:
usage: mvn [options] [<goal(s)>] [<phase(s)>]
Options:
…