漂移日免安装绿色中文版
534M · 2025-11-11
POM(Project Object Model)是maven的基本工作单元。它是一个 XML 文件,其中包含有关项目的信息以及 Maven 用于构建项目的配置详细信息。简单来说:POM(pom.xml)就是整个工程的项目规划书,它定义了项目的所有细节:需要什么材料(依赖)、由谁建造(开发者信息)、如何建造(构建配置)、以及项目的版本等。
超级 POM 是 Maven 的默认 POM。除非显式设置,否则所有 POM 都会扩展超级 POM,这意味着超级 POM 中指定的配置将为项目创建的 POM 继承。超级POM可以理解为MAVEN世界的宪法,所有maven项目都必须遵守。超级POM中定义了一些默认配置,下面列举几个:
<!-- 源代码目录 -->
<sourceDirectory>src/main/java</sourceDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<!-- 测试代码目录 -->
<testSourceDirectory>src/test/java</testSourceDirectory>
<testResources>
<testResource>
<directory>src/test/resources</directory>
</testResource>
</testResources>
<!-- 输出目录 -->
<outputDirectory>target/classes</outputDirectory>
<testOutputDirectory>target/test-classes</testOutputDirectory>
这就是为什么所有 Maven 项目都长得一样的原因。
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
</repository>
</repositories>
所有依赖默认都从 Maven 中央仓库下载。
| 构建阶段 | 默认插件 | 作用 |
|---|---|---|
| compile | maven-compiler-plugin | 编译源代码 |
| test | maven-surefire-plugin | 运行单元测试 |
| package | maven-jar-plugin | 打包成 JAR 文件 |
| install | maven-install-plugin | 安装到本地仓库 |
对不同构建阶段绑定了不同的插件。
<!-- 默认打包方式就是 JAR -->
<packaging>jar</packaging>
POM 用三坐标(groupId、artifactId、version) 的方式唯一标识一个项目。可以理解成项目的身份证。如:
<project> <!-- 说:这是个项目 -->
<modelVersion>4.0.0</modelVersion> <!-- 说:用第4版规则 -->
<groupId>com.mycompany.app</groupId> <!-- 姓:公司/组织名 -->
<artifactId>my-app</artifactId> <!-- 名:项目具体叫啥 -->
<version>1</version> <!-- 排行:这是第几个版本 -->
</project>
一个标准的 POM 文件包含以下核心元素:
这三个元素(groupId, artifactId, version)合称为GAV,是 Maven 世界的唯一身份证。
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
<optional>false</optional>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<project>
<groupId>com.example</groupId>
<artifactId>project-A</artifactId>
<version>1.0.0</version>
...
<dependencies>
<!-- 可选依赖:MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
<optional>true</optional>
</dependency>
<!-- 可选依赖:PostgreSQL驱动 -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.3.6</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>
现在,有另一个项目project-B依赖了project-A:
<project>
<groupId>com.example</groupId>
<artifactId>project-B</artifactId>
<version>1.0.0</version>
...
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>project-A</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>
那么,project-B不会自动传递依赖MySQL和PostgreSQL驱动。如果project-B需要用到MySQL,那么它必须在自己的POM中显式声明MySQL驱动。
用于从父 POM 继承配置,实现统一管理。类似于JAVA中的继承。
注意点:
总的来说:
relativePath规则:
| 设置方式 | 策略 | 适用场景 |
|---|---|---|
| 空标签 | 1. 去本地仓库找 2. 去远程仓库找 | 父POM是知名框架(Spring Boot) |
| ../pom.xml | 1. 去../pom.xml找 2. 找不到再去仓库 | 父POM在本地项目里 |
示例1:
子pom文件:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/>
</parent>
<artifactId>my-app</artifactId>
<!-- 只写了自己的名字,其他都没写 -->
实际生效的配置:
<!-- 自动获得老爸的配置 -->
<properties>
<java.version>11</java.version> <!-- Java 11 -->
<maven.compiler.source>11</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- 自动获得依赖版本管理 -->
<dependencyManagement>
<!-- Spring Boot 2.7.0 兼容的所有版本 -->
<spring.version>5.3.20</spring.version>
<jackson.version>2.13.3</jackson.version>
<!-- ... -->
</dependencyManagement>
<!-- 自动获得插件配置 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
目的: 用于将多个模块/子项目聚合在一起,以便一次性构建整个项目。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>my-app-aggregator</artifactId>
<version>1.0</version>
<packaging>pom</packaging> <!-- 必须为pom -->
<modules>
<module>core-module</module> <!-- 相对路径,表示聚合项目目录下的core-module目录 -->
<module>service-module</module>
<module>web-module</module>
</modules>
</project>
这通常用在父 POM(其 packaging 为 pom)中。聚合项目本身可以没有源码,它只是作为一个构建的入口。在聚合项目目录下执行mvn命令,Maven会根据模块间的依赖关系自动确定构建顺序,依次构建每个模块。
聚合和继承经常结合使用:聚合项目同时作为父项目,提供统一的配置管理。这种情况下,聚合项目的pom.xml中既有也有等配置。
示例:
<project>
<modelVersion>4.0.0</modelVersion>
<!-- 聚合项目的身份证 -->
<groupId>com.mycompany</groupId>
<artifactId>ecommerce-platform</artifactId>
<version>1.0.0</version>
<!-- 关键:打包方式必须是pom -->
<packaging>pom</packaging>
<!-- 聚合的核心:列出所有小弟 -->
<modules>
<module>user-service</module> <!-- 用户服务模块 -->
<module>product-service</module> <!-- 商品服务模块 -->
<module>order-service</module> <!-- 订单服务模块 -->
<module>common</module> <!-- 公共模块 -->
</modules>
<!-- 注意:聚合项目可以同时是父项目 -->
<properties>
<java.version>11</java.version>
<spring-boot.version>2.7.0</spring-boot.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- 统一的依赖版本管理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
<!-- user-service/pom.xml -->
<project>
<modelVersion>4.0.0</modelVersion>
<!-- 既可以认父(继承),又可以被聚合 -->
<parent>
<groupId>com.mycompany</groupId>
<artifactId>ecommerce-platform</artifactId>
<version>1.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<!-- 自己的身份证 -->
<artifactId>user-service</artifactId>
<packaging>jar</packaging> <!-- 子模块通常是jar或war -->
<dependencies>
<!-- 依赖common模块 -->
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 其他业务依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
不使用聚合:
# 要跑4次命令,还要注意构建顺序
cd common && mvn clean install
cd ../user-service && mvn clean install
cd ../product-service && mvn clean install
cd ../order-service && mvn clean install
使用后:
# 在聚合项目根目录,一次搞定
cd ecommerce-platform
mvn clean install
# Maven自动处理:
# 1. 分析模块依赖关系(common → user-service → ...)
# 2. 按正确顺序构建
# 3. 一次性输出所有结果
platform/
├── pom.xml(聚合所有微服务)
├── gateway/(网关服务)
├── user-service/(用户服务)
├── order-service/(订单服务)
└── product-service/(商品服务)
用于定义变量,方便统一管理和复用,常见在父POM中定义公共属性。
<properties>
<java.version>11</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<spring.version>5.3.20</spring.version>
</properties>
<!-- 在依赖中使用属性 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
属性的常见用法:
<properties>
<!-- 默认开发环境配置 -->
<env>dev</env>
<server.port>8080</server.port>
<database.url>jdbc:mysql://localhost:3306/dev</database.url>
</properties>
<profiles>
<profile>
<id>prod</id>
<properties>
<!-- 生产环境覆盖默认值 -->
<env>prod</env>
<server.port>80</server.port>
<database.url>jdbc:mysql://prod-server:3306/prod</database.url>
</properties>
</profile>
</profiles>
用于配置构建过程中的插件和行为。
构建配置可以包含两个主要部分:
此外,构建配置还包括:
一般为:
<build>
<!-- 1. 源代码目录(可以改默认位置) -->
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<!-- 2. 资源文件处理 -->
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering> <!-- 是否替换占位符 -->
</resource>
</resources>
<!-- 3. 插件管理(父POM中用) -->
<pluginManagement>
<plugins>
<!-- 定义插件版本和基础配置 -->
</plugins>
</pluginManagement>
<!-- 4. 实际使用的插件 -->
<plugins>
<!-- 具体配置每个插件 -->
</plugins>
<!-- 5. 扩展(自定义组件) -->
<extensions>
<!-- 扩展Maven核心功能 -->
</extensions>
</build>
<build>
<plugins>
<!-- Spring Boot打包插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.0</version>
<configuration>
<mainClass>com.mycompany.app.Application</mainClass>
<!-- lombok只在编译时起作用,已经变成class了,不需要再打jar包依赖了 -->
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal> <!-- 生成可执行JAR -->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<!-- 在父POM中统一管理插件版本 -->
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<!-- 在子POM中引用,不需要写版本 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<!-- 版本从父POM继承 -->
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>production</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests> <!-- 生产环境跳过测试 -->
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources-prod</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</profile>
</profiles>
: 只是一个声明,它并不实际引入依赖。它主要用于统一管理子模块或项目的依赖版本。子模块需要显式声明依赖,但可以省略 version。如:
示例1:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 不需要写版本,版本由父POM统一管理 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
示例2:
<!-- 直接使用Spring Boot定义的所有版本 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.0</version>
<type>pom</type>
<scope>import</scope> <!-- 关键:导入整个版本表 -->
</dependency>
</dependencies>
</dependencyManagement>
<!-- 现在所有Spring Boot相关的依赖都不用写版本了 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 自动使用2.7.0对应的版本 -->
</dependency>
</dependencies>
关键标签:合并另一个POM的依赖管理。类似于继承别人的dependencyManagement一样。
当父POM中配置了,子模块继承的是依赖的管理规则(主要是版本信息),而不是依赖本身。这带来了几个显著优势:
Profile 允许为不同的环境(如开发、测试、生产)定义不同的配置。它能够覆盖 POM 中的默认配置。
<profiles>
<profile>
<id>dev</id>
<properties>
<db.url>jdbc:mysql://localhost:3306/dev</db.url>
</properties>
<activation>
<activeByDefault>true</activeByDefault> <!-- 默认激活 -->
</activation>
</profile>
<profile>
<id>prod</id>
<properties>
<db.url>jdbc:mysql://prod-server:3306/prod</db.url>
</properties>
</profile>
</profiles>
# 用命令激活
mvn clean install -P prod
<?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>com.example</groupId>
<artifactId>my-webapp</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>My Web Application</name>
<!-- 父POM -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
</parent>
<!-- 属性 -->
<properties>
<java.version>11</java.version>
<junit.version>5.8.2</junit.version>
</properties>
<!-- 依赖管理 -->
<dependencyManagement>
<dependencies>
<!-- 可以在这里管理非Spring Boot管理的依赖 -->
</dependencies>
</dependencyManagement>
<!-- 依赖 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 构建配置 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<!-- 多环境配置 -->
<profiles>
<profile>
<id>dev</id>
<properties>
<activatedProperties>dev</activatedProperties>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>prod</id>
<properties>
<activatedProperties>prod</activatedProperties>
</properties>
</profile>
</profiles>
</project>
比如:
sip-boot依赖了sip-application
sip-application依赖了sip-orm,sip-sieengine
则sip-boot中会引入sip-orm,sip-sieengine