Maven pom.xml 文件格式详解一

目录

项目基本信息配置

parent 依赖继承

dependency 依赖引用

如何解决依赖冲突

resource 指定资源文件

plugin 指定 Maven 插件

fork true 新开 Jvm 运行插件

packaging 打包类型说明

modules 多模块管理

relativePath 相对父项目 pom 路径

DepencyManagement 依赖管理

properties 自定义全局属性

repositories 配置工程远程仓库


1、pom:project object model 项目对象模型

2、pom.xml 是 Maven 的核心配置文件,一个 Maven 项目有且只有一个 pom.xml 文件,必须在项目的根目录下。

项目基本信息配置

1、设置当前开发项目信息:

<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>grp.budget</groupId>
	<artifactId>bgt-basic-server</artifactId>
	<version>1.1.4-SNAPSHOT</version>
	<name>bgt-basic-server</name>
    <description>Demo project for Spring Boot</description>
	<packaging>jar</packaging>
modelVersion描述当前 pom 文件遵从哪个版本的项目描述符
groupId组织标识,通常是公司域名,例如:com.alibaba
artifactId项目名称,例如:druid、guava
version版本号,例如:1.0、1.1.4-SNAPSHOT
description项目的描述信息
packaging打包的格式,可以为:pom , jar , maven-plugin , ejb , war , ear , rar , par等等

parent 依赖继承

1、子项目继承父项目的依赖、插件等等,如:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

dependency 依赖引用

1、引用第三方 jar 包依赖:

<dependencies>
	<!-- dependency 表示依赖-->
	<dependency>
        <!-- 创建项目的组织或团体的唯一 Id -->
		<groupId>org.freemarker</groupId>
        <!-- 项目名称 -->
		<artifactId>freemarker</artifactId>
        <!-- 产品版本号 -->
		<version>2.3.30</version>
        <!-- 依赖范围 -->
		<scope>compile</scope>
        <!-- 本地的/系统的类库路径 -->
        <!-- <systemPath>${project.basedir}/libs/tinyid-client-0.1.0-SNAPSHOT.jar</systemPath> -->
        <!-- 设置依赖是否传递,默认为 false-依赖传递,true 表示依赖不进行传递 -->
        <optional>true</optional>
	</dependency>
</dependencies>

<scope>:为jar包作用范围,可选值如下:

compile编译范围,默认值,依赖在所有的 classpath 中可用,同时它们也会被打包。用的最多的选项。
provided已提供范围,表明 dependency 由 JDK 或者容器提供。例如如果开发了一个 web 应用,可能在编译 classpath 中需要可用的 Servlet API 来编译一个servlet,
但是你不会想要在打包好的 WAR 中包含这个 Servlet API;因为 Servlet API JAR 由你的应用服务器或者 servlet 容器提供。
已提供范围的依赖在编译时(不是运行时)可用,它们不是传递性的,也不会被打包。
runtime运行时范围,依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如可能在编译的时候只需要 JDBC API JAR,而只有在运行的时候才需要 JDBC 驱动实现。
test测试范围。依赖在一般的编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用。
system本地的/系统的,maven仓库之外的类库,​  与 systemPath 配合使用,

通常用于项目引用本地Maven仓库以外的第三方 jar 包

compile 、provided  、runtime 的区别
通过 maven 引入的jar包,里面的类,都是已经编译好的字节码文件。
通过 compile 和 provided 引入的 jar 包,里面的类在项目中可以直接 import 引用使用,编译没问题,
通过 runtime 引入的 jar 包中的类,只在运行时生效,所以项目中不能直接 import 使用,只能通过反射等方式使用。
通过 compile 和 runtime 引入的 jar 包,会一起打包到自己项目包里,而 provided 引入的 jar 包则不会。
举个例子就很容易懂了,如果不想团队成员直接使用 log4j2 实现,而是面向 slf4j 接口编程,则可以设置:
    slf4j 定义为 compile
    log4j2 定义为 runtime
依赖范围对于编译classpath有效(src/main)对于测试classpath有效(src/test)对于运行时classpath有效例子
compileYYYSpring-boot
test-Y-Junit
providedYY-Servlet-api
runtime-YYJDBC驱动
systemYY-本地的,maven仓库之外的类库

如何解决依赖冲突

1、使用 Maven 自身的依赖调解原则
    A、第一声明者优先原则
        pom.xml 文件从上到下优先级由高到低,先声明的优先。
        如 pom 中有组件 A、B,它们同时依赖了 C,当 A、B 依赖 C 的版本不同时,A、B 谁先声明在前,就以谁关联 C 的版本为准。
    B、路劲近者优先原则
        依赖传递时,被依赖的组件谁离本 pom.xml 文件近,谁就优先。
        如 pom 中有组件 A、B,它们同时依赖了 C,当 pom 文件直接引入组件 C 时,则 A、B 依赖的组件 C 即使不用排除也不会再生效。

2、依赖排除
    2.1、对于冲突的依赖,可以直接使用 <exclusions> 标签排除。
    2.2、如 pom 中有组件 A、B,它们同时依赖了 C,当 A、B 依赖 C 的版本不同时,可以对不需要的 C 组件,直接在 A、B 依赖中排除。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <!--移除掉 spring boot 默认的日志启动器-->
                <exclusion>
                    <artifactId>spring-boot-starter-logging</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>

3、锁定版本/依赖管理
    3.1、使用 dependencyManagement 管理依赖 jar 包的版本,版本锁定后不会再考虑依赖的声明顺序以及路径优先,以管理的版本为准。

  <!--自定义属性-->
    <properties>
        <hutool.version>5.5.7</hutool.version>
    </properties>

    <!--依赖管理的好处是确保依赖的版本号保持统一,引用依赖(dependency)时,可以省略不写 version-->
    <!--新建 spring cloud 项目时就会自动有 dependencyManagement 管理微服务的依赖版本-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <!--取的是上面 properties 中自定义的版本号-->
                <version>${hutool.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

resource 指定资源文件

1、一般情况下资源文件(各种 yml、xml,properites,xsd、ftl 文件等)都放在 src/main/resources 下面,maven 打包时,自动把这些资源文件打包到 classes 类路径下。

2、然而有时候,比如 mybatis 的 XxxMapper.xml 文件,如果和 XxxMapper.java 一样放在 src/main/java 源码目录下面,这样 maven 打包时,默认这些非 .java 的资源文件是不会被打包的(maven认为src/main/java只是java的源代码路径)。解决办法也有很多种方式,比如使用 resources 标签强行指定 src/main/java 目录下的哪些文件也必须作为资源文件处理。

3、**/* 这样的写法,是为了保证各级子目录下的资源文件被打包,includes 是包含,excludes 是排除。

 <build> 
    <resources> 
      <resource> 
        <directory>src/main/java</directory>  
        <includes> 
          <include>**/*.*</include> 
        </includes> 
      </resource> 
    </resources>  
    <plugins>
        ...
     </plugins>
 </build> 

plugin 指定 Maven 插件

1、如下所示就是 spring-boot 的 spring-boot-maven-plugin 插件,它能够以 Maven 的方式为应用提供 Spring Boot 的支持,能够将 Spring Boot 应用打包为可执行的 jar 或 war 包,然后双击即可运行 Spring Boot 应用。

2、 spring-boot-maven-plugin 是每个 Spring boot 项目都会有的插件。

3、includeSystemScope 通常用于项目引用本地Maven仓库以外的第三方 jar 包

 <build> 
    <resources> 
       ...
    </resources>  
    <plugins>
       <plugin>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-maven-plugin</artifactId>
          <configuration>
               <fork>true</fork>
               <!--打包配置:是否包括系统范围的依赖项-->
               <!--<includeSystemScope>true</includeSystemScope>-->
          </configuration>
        </plugin>
     </plugins>
 </build> 

fork true 新开 Jvm 运行插件

1、IDEA 使用 spring-boot-devtools热部署项目时,通常在 spring-boot-maven-plugin 插件下面会加上:plugin.configuration.fork=true

2、<fork>false</fork> 表示 Maven 使用自身的 JVM 虚拟机运行插件,而 <fork>true</fork> 则告知 Maven 启动一个新的 JVM 虚拟机进程运行插件。使用 spring-boot-devtools 模块时需要特定 JVM 配置来运行,所以需要创建新的 JVM 虚拟机进程来运行。

3、插件源码中对 fork 属性的解释是:

Flag to indicate if the run processes should be forked. Disabling forking will disable some features such as an agent, custom JVM arguments, devtools or specifying the working directory to use.
(指示是否应分叉运行进程的标志。禁用分叉将禁用某些功能,例如代理、自定义JVM参数,开发工具或指定要使用的工作目录。)

packaging 打包类型说明

1、packaging 设置项目打包的方式,可选值有:pom, jar(默认值), war, maven-plugin, ejb, ear, rar, par 等等,其中常用的是 jar、war、pom。

打包方式描述
jar作为内部调用,或者是作为服务使用
war需要部署在容器上的项目,比如部署到 Tomcat、Jetty...
pom

多模块项目架构时,父项目必须指定为 pom

2、多模块管理 pom 类型说明

2.1、使用 maven 分模块管理项目时,父级项目的 packaging 都设置为 pom,表示项目里没有 java 代码(也不执行代码),只是为了聚合工程或传递依赖使用。
2.2、通过 <modules> 标签指定子模块的相对路径,这就可以直接在父项目里执行 maven 命令,一次构建全部模块(当然每个模块逐个执行也是可以的)。
2.3、对父项目执行 maven 命令时,只有当父项目的 packing 类型为 pom 时,才会对所有的子模块执行同样的命令。
2.4、在子模块的 pom.xml 通过 <parent> 标签继承父项目。

modules 多模块管理

1、用于管理同个项目中的各个模块,通常用于大一点的项目。

2、假设项目分为 A、B、C、D 四个模块,在父模块的 pom.xml 中,一般这样来对子模块进行聚合:

<modules>
    <module>A</module>
    <module>B</module>
    <module>C</module>
    <module>D</module>
</modules>

3、假设各个子模块间,配置的相互依赖关系为:

A 依赖 B
B 依赖 C
D 依赖 A

4、子模块的构建顺序受两个因素影响:

1、父模块中各子模块的声明次序,优先级由上到下
2、子模块间的依赖关系,被依赖的先执行

5、构建父模块时,控制台实际的模块构建顺序为:C、B、A、D。

relativePath 相对父项目 pom 路径

1、搭建 Spring boot 项目时,项目中都会默认有这样一句:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

2、relativePath 表示父项目(parent)的路径,即引用的这个 parent 项目的 pom 文件的位置,通常有三种情况。

默认值(不写)不写 <relativePath> 标签时默认值就是 ../pom.xml,会从本地路径中获取 parent 的 pom,多模块项目架构时子模块就是这种情况(直接不写)
<relativePath/>为 relativePath 指定一个空值,此时将始终从仓库中获取,不从本地路径获取,比如 Spring boot 就是这种情况
<relativePath>指定的pom路径<relativePath/>明确指定一个本地的路径,从本地路径获取parent的pom

DepencyManagement 依赖管理

1、dependencyManagement 用于声明/管理依赖的版本,方便统一管理各个子模块的版本以及 scope,但实际并不引入,因此子项目中需要显示的引用依赖(dependency)。

2、子项目中引用了依赖,并且没有指定具体 version 或者 scope 时,就会自动从父项目中继承 dependencyManagement  指定的 version 或者 scope ,如果子项目中指定了版本号,则会使用子项目中指定的版本。

3、在线演示源码:pom.xml · 汪少棠/basic - Gitee.com
        

properties 自定义全局属性

1、properties 用于自定义全局属性变量,在 pom.xml 文件中可以通过 ${property_name} 的形式引用变量的值。

2、properties 常用于声明相应的版本信息,然后在 dependency 下引用依赖的时候用 ${property_name} 关联版本信息。

3、${property_name} 还可以引用 pom 属性

${project.groupId}对应 <project><groupId> 元素的值
${project.artifactId}对应 <project><artifactId> 元素的值
${project.version}对应 <project> <version> 元素的值
${project.basedir}表示项目根目录(即包含pom.xml文件的目录)
${project.build.sourceDirectory}项目的主源码目录,默认为 xxx/src/main/java/
${project.build.testSourceDirectory}项目的测试源码目录,默认为 xxx/src/test/java/
${project.build.directory}项目构建输出目录,默认为 ${project.basedir}/target
${project.build.outputDirectory}项目主代码编译输出目录,默认为 ${project.build.directory}/classes
${project.build.testOutputDirectory}项目测试代码编译输出目录,默认为 ${project.build.directory}/test-classes
${project.build.finalName}项目打包输出文件的名称,默认为 ${project.artifactId}-${project.version}

4、${property_name} 还可以引用 Maven 内置属性:

${basedir}表示项目根目录(即包含pom.xml文件的目录),等同于 ${project.basedir}
${version}表示项目版本,等同于 ${project.version} 或者 ${pom.version}

5、${property_name} 还可以引用 Java 系统(System)属性:

    所有 Java 系统(System)属性都可以使用 Maven 属性引用,例如 ${user.home} 指向了用户目录
    可以通过命令行 mvn help:system 查看所有的 Java 系统属性

6、${property_name} 还可以引用表示项目版本,等同于 ${project.version} 或者 ${pom.version}

    所有环境变量都可以使用以 'env.' 开头的 Maven 属性引用,例如 ${env.JAVA_HOME} 表示 JAVA_HOME 环境变量的值。

    也可以通过命令行 mvn help:system 查看所有环境变量。

 在线演示源码:pom.xml · 汪少棠/basic - Gitee.com

repositories 配置工程远程仓库

1、repositories  用于配置当前工程使用的远程仓库。

2、项目依赖查找顺序:本地仓库—> 当前工程pom.xml中配置的远程仓库—> setting.xml 中配置的远程仓库。

    <repositories>
        <!--有些最新的jar包,或者公司内部的jar包,可能在远程中央仓库上并没有提供,此时可以指定官方提供的仓库,或者公司的私服-->
        <!--比如 Spring cloud 项目新建时默认会提供地址 https://repo.spring.io/milestone -->
        <repository>
            <id>qcloud-plugin-central</id>
            <name>腾讯云公共仓库</name>
            <url>http://mirrors.cloud.tencent.com/nexus/repository/maven-public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>huaweicloud</id>
            <name>华为云公共仓库</name>
            <url>https://mirrors.huaweicloud.com/repository/maven/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>aliyunmaven</id>
            <name>阿里云公共仓库</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
        <repository>
            <id>nexus</id>
            <name>nexus</name>
            <url>http://124.254.6.162:8081/nexus/content/groups/public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蚩尤后裔-汪茂雄

芝兰生于深林,不以无人而不芳。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值