首页 > 其他分享 >maven项目聚合和父子项目

maven项目聚合和父子项目

时间:2023-11-10 09:13:30浏览次数:37  
标签:依赖 聚合 模块 项目 boot maven pom 子项目

maven项目聚合

聚合项目又称为多模块项目,这种结构的目的是为了统一构建项目,也就是说当对根项目的任何mvn 命令操作,都会相应的执行到每一个被聚合的module项目中,目的是为了方便管理多个项目的编译打包等操作。

想象一下,如果你创建了10个项目,如果你要对这10个项目进行 mvn install操作(将项目发布到本地仓库),难道要单独的进行10遍操作么?这样做显然是枯燥且乏味的。

项目构建工具如maven提供的聚合特性就是应对该场景的,只需要对根项目操作一次命令后,每个被聚合的模块项目均会自动执行一遍该命令,十分方便。

项目聚合样例:

根项目pom文件

<?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>com.example</groupId>
    <artifactId>mvn-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>module1</module>
        <module>module2</module>
    </modules>

    <properties>
        <java.version>17</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

根项目的pom文件里有必须添加两个标签:

<packaging>pom</packaging>是一种打包类型的配置。它表示项目不会生成可执行的JAR或WAR文件,而是作为一个父项目或聚合项目存在,用于管理子模块的构建和依赖关系

<modules>
        <module>module1</module>
        <module>module2</module>
 </modules>

Maven项目中的<modules>元素,它指定了当前项目的子模块列表。在这个例子中,项目有两个子模块,分别是module1和module2。这意味着这个项目是一个聚合项目,它管理着多个子模块的构建和依赖关系。当你运行Maven命令时,Maven会自动构建所有的子模块。

子模块并不知道根项目的存在,新建子模块也非常简单

这样只需在根项目的pom文件路径下执行mvn命令,那么mvn命令会自动在子模块中都执行一遍,比如打包package,只需在根项目中执行mvn clean package,两个模块module-demo1和module-demo2均会执行一遍命令mvn clean package。

父子项目

父子模块这种项目结构,本质上就是继承关系。上边聚合模块结构没有上下级区分,但这里的父子模块就要区分上下级了(这里的上下级不是指文件目录的上下级),子模块会继承父模块的相关依赖配置。

继承在java里的好处就是子类可以使用父类的属性和方法,减少代码冗余。
maven这里同样也是这个好处:

  1. 父模块的groupId和version会传递到子模块,父子模块作为一个整体,子模块不需要再声明,仅需要指定自己独有的artifactId即可,当然如果你依赖的父模块和你的项目不是同一个groupId时,你也可以指定子模块的groupId和version;
  2. 父模块的依赖配置会传递到子模块,子模块不需要再单独引入依赖;
  3. 父模块可以管理依赖的版本,子模块可以自由灵活的选择需要的依赖,不需要再关心版本的问题。

在聚合项目那里说过,被聚合的模块根本无法感知到根模块的存在。父子模块正好相反,父模块根本无法感知到哪个子模块把它当作爸爸。

搭建父子模块

这里搭建一个单纯的父子模块,也就是不在父模块中配置module标签,仅在子模块中指定它的父模块是谁。

1.创建父模块
父子模块中,父模块一般作为子模块依赖的管理,它只需要定义好依赖的版本和必须的依赖即可。

父模块的打包方式必须为pom。

父模块的pom文件

