前言
在一个多模块的Maven项目中,反应堆(Reactor)是指所有模块组成的一个构建结构。对于单模块的项目,反应堆就是该模块本身;但是对于多模块项目来说,反应堆就包含了各模块之间继承和依赖的关系,从而能够自动计算出合理的模块构建顺序。
反应堆的构建顺序
假设现在有四个模块,account-aggregator、account-parent、account-email、account-persist。
account-aggregator作为聚合模块聚合了account-email模块,account-persist模块和account-parent模块,其中account-parent为父模块,account-email模块和account-persist模块继承于它。
当前account-aggregator模块的聚合配置如下
<modules>
<module>account-email</module>
<module>account-persist</module>
<module>account-parent</module>
</modules>
然后构建account-aggregator,看到如下输出:
如上图,告诉我们反应堆的构建顺序是account-aggregator、account-parent、account-email、account-persist,顺序和我们在上面配置的<modules>顺序不同(account-aggregator第一个可以理解,因为构建的是自己,自己先执行),这是为什么呢?
因为Maven构建的时候,按序读取pom,如果该pom没有依赖模块,那就构建该模块,否则就先构建自己依赖的模块,如果该模块还依赖于其他模块,就继续先构建依赖的依赖。上面的例子中,先构建自己,也就是account-aggregator,account-aggregator没有依赖模块,就先构建它,然后按照<modules>顺序读取构建,下一个是account-email,它依赖于account-parent,所以就先构建account-parent,然后在构建account-persist,account-persist也依赖account-parent,但是account-parent刚才已经构建了,所以此时直接构建account-persist即可。
模块之间的依赖关系会将反应堆构成一个有向非循环图(DAG),不允许各个模块节点依赖出现循环,也就是A依赖于B,B依赖于A时,构建就会报错!!!
裁剪反应堆
一般来说,用户会选择构建整个项目或者选择构建单个模块,但有些时候,用户会想要仅仅构建完整反应堆中的某些个模块。换句话说,用户需要实时的裁剪反应堆。
Maven提供了很多的命令行选项支持裁剪反应堆:
- -am:同时构建所列模块的依赖模块
- -amd:同时构建依赖于所列模块的模块
- -pl:构建指定的模块,模块间用逗号分隔
- -rf:从指定的模块回复反应堆(就是在完整的反应堆构建顺序基础上指定从哪个模块开始构建)
还是以一开始的项目结构示例。在account-aggregator中进行构建,mvn clean install,得到如下反应堆:
可以使用 -pl 指定构建某几个模块,运行命令:
mvn clean install -pl account-email,account-persist
得到反应堆如下:
使用 -am 选项可以同时构建所列模块的依赖模块,运行命令:
mvn clean install -pl account-email -am
由于account-email依赖了account-parent,因此得到如下反应堆:
使用 -amd 选项可以同时构建依赖于所列模块的模块,运行命令:
mvn clean install -pl account-parent -amd
由于account-email和account-persist依赖于account-parent,因此得到如下反应堆:
使用 -rf 选项可以在完整的反应堆构建顺序基础上指定从哪个模块开始构建,执行命令:
mvn clean install -rf account-email
完整的构建反应堆中,account-email在第三个顺序,它之后有account-persist,因此得到如下反应堆:
最后,在 -pl -am 或者 -pl -amd 的基础上,还能应用 -rf 参数,以对裁剪后的反应堆再次裁剪,例如执行命令:
mvn clean install -pl account-parent -amd -rf account-email
该命令中, -pl 和 -amd 参数会构建出一个 account-parent、account-email和account-persist的反应堆,在此基础上, -rf 参数指定从account-email开始裁剪反应堆,因此最后得到的反应堆如下: