云计算百科
云计算领域专业知识百科平台

<packaging>pom</packaging>:集团总部不生产产品,只发号施令

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}

<packaging>pom</packaging>:集团总部不生产产品,只发号施令

一句话记忆:jar 是成品,war 是外卖盒,pom 是文件夹——它自己不是产品,但能组织一堆产品。


一、先看比喻:总部 vs 工厂

想象一个集团公司:

  • 集团总部:不生产具体产品,只负责定制度、管预算、协调各个子公司。总部本身不是一个“可售卖的商品”。
  • 子公司 A:生产饼干,产出的是一盒盒饼干(jar)。
  • 子公司 B:做外卖套餐,产出的是打包好的餐盒(war)。

Maven 里的 <packaging>pom</packaging>,就是那个集团总部。

它自己不产出 jar,也不产出 war。它的价值在于:

  • 定规矩:统一管理依赖版本、插件配置(父工程)。
  • 管组织:把多个子模块聚在一起,一次构建(聚合工程)。
  • 而默认的 <packaging>jar</packaging> 是“工厂”,产出一个能放进 classpath 的 jar 包;<packaging>war</packaging> 是“外卖打包站”,产出一个能丢进 Tomcat 的 war 包。

    记忆钩子:pom 是文件夹,jar 是文件,war 是外卖盒。


    二、Maven 的 packaging 有哪几种?

    packaging产出物典型用途比喻
    jar(默认) .jar 普通 Java 库、Spring Boot 可执行 jar 一盒成品饼干
    war .war 传统 Web 应用,部署到 Tomcat 一份打包外卖
    pom 不产生构件,只安装 pom 文件 父工程、聚合工程 集团总部 / 文件夹
    maven-plugin 插件 jar 自定义 Maven 插件 工具箱
    ear / rar 企业包 / 资源包 较少用 大礼包

    重点记住:pom 打包的模块,mvn package 不会生成 jar 或 war。 它只会在 install 时把 pom.xml 本身安装到本地仓库,供子模块继承或引用。


    三、它到底有什么意义?两大用途

    用途 1:父工程——统一“家规”

    子模块通过 <parent> 继承父工程,父工程用 packaging=pom 统一管理:

    <!– 父工程 pom.xml –>
    <groupId>com.example</groupId>
    <artifactId>my-project-parent</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>

    <properties>
    <java.version>17</java.version>
    <spring.version>6.1.0</spring.version>
    </properties>

    <dependencyManagement>
    <dependencies>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spring.version}</version>
    </dependency>
    </dependencies>
    </dependencyManagement>

    子模块:

    <parent>
    <groupId>com.example</groupId>
    <artifactId>my-project-parent</artifactId>
    <version>1.0.0</version>
    </parent>

    好处:版本只写一次,子模块不用重复写 <version>,升级时改父工程一处即可。

    你熟悉的 spring-boot-starter-parent 就是 packaging=pom 的典型——它自己不产出任何 jar,只负责给所有 Spring Boot 子模块定规矩。

    用途 2:聚合工程——统一“调度”

    父工程用 <modules> 把子模块聚在一起:

    <packaging>pom</packaging>

    <modules>
    <module>user-service</module>
    <module>order-service</module>
    <module>common-utils</module>
    </modules>

    在父工程目录执行一次 mvn clean install,Maven 会按依赖关系自动构建所有子模块,这叫 reactor 构建。

    记忆钩子:父工程管“怎么建”,聚合工程管“建哪些”。两者常写在同一个 pom 里。


    四、和 SpringMVC / Spring Boot 项目的关系

    典型的多模块 Spring 项目结构:

    my-shop/
    ├── pom.xml ← packaging=pom,父工程 + 聚合
    ├── common/
    │ └── pom.xml ← packaging=jar,公共工具库
    ├── user-service/
    │ └── pom.xml ← packaging=jar,业务模块
    └── web-app/
    └── pom.xml ← packaging=war 或 jar,Web 入口

    • 根 pom.xml 用 pom 打包:不产出构件,只做继承和聚合。
    • common 用 jar:产出公共 jar,被其他模块依赖。
    • web-app 用 war 或 Spring Boot 可执行 jar:最终部署单元。

    一句话:pom 打包的模块是“组织者”,不是“产品”。


    五、怎么记?三个钩子

    钩子 1:口诀

    pom 是总部,只发号令不出货;
    jar 是饼干,war 是外卖盒;
    父工程定规矩,聚合工程管调度。

    钩子 2:三问法

    看到 packaging=pom,问三句:

  • 它产出 jar/war 吗? 不产出。
  • 它干什么用? 当父工程继承,或当聚合工程管子模块。
  • 它能直接运行吗? 不能,java -jar 和它无关。
  • 钩子 3:文件夹类比

    packaging=pom 的模块就像一个文件夹:文件夹本身不是文件内容,但它里面可以装很多文件,还能规定这些文件怎么命名、怎么组织。


    六、面试 30 秒版

    packaging=pom 表示该 Maven 模块不产生可部署构件,通常用于父工程或聚合工程。父工程通过 <parent> 被子模块继承,在 dependencyManagement、properties、build 中统一管理依赖版本和插件配置;聚合工程通过 <modules> 组织多模块,实现一次构建。它本身不能直接运行,install 时只把 pom 文件安装到本地仓库。Spring Boot 的 spring-boot-starter-parent 就是典型例子。


    七、常见坑

  • 父工程 packaging 写成 jar
    会生成一个几乎空的 jar,而且继承/聚合语义不规范。父工程就该用 pom。

  • 以为 packaging=pom 的模块能 java -jar
    不能。它没有可执行入口,也不是部署单元。

  • 在 packaging=pom 的模块里配 spring-boot-maven-plugin 的 repackage
    没有主类、没有可执行 jar,repackage 会报错。该插件应放在可执行子模块里。

  • 子模块忘了写 <parent> 却怪版本管理不生效
    dependencyManagement 的继承依赖 <parent> 关系,不是靠目录位置自动生效。

  • 聚合工程和父工程混为一谈
    聚合靠 <modules>(管构建范围),继承靠 <parent>(管配置复用)。两者可以合一,但概念不同。


  • 八、记忆卡片

    pom 是总部:不产 jar 不产 war,只定规矩管调度。
    父工程靠 <parent> 继承,聚合工程靠 <modules> 组织。
    jar 是饼干,war 是外卖盒,pom 是文件夹。
    能运行的是子模块,发号施令的是 pom。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » <packaging>pom</packaging>:集团总部不生产产品,只发号施令
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!