Maven 主模块和子模块pom.xml依赖声明

前言

今天想到了一个问题,如果一个依赖只有子模块用到了,是放入子模块的 pom.xml 呢,还是放入父模块的 pom.xml 呢?

理论上当然是子模块单独声明更符合逻辑。但是以上问题的场景来源有两个:

  1. 为了方便,或者考虑到其它子模块或许以后会用到此依赖的可能性。
  2. 单模块项目改造为多模块后,原本的依赖全部声明在父模块 pom.xml 中,考虑是否要大量迁移到用到的子模块中。

进而引申出的问题:

如果依赖全部放入父模块,部分子模块没有用到这些依赖,是否会增加这些子模块打包后的代码体积?

背景知识

dependencies与dependencyManagement的区别

  • 父项目中的 <dependencies></dependencies> 中定义的所有依赖,在子项目中都会直接继承。
  • 在父项目中的 <dependencyManagement></dependencyManagement> 中定义的所有依赖,子项目并不会继承,我们还要在子项目中引入我们需要的依赖,才能进行使用。此时我们在子项目中不用设置版本。

实验

为了回答这个问题:“如果依赖全部放入父模块,部分子模块没有用到这些依赖,是否会增加这些子模块打包后的代码体积?”。我们拿一个 maven 多模块项目打包测试一下。

实验材料:

如图,一个多模块项目。

其中 wx-common 模块只是放了一些 enums:

父模块依赖:

<properties>
  <java.version>11</java.version>
  <spring-cloud.version>Hoxton.SR8</spring-cloud.version>
  <wx-common-version>0.0.1-SNAPSHOT</wx-common-version>
</properties>

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.2.6.RELEASE</version>
  </dependency>

  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    <version>2.2.5.RELEASE</version>
  </dependency>

  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <version>2.2.6.RELEASE</version>
    <scope>test</scope>
    <exclusions>
      <exclusion>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
      </exclusion>
    </exclusions>
  </dependency>

  <!--lombok-->
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.json/json -->
  <dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20190722</version>
  </dependency>

  <dependency>
    <groupId>com.jellyfishmix.interchange</groupId>
    <artifactId>common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </dependency>

  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>2.2.2.RELEASE</version>
  </dependency>
