Maven实战——聚合与继承

聚合#

有时候,一个项目被拆分成多个功能模块,每个模块是一个子项目,这时如果你想打包所有的子项目,必须将每一个项目单独打包。

Maven提供的聚合功能可以将其一次性打包。

首先假设我们的项目中有两个模块,account-emailaccount-persist,我们想使用一种手段将它们一起打包,在maven中,可以创建一个新的maven项目,它可以只有pom.xml,然后它的xml中这样编写:

<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>top.yudoge.account</groupId>
    <artifactId>account-aggregator</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!-- 注意打包方式是pom,不是war也不是jar -->
    <packaging>pom</packaging>


    <modules>
        <module>../account-email</module>
        <module>../account-persist</module>
    </modules>

</project>

modules指定了它要聚合打包的模块的相对路径,现在你只需要在account-aggregator中运行mvn clean compile即可对这两个模块进行打包。

上面展示的是所有子项目平行放置的模式,所以module中都加了../,在实际开发中也可以将所有要聚合打包的项目放到聚合项目的文件夹中,这样就不用写../了,不过个人比较喜欢平行放置

平行放置:
account-aggregator
  pom.xml
account-email
  pom.xml
account-persist
  pom.xml


另一种放置方式:
account-aggregator
  pom.xml
  account-email
    pom.xml
  account-persist
    pom.xml

继承#

聚合提供的是将多个子项目共同打包的能力,在聚合中,所有项目没有父子关系,而在继承中,一般多个项目会继承一个共同的父项目来继承它其中的属性

考虑这样一个场景,account-email依赖很多个spring库,account-persist也依赖很多个spring库,它们当中存在很多共同依赖,在以前,我们只能在每个子项目的pom中分别写入这些,这时冗余就出现了,冗余出现就容易有错误,比如你更新了某一个模块中的依赖的版本,而另一个模块没有更新,通常我们在一个项目中期待所有子项目都共享同一个依赖版本。

这时可以创建一个account-parent,在其中写入这些所有(或部分,因为子项目也可以覆盖继承的属性)期望子项目共享的属性,然后子项目再去继承它。

下面我们创建account-parent,就简简单单的写一个让子项目继承groupIdversion的例子

<?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和version -->
    <groupId>top.yudoge.account</groupId>
    <artifactId>account-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>Account Parent</name>

</project>

让子项目account-emailaccount-persist继承它

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

    <parent>
        <artifactId>account-parent</artifactId>
        <groupId>top.yudoge.account</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../account-parent/pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>account-email</artifactId>

</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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <artifactId>account-parent</artifactId>
        <groupId>top.yudoge.account</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../account-parent/pom.xml</relativePath>
    </parent>
    <artifactId>account-persist</artifactId>
</project>

可以看到,子项目中不用编写groupIdartifactId了。relativePath指定了父项目的pom位置,Maven会先根据relativePath查找父项目的pom,如果找不到再去本地仓库查找。

虽然聚合和继承是为了达到不同的目的而出现的两种手段,但是它们也有一些共同点,比如,它们的packaging都是pom,它们都不需要有除了pom.xml外的任何部分,即它们是一个包含pom.xml的文件夹即可。

如果子模块在父模块的文件夹中,relativePath可以被省略,Maven会找到父模块的pom.xml

可继承的pom元素#

依赖管理#

上面写道,dependencies也是可以继承的,但我们通常不直接在父项目中写dependencies让子项目继承,因为并不能知道是不是每个子项目都会用到其中的每一个依赖。我们通常通过dependencyManagement在父项目中来声明所有项目中可能用到的依赖以及版本,然后子项目可以自己决定是否使用其中的某一个依赖或添加一个不在其中的依赖。

下面是account-parent的内容

下面是其中某一个继承它的子项目的内容

子项目自行要求要依赖哪些库,因为它自己最清楚它要依赖什么,唯一的好处就是这样写的情况下,我们不用在每个项目中维护版本。

import#

scope中的import的作用是,如果你想提供一个父项目,你可以通过上面的方式来导入另一个父项目中的dependencyManagement

反应堆#

在构建时,我们需要构建所有的模块,所以我们要修改一下account-aggregatorpom中的代码,将所有三个子项目都放进modules

<modules>
  <module>../account-email</module>
  <module>../account-persist</module>
  <module>../account-parent</module>
</modules>

而在我们构建时。。。我们发现构建的顺序并和我们写的不一致

Maven能自己发现所有项目中的依赖关系,它编译account-email时,发现它依赖它的父项目,所以它先去编译父项目。Maven会自动检测这些依赖关系并给出正确的编译顺序。

裁剪反应堆#

你可以选择不构建所有项目,只构建其中一部分

-pl只编译你指定的模块

mvn clean compile -pl top.yudoge.account:account-email,top.yudoge.account:account-persist

-amd编译模块以及依赖它的模块

mvn clean compile -pl top.yudoge.account:account-parent -amd

-rf指定在完整的反应堆构建顺序之上,从哪个模块开始构建

posted @   yudoge  阅读(113)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示
主题色彩