跳至主要內容

Maven的生命周期

ChenSino原创maven大约 5 分钟

Maven的生命周期

There are three built-in build lifecycles: default, clean and site. The default lifecycle handles your project deployment, the clean lifecycle handles project cleaning, while the site lifecycle handles the creation of your project's web site.

各个生命周期包含的phase

官方说明open in new window

default lifecycle包含的phase

<phases>
  <phase>validate</phase>
  <phase>initialize</phase>
  <phase>generate-sources</phase>
  <phase>process-sources</phase>
  <phase>generate-resources</phase>
  <phase>process-resources</phase>
  <phase>compile</phase>
  <phase>process-classes</phase>
  <phase>generate-test-sources</phase>
  <phase>process-test-sources</phase>
  <phase>generate-test-resources</phase>
  <phase>process-test-resources</phase>
  <phase>test-compile</phase>
  <phase>process-test-classes</phase>
  <phase>test</phase>
  <phase>prepare-package</phase>
  <phase>package</phase>
  <phase>pre-integration-test</phase>
  <phase>integration-test</phase>
  <phase>post-integration-test</phase>
  <phase>verify</phase>
  <phase>install</phase>
  <phase>deploy</phase>
</phases>

clean lifecycle生命周期所包含的phase

<phases>
  <phase>pre-clean</phase>
  <phase>clean</phase>
  <phase>post-clean</phase>
</phases>
<default-phases>
  <clean>
    org.apache.maven.plugins:maven-clean-plugin:3.2.0:clean
  </clean>
</default-phases>

site lificycle生命周期包含的phase

<phases>
  <phase>pre-site</phase>
  <phase>site</phase>
  <phase>post-site</phase>
  <phase>site-deploy</phase>
</phases>
<default-phases>
  <site>
    org.apache.maven.plugins:maven-site-plugin:3.12.1:site
  </site>
  <site-deploy>
    org.apache.maven.plugins:maven-site-plugin:3.12.1:deploy
  </site-deploy>
</default-phases>

关于默认绑定的插件

以前一直好奇,为啥随便搞一个maven项目都有自带的插件,并且有时候插件还不一样,今天终于搞懂了,其实默认的插件和packaging的类型有关,另外clean和site插件是任何项目都默认就有的。

比如下图有两个maven项目,插件不一样,并且我在pom中没有配置任何maven插件

20230607163732

原因是maven会根据pom中packaging的类型给项目设置默认绑定的插件,点击查看官方文档open in new window

packaging类型以后pom,jar,war,ejb,maven-plugin,rar,ear等等,这里只列出最常用的pom和jar,完整版请看官网文档

packaging类型pom 类型默认绑定插件

<phases>
  <install>
    org.apache.maven.plugins:maven-install-plugin:3.1.0:install
  </install>
  <deploy>
    org.apache.maven.plugins:maven-deploy-plugin:3.1.0:deploy
  </deploy>
</phases>

packaging类型为jar,绑定的插件

<phases>
  <process-resources>
    org.apache.maven.plugins:maven-resources-plugin:3.3.0:resources
  </process-resources>
  <compile>
    org.apache.maven.plugins:maven-compiler-plugin:3.10.1:compile
  </compile>
  <process-test-resources>
    org.apache.maven.plugins:maven-resources-plugin:3.3.0:testResources
  </process-test-resources>
  <test-compile>
    org.apache.maven.plugins:maven-compiler-plugin:3.10.1:testCompile
  </test-compile>
  <test>
    org.apache.maven.plugins:maven-surefire-plugin:3.0.0:test
  </test>
  <package>
    org.apache.maven.plugins:maven-jar-plugin:3.3.0:jar
  </package>
  <install>
    org.apache.maven.plugins:maven-install-plugin:3.1.0:install
  </install>
  <deploy>
    org.apache.maven.plugins:maven-deploy-plugin:3.1.0:deploy
  </deploy>
</phases>

我对maven生命周期的理解