</dependencies>

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>${spring-cloud.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>com.jellyfishmix.interchange</groupId>
      <artifactId>wx-common</artifactId>
      <version>${wx-common-version}</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

wx-common 模块无单独引入的依赖。

wx-common 模块单独打包后的大小(3982 bytes):

接下来我们把父模块的依赖都放入 <dependencyManagement></dependencyManagement> 中,这样子模块就不会全部继承这些依赖,而是需要在子模块的 pom.xml 中也进行声明,子模块才能继承对应的依赖。

按照博主的猜想, 子模块最初继承了很多父模块的依赖,当单独打包子模块时,这些依赖被打入了子模块jar包中。而这些继承过来的父模块的依赖中,有很多是子模块不需要的,因此子模块单独打出的包,会有不少冗余体积

我们把父模块的依赖都挪入 <dependencyManagement></dependencyManagement> 中,而 子模块又没有在自己的 pom.xml 中声明这些依赖,也就不会继承这些依赖,这样子模块单独打出的包,会不会减少很多体积呢 ?

按我们的推测,把父模块的依赖都放入 <dependencyManagement></dependencyManagement> 中,然后对子模块单独打包(3982 bytes):

可以看到打包出来的 jar,并没有按照我们预先设想的,体积减少了很多,而是和之前的体积一模一样(都是3982 bytes)。

看到这个结果,博主百思不得其解。难道 子模块继承的父模块的依赖,如果在子模块中没有被使用,在子模块单独打包时,就不会被打入 jar 吗?

我们再做一个实验来验证猜想,现在父模块的依赖还是在 <dependencyManagement></dependencyManagement> 中,需要在子模块的 pom.xml 中也进行声明,子模块才能继承对应的依赖。我们给子模块的 pom.xml 多声明几个依赖:

<!--lombok-->
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.12</version>
</dependency>

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  <version>2.2.5.RELEASE</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
  <version>20190722</version>
</dependency>

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-openfeign</artifactId>
  <version>2.2.2.RELEASE</version>
</dependency>

然后对子模块单独打包(4175 bytes):

可以看到我们的 jar 包体积确实增加了(4175 - 3982 = 193 bytes),但这些增加的代码体积,应该是我们的 pom.xml 中新增的一对对 <dependency></dependency> 的体积,而不是真正引入的依赖的代码。

因此,博主确信了推测: 子模块继承的父模块的依赖/子模块声明的依赖,如果在子模块中没有被使用,在子模块单独打包时,就不会被打入 jar 。

进一步实验来确认推测,我们在子模块中使用一下声明的依赖。只在子模块中加两个注解: @FeignClient(name = "interchange-wx") ,对子模块单独打包(4259 bytes):

打包结果(4259 - 4175 = 84 bytes)。

因此,maven 打包加入的依赖代码应该是被调用到的部分代码,没有被调用到的依赖代码不会被加入打包后的 jar 包中。

实验结论

  • 子模块继承的父模块的依赖/子模块声明的依赖,如果在子模块中没有被使用,在子模块单独打包时,就不会被打入 jar 。
  • maven 打包加入的依赖代码是被调用到的部分代码,没有被调用到的依赖代码不会被加入打包后的 jar 包中。

推荐做法

对于 “依赖放入子模块还是父模块” 这个问题,推荐将依赖放入父模块的 <dependencyManagement></dependencyManagement> 中,然后子模块有需要的依赖,在子模块的 pom.xml 中声明。这样便于在父模块中统一管理依赖版本,避免子模块依赖版本不一致造成的混乱或冲突。

到此这篇关于Maven 主模块和子模块pom.xml依赖声明的文章就介绍到这了,更多相关Maven pom.xml依赖声明内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • maven中pom.xml详细介绍

    POM 代表工程对象模型.它是使用 Maven 工作时的基本组建,是一个 xml 文件.它被放在工程根目录下,文件命名为 pom.xml. POM 包含了关于工程和各种配置细节的信息,Maven 使用这些信息构建工程. POM 也包含了目标和插件.当执行一个任务或者目标时,Maven 会查找当前目录下的 POM,从其中读取所需要的配置信息,然后执行目标.能够在 POM 中设置的一些配置如下: project dependencies plugins goals build profiles pr

  • Maven pom.xml与settings.xml详解

    pom.xml与settings.xml pom.xml与setting.xml,可以说是Maven中最重要的两个配置文件,决定了Maven的核心功能,虽然之前的文章零零碎碎有提到过pom.xml和settings.xml里面的内容,但都是大略带过,学习与研究地并不细致,本文的目的就是详细研究下这两个Maven重要的配置文件,从这两个配置文件可以牵出非常多的Maven话题.  Maven坐标 首先谈一下为什么要使用Maven坐标. Maven世界拥有数量非常巨大的构件,也就是平时使用的一些jar

  • 解决idea2020.2遇到pom.xml文件报错maven插件tomcat7的问题

    之前百度找答案,指明的是依赖中servlet-api中添加provided 发现自己的依赖中已添加,未找到解决办法. 显示红色报错,阿里云仓库无法下载该文件.报错如下: 找到文件位置,删除maven本地仓库文件 解决办法:指定版本信息2.2 到此这篇关于idea2020.2遇到pom.xml文件报错maven插件tomcat7的问题的文章就介绍到这了,更多相关idea2020.2报错maven插件tomcat7内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

  • 基于Maven的pom.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/maven-v4_0_0.xsd "> <!-- 父项

  • 配置pom.xml用maven打包java工程的方法(推荐)

    最近由于项目需要,研究了一下maven的打包,项目要做到 1,生成3个目录/lib,/conf,/bin目录 2,把所有的jar目录编译.拷贝到/lib目录(包括maven的jar包和lib目录下的jar,以及编译的jar包) 3,把所有的启动脚本从工程根目录拷贝到/bin目录 4,把所有的配置文件从src/main/resources拷贝到/conf 下面是配置的pom.xml,我把相关的配置都加了注释,一看就能明白,把build节点拷贝到你们的项目中,就基本可以用了:) <project x

  • Maven中pom.xml配置文件详细介绍

    setting.xml主要用于配置maven的运行环境等一系列通用的属性,是全局级别的配置文件:而pom.xml主要描述了项目的maven坐标,依赖关系,开发者需要遵循的规则,缺陷管理系统,组织和licenses,以及其他所有的项目相关因素,是项目级别的配置文件. 基础配置 一个典型的pom.xml文件配置如下: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org

  • java 中maven pom.xml文件教程详解

    maven pom.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/maven-v4_0_0.x

  • 详解 maven的pom.xml用<exclusion>解决版本问题

    详解 maven的pom.xml用<exclusion>解决版本问题 用maven管理库依赖,有个好处就是连同库的依赖的全部jar文件一起下载,免去手工添加的麻烦,但同时也带来了同一个jar会被下载了不同版本的问题,好在pom的配置里面允许用<exclusion>来排除一些不需要同时下载的依赖jar . 比如配置struts-core,它会同时下载javassist和asm相关的jar,但版本又不够新,这时可以排除它们: <!-- Struts2 --> <dep

  • Maven配置文件pom.xml详解

    什么是POM? POM是项目对象模型(Project Object Model)的简称,它是Maven项目中的文件,使用XML表示,名称叫做pom.xml.在Maven中,当谈到Project的时候,不仅仅是一堆包含代码的文件.一个Project往往包含一个配置文件,包括了与开发者有关的,缺陷跟踪系统,组织与许可,项目的URL,项目依赖,以及其他.它包含了所有与这个项目相关的东西.事实上,在Maven世界中,project可以什么都没有,甚至没有代码,但是必须包含pom.xml文件. 概览 下面

  • Maven 主模块和子模块pom.xml依赖声明

    前言 今天想到了一个问题,如果一个依赖只有子模块用到了,是放入子模块的 pom.xml 呢,还是放入父模块的 pom.xml 呢? 理论上当然是子模块单独声明更符合逻辑.但是以上问题的场景来源有两个: 为了方便,或者考虑到其它子模块或许以后会用到此依赖的可能性. 单模块项目改造为多模块后,原本的依赖全部声明在父模块 pom.xml 中,考虑是否要大量迁移到用到的子模块中. 进而引申出的问题: 如果依赖全部放入父模块,部分子模块没有用到这些依赖,是否会增加这些子模块打包后的代码体积? 背景知识 d

  • Maven 命令行打包 和 pom.xml的常用配置详解

    maven 命令行打包 mvn -v, --show-version 现在最新的maven版本是 3.6,我这里用的还是 2017 年下载的 3.1.1 版本(虽然有点过时,但是大版本不变,指令基本一样) mvn -h, --help 使用 help 命令可以看到 maven 命令的帮助文档,下面主要介绍两个常用的指令 -- D 和 P. mvn -D, --define <arg> mvn -DpropertyName=propertyValue clean package 可以用来临时定义

  • 使用maven开发springboot项目时pom.xml常用配置(推荐)

    如题,记录一些平常开发用的pom文件细节 1.使用parent父类引用,解决依赖版本号不确定时自动匹配的问题 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.7.RELEASE</version> <relativePath/>

  • SpringBoot+Maven 多模块项目的构建、运行、打包实战

    本篇文章主要介绍了SpringBoot+Maven 多模块项目的构建.运行.打包,分享给大家,具体如下: 项目使用的工具: IntelliJ IDEA JDK 1.8 apache-maven-3.3.9 项目的目录: 主项目 springboot-multi 子模块 entity.dao.service.web 一.使用IDEA创建一个SpringBoot项目 : File -> new -> Project 项目名称为springboot-multi 二.删除项目中的src目录,把pom.

  • 解决IDEA创建maven项目时pom.xml没有变蓝的问题

    如下所示: 选中pom.xml,右键点击add as maven project, 稍等片刻后就可以了 补充知识:Idea导入maven项目不自动识别pom.xml *Idea导入maven项目不自动识别pom.xml *当在idea中导入maven项目时,不能自动识别pom文件 解决方法: 1.右键pom.xml文件,选择" add as maven project",即可自动导入pom所依赖的jar包 另外刷新Maven配置的方法为: (1)右键单击项目: (2)在弹出菜单中选择M

  • Maven多模块及version修改的实现方法

    对于使用maven构建的java项目,通常聚合多个子模块项目.在版本迭代的过程中经常变更版本号,更新parent版本号,发现子模块版本号没有更新,需要一个个的手动去更新,太麻烦,且容易出错. 在版本更新之后,内部模块之间的依赖也需要变更,往往存在遗漏. MAVEN多个子模块项目 以上是一个基本的 主项目parent包 maven-multily-module/pom.xml 指定整个应用的dependencyManagement 定义项目的发布的仓库地址distributionManagemen

  • 详解Maven多模块打包遇到的问题解决方法

    项目描述: springboot+springcloud+zookeeper+eureka+maven:为多模块多module的分布式架构: 项目目录结构如下 父工程为server工程,其中有多个子module工程: 1.独立子工程:db.model.quartz.redis.util.basecontroller: 2.独立功能模块:dao.service.controller: 其中dao.service.controller分别依赖db.model.quartz.redis.util.ba

  • 构建Maven多模块项目的方法

    目录 构建Maven多模块项目 创建父模块 创建子模块:model层 创建子模块:dao模块 创建子模块:service层 创建子模块:web层 编译运行项目 Maven相关特性 父模块的配置 父模块聚合子模块 父模块统一管理依赖包 子模块在pom.xml中声明父模块 参考文章 构建Maven多模块项目 JavaWeb开发一般都会进行分层开发,通常分为 model,模型层 dao,数据访问层 service,业务逻辑层 web,表现层 分层后,各层职责明确,后期维护起来也会容易一些.接下来我们就

  • springboot实现maven多模块和打包部署

    目录 创建多模块项目 依赖关系 开发工具 :idea 工程结构: 父工程father 子模块 dao (用于持久化数据跟数据库交互) 子模块 entity (实体类) 子模块 service (处理业务逻辑) 子模块 web (页面交互接收.传递数据,唯一有启动类的模块) 关系: web依赖 service.dao.entity service依赖 dao.entity dao依赖 entity entity谁都不依赖,独立的 创建多模块项目 new ------file-------proje

  • Maven pom.xml 添加本地jar包依赖以及打包方法

    Maven项目打包时,如果遇到需要添加本地jar包依赖的时候,可以选择两种方法: 1. 安装到本地仓库 第一种方法比较常规,适用于需要添加的jar包也是由maven项目导出,含有pom文件的时候.只需要将jar包安装到本地maven仓库下,然后添加依赖即可. (1)安装到本地仓库,执行以下命令(其中的-Dfile/-DgroupId/-DartifactId/-Dversion项根据pom文件内容填写): mvn install:install-file -Dfile=xxxxx.jar -Dg

随机推荐