<?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>com.example</groupId>
    <artifactId>mvn-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <packaging>pom</packaging>

    <properties>
        <java.version>17</java.version>
        <commons.lang3.version>3.12.0</commons.lang3.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>${commons.lang3.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>2.7.15</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>2.7.15</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

可以看到父模块的pom文件有三个特殊标签

<packaging>pom</packaging>

 package标签作用和上面讲述的相同

<dependencyManagement>

<dependencyManagement>标签在Maven项目中的作用是管理依赖项的版本。它允许您在父项目中集中定义依赖项的版本,然后在子项目中继承这些版本定义而无需重复声明。

通过在父项目的pom.xml文件中使用<dependencyManagement>标签,您可以列出所有依赖项及其所需的版本。然后,在子项目的pom.xml文件中,您可以引用这些依赖项而无需指定版本号。这样,当您更新父项目中的依赖项版本时,所有子项目都会自动继承这些变化。

这种集中管理依赖项版本的方式有助于确保项目中使用的依赖项保持一致,并简化了项目配置。此外,它还可以避免不同子项目中使用不同版本的依赖项导致的冲突和问题。

<dependencyManagement>标签的作用是集中管理Maven项目中的依赖项版本,以确保项目的一致性和简化配置。

<dependencies>

 在Maven父子项目中,父项目的<dependencies>标签用于管理整个项目组的依赖项。它允许在父项目中声明和管理所有子模块共享的依赖关系。也就是说在父项目的pom文件中配置的<dependencys>依赖项,会被所有子项目全部继承。

2、创建两个子项目child-demo1和child-demo2

两个子项目pom文件如下:

<?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>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>mvn-demo1</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <artifactId>child-demo2</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</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>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>mvn-demo1</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <artifactId>child-demo1</artifactId>

    <name>child-demo1</name>
    <description>child-demo1</description>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
    </dependencies>
</project>

可以看到这两个子项目的pom文件的<parent>标签均填写的父项目的gav,在子项目pom文件中,不需要再填写<group>和<version>标签,因为子项目会自动继承父项目的这两个标签的值。

当前如果子项目想适用和父项目不同的g和v,则添加该两个标签和想要的值即可。

child-demo1子项目和child-demo2项目会自动继承父项目中<dependencis>标签中的所有依赖,所以在这两个子项目的pom文件中,即使没有显式的配置junit和spring-boot-starter-test这两个依赖项,

但是子项目也会直接从父项目中将这两个依赖项配置项继承过来。

可以看到child-demo1子项目的spring-boot-start-web和commons-lang3两个依赖项并没有配置<version>标签,因为在父项目中的<dependencyManagement>标签中已经声明了这两个依赖项的版本,子项目会直接将<dependencyManagement>标签中配置的版本信息,范围等继承过来,但在父项目中<dependencyManagement>标签配置的依赖紧紧起到版本管理的作用,子项目中如果不配置该依赖项,则不会继承父项目中<dependencyManagement>标签配置的数据。<dependencyManagement>标签仅起到版本管理的作用。

配置完成后,可以分别在child-demo1子项目和child-demo2子项目的pom文件所在路径直接mvn命令直接打包即可。

可以看到父子项目是起到减少子项目中pom文件的重复配置和版本管理方便的目的。

聚合项目和父子项目同时使用

可以看到上面的父子项目,在打包时,需要分别对两个子项目进行打包,这时,如果想一次打包两个或者多个子项目,就要用到上面讲的maven聚合功能就能用到了。

只需在父项目的pom文件中添加<modules>标签,然后将需要聚合的子项目填进来即可

<modules>
    <module>child-demo1</module>
    <module>child-demo2</module>
</modules>

 完整的父项目pom文件如下:

<?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>com.example</groupId>
    <artifactId>mvn-demo1</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <packaging>pom</packaging>

    <name>mvn-demo1</name>
    <description>mvn-demo1</description>

    <modules>
        <module>child-demo1</module>
        <module>child-demo2</module>
    </modules>

    <properties>
        <java.version>17</java.version>
        <commons.lang3.version>3.12.0</commons.lang3.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>${commons.lang3.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>2.7.15</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>2.7.15</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

子项目不需要修改,即可实现在父项目的pom文件路径下执行maven命令,打包两个或多个子项目的给功能。

可以看出maven聚合功能是为了方便管理和打包多个项目,而maven的父子项目则是利用了和java继承思想类似的思想,让子项目继承父项目的maven配置,如版本,依赖项,版本控制等,这样子项目就可以复用父项目中的配置,起到减少配置冗余的目的。

可以看到直接在父项目的pom文件所在路径执行mvn clean package命令,两个子项目就都打包成功了。

总结

在我们实际开发中,一般都是将聚合和父子这两种关系混合使用,这里我拆分说,只是为了分别去理解它们各自的作用。

不论父子模块还是聚合模块,根模块的打包方式都必须是pom,下面的模块可以是jar或者war这两种打包方式。

聚合模块这种项目结构,仅仅是为了方便统一管理操作所有的模块。根模块和它内部<module> 标签内的模块是一个整体,项目目录层级上可以不要求一定上下级,但必须保持一定的层级联系。

父子模块这种项目结构,仅仅是为了方便子模块对依赖的管理,子模块通过<parent> 标签,引入父模块的配置去约束子模块的依赖版本。也可以抽出共同的依赖给到父模块,子模块去继承它,减少每个子模块冗余的配置。项目层级没有要求,你可以引入任意的依赖当作父模块,比如spring-boot-starter。

当然混合使用才能发挥它们最大的优势!

参考文章

 

 

 

标签:依赖,聚合,模块,项目,boot,maven,pom,子项目
From: https://www.cnblogs.com/longan-wang/p/17822468.html

相关文章

  • 解决Maven中90%的依赖(导包)问题
    今天给大家分享一个非常好用的技巧,这个技巧是一个组合技巧是的,自从我开始接触了以spring为框架的项目学习后,这个maven导包老是出现问题,每次在这个上面花费好多时间,于是乎打算写一个秘籍出来。你可能会遇到这样的问题这玩意咋红了,看人怪吓人的接下来这个我们来看看有什么解决......
  • 推荐我最喜爱的聚合类应用——太极神器
    今天给大家分享一款好用好玩的软件。如果你的日常工作娱乐,常常用到不同类型的软件,每个都要安装一边又占内存,那么强烈推荐你使用聚合类工具箱,软件体积不大,但功能多样,日用非常方便。最近,该软件进行了全新升级,功能更强更稳定,轻度用户使用基本功能就已经足够了,壕无人性的同学则可以考虑......
  • iOS项目(Swift),使用Flutter进行混合开发
    一、创建flutter_module先创建fluttermodule项目,参考官方文档,先cd至目标文件夹,执行命令为fluttercreate--templatemoduleflutter_module创建成功后,打开flutter_module项目,打开pubspec.yaml文件,添加所需的依赖 执行命令,更新依赖。执行 flutterrun 命令,生成po......
  • Vite4+Typescript+Vue3+Pinia 从零搭建(1) - 项目初始化
    项目初始化项目代码同步至码云weiz-vue3-template前提准备1.node版本Node.js版本>=12,如果有老项目需要旧版本的,推荐用nvm管理node版本。PSC:\Users\Administrator>nvm--version1.1.11PSC:\Users\Administrator>nvmlist*16.20.2(Currentlyusing64-bit......
  • 强无敌!一个项目涵盖SpringBoot集成各种场景
    大家好,我是Java陈序员。我们都知道,作为Java后端开发肯定绕不开Spring,而SpringBoot的横空出世更是帮助我们开发者可以快速迭代一个项目!SpringBoot之所以强大,是因为支持自动化配置,可以快速装配组件,如持久化框架缓存消息队列日志等等。今天给大家介绍一个SpringBoot集成各种......
  • 智慧工地平台源码:支持PC端、手机端,支持项目级、公司级、集团级多级权限划分,
    智慧工地管理平台实现对人员管理、施工进度、安全管理、材料管理、设备管理、环境监测等方面的实时监控和管理,提高施工效率和质量,降低安全风险和环境污染。智慧工地平台支持项目级、公司级、集团级多级权限划分,可根据企业的组织架构进行项目权限、功能权限、数据权限设定。支持PC端......
  • 第一次将Springboot项目上传到GitLab仓库(初始化)
    步骤:1、在GitLab上创建项目仓库(创建空项目)   创建完成如下: 2、在IDEA中新建一个Springboot项目 使用Git版本集成这里说明一下:1、本机计算机已经安装Git2、IDEA已经集成了Git3、这里使用的IDEA是2021版本(2018版本是VCS),IDEA中文......
  • Go Web开发进阶项目实战-Go语言实战课程体系,企业项目开发经验与技巧
    书接上回,上次我们搭建好了项目入口文件,同时配置了路由体系,接着就可以配置项目的模板了,这里我们采用Iris内置的模板引擎,事实上,采用模板引擎并不意味着前后端耦合,模板中的数据保持其独立性即可,也就是说模板的数据操作交互方式采用http接口请求的形式,Iris并不参与模板逻辑,只返回Jso......
  • 本地jar包安装到maven仓库
    mvninstall:install-file-DgroupId=zac.fc-DartifactId=aeswithjec-20171214-Dversion=2.0.0-Dpackaging=jar-Dfile=E:\shiqr\lib\aeswithjec-20171214.jar-DgroupId=自定义groupId -DartifactId=自定义artifactId-Dversion=自定义版本1.0.0 -Dpackaging=jar 设置该包的......
  • 软件测试技术,软件项目管理 实验时间安排 2009春季
     2009年春季十一周课表时间星期一星期二星期三星期四星期五时间上1   计082  8:00-8:502    9:00-9:503     10:10-11:004     11:10-12:00下5      6      7 项目软061-062计082 计06314:10-15:008  15:10-16:009 答疑曲江 16:10-17:0010......