maven有三条生命周期线,clean/build/site,每次执行命令只会执行一条生命线,比如执行mvn clean,就只会执行clean生命周期线上绑定的 一些插件(具体来说是插件上的goal),并不会执行到build和site生命周期(mvn clean install这种写法暂且不考虑)。

就以mvn clean为例来讲解maven执行的原理。此命令执行,会自动识别为clean那条生命周期的clean阶段(phase),然后我们知道clean生命周期实际上包含三个phase,分别为pre-clean,clean,post-clean,然后程序会按照这个顺序依次去扫描每个phase绑定的插件然后 再去执行设定好的goal。第一步运行到pre-clean阶段,会去pom.xml扫描有没有插件绑定到此phase,如果有则执行其设置好的goal,比如有如下配置(插件是我瞎配置的,肯定有问题,此处就仅仅举例说明maven执行流程),当执行到pre-clean的阶段,发现有一个插件echo-plugin绑定在这个phase,就会执行这个插件对应的goal,就是那个echo,然后继续clean的第二个阶段发现绑定的有个log-plugin插件,然后就会执行绑定的goal就是那个log,然后继续执行到第三个阶段post-clean发现没有插件绑定,就啥都不做,程序结束了。

 <plugin>
                <groupId>com.chensino</groupId>
                <artifactId>echo-plugin</artifactId>
                <version>x.x.x</version>
                <configuration>
                </configuration>
                <executions>
                    <execution>
                        <phase>pre-clean</phase>
                        <goals>
                            <goal>echo</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>


             <plugin>
                <groupId>com.chensino</groupId>
                <artifactId>log-plugin</artifactId>
                <version>x.x.x</version>
                <configuration>
                </configuration>
                <executions>
                    <execution>
                        <phase>clean</phase>
                        <goals>
                            <goal>log</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

上面虽然是用clean生命周期进行举例,但是最重要的是build生命周期,原理都一样,无非build周期的phase多了一些而已。

写在最后

以前一直对maven的生命周期理解的很模糊,对clean/build/site三条生命周期稀里糊涂的,可能是被mvn clean install类似这种连写的方式误导了,最近有心得理解。

其实字面意思很明显了,“生命周期”,什么是“生命周期”,其实就是一条完整的流程,或者叫流水线,每条流水线上已经按照顺序定义好了phase。那clean/build/site其实就是三条独立的流水线。

每次执行一条生命周期时,其实就是按照某一个生命周期上已经绑定好的phase进行顺序扫描,扫描到有插件绑定在这个phase上时,就去执行配置好的goal,仅此而已。

另外补充一下,在idea插件中,有个lifecycle,显示的其实是phase,在使用spring-boot-maven-plugin插件时,发现并没有配置phase,其实插件默认绑定在了package极端

spring-boot-maven-plugin是不是默认绑定在package阶段?

是的,Spring Boot Maven插件默认绑定在Maven的package阶段,它会在执行该阶段时自动运行。在默认的情况下,spring-boot-maven-plugin会使用repackage目标来创建可执行的jar或war文件。

以下是Spring Boot官方文档对repackage目标的说明:

repackage 目标是 spring-boot-maven-plugin 的一个目标,它用于重新打包当前的JAR或WAR文件。在处理普通的JAR或WAR文件时,这通常会将依赖项复制到 BOOT-INF/lib 目录中,并将所有类文件复制到 BOOT-INF/classes 目录中。同时,此目标还重命名了原始的JAR或WAR文件,以 *-original.jar 或 *-original.war 命名,并创建一个新的可执行的JAR或WAR文件,以便在命令行上运行应用程序。

因此,在大多数情况下,您不需要在 pom.xml 文件中为 spring-boot-maven-plugin 插件指定任何额外的配置,它将在默认的package阶段正常工作。只有在您需要更改默认行为时,才需要根据需要更改 spring-boot-maven-plugin 插件的配置或执行计划。

最后再画一个图,图示用的default生命周期进行说明。

20230608144107