侧边栏壁纸
博主头像
孔子说JAVA博主等级

成功只是一只沦落在鸡窝里的鹰,成功永远属于自信且有毅力的人!

  • 累计撰写 285 篇文章
  • 累计创建 125 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

maven中parent与dependencyManagement、dependencies应用场景及使用方式

孔子说JAVA
2022-08-20 / 0 评论 / 0 点赞 / 52 阅读 / 7,114 字 / 正在检测是否收录...

maven的pom.xml文件中parent,dependencyManagement、dependencies标签是我们经常要用到的,其中parent的作用是引用父工程,dependencyManagement只能位于父工程中,相当于一个对所依赖jar包进行版本管理的管理器,只是声明依赖,并不实现引入,dependencies是对所需要的的jar包进行引入。

1、应用场景

在多模块(module)的项目中,有很多模块中的pom中存在相同的引用,如果此时声明一个父pom文件,将公用的依赖提取到父pom文件中(即使用 <parent> 标签),将大大减少其他pom文件中的依赖的配置。parent标签能够管理多个项目之间公共的依赖,和 java 中的继承相当,作用就是复用。

例如一个项目中有2个module,分别为A模块、B模块,它们都需要依赖一些共同的jar包(如domain.jar,当然jar包可能有多个共有的),如果我们分别在A、B模块各自的pom文件中引入domain.jar的依赖,那么当domain.jar的版本发生变化时,这2个模块的pom文件都要改,项目中依赖越多修改越多。

该场景下我们就需要用到parent标签:

  1. 创建一个新的module,名为parent(当然也可以叫其他名字),存放父pom,parent项目的打包类型为pom,且parent项目中没有任何代码,只是管理多个项目之间公共的依赖。
  2. 父pom中,可以使用parent标签(定义大部分module都使用的组件,如spirng boot)。
  3. 父pom中,可以定义dependencyManagement标签,管理其他模块共同依赖的jar包版本(定义公共依赖),当这些公共依赖的版本号需要修改时,只需要修改parent的dependencyManagement中的版本就可以了。
  4. 父pom中,可以定义dependencies标签,该标签下定义的jar为所有模块共同依赖的jar包。
  5. 在其他两个module中使用parent标签,其坐标就是父pom中声明的坐标。这2个module作为parent模块的子模块。
  6. 在子模块中dependencies标签中,可以直接使用parent模块中dependencyManagement标签定义的jar,而不需要指定版本号(如果子模块指定了公共依赖jar包的版本号,则以子模块的版本号为主)。

2、使用方式

2.1 parent标签

  1. 创建一个新的module,名为parent,存放父pom
<groupId>com.demo</groupId>
<artifactId>parent</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>

<!-- 这里的parent标签页视情况而定,非必须的,如果所有子项目都依赖springboot,就这样定义 -->
<parent>
    <!--这是Spring Boot的父级依赖,这样当前的项目就是Spring Boot项目了。
      spring-boot-starter-parent 是一个特殊的starter,它用来提供相关的Maven默认依赖。
      使用它之后,常用的包依赖可以省去version标签。-->
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.2.RELEASE</version>
    <!--查找顺序:relativePath元素中的地址–本地仓库–远程仓库,
          设定一个空值将始终从仓库中获取,不从本地路径获取-->
    <relativePath/>
</parent>
  1. 在其他两个module中使用parent标签
<parent>
    <groupId>com.demo</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1</version>
</parent>

通过这一步,所有的子模块都可以使用父模块定义的springboot,如果需要修改springboot的版本,只需要修改父pom.xml中parent的version版本号。另外在每个模块中都可以定义properties属性,可以自定义一个或多个Maven属性,然后在POM的其他地方使用${属性名}的方式引用该属性,这种做法的最大意义在于消除重复和统一管理。在父模块中定义的属性可以直接在子模块中使用。

2.2 dependencyManagement标签

在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管理器,只是声明依赖,并不实现引入,只有在某个模块中显示引入某个依赖的时候才会真正的引入jar包。

  • dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显式的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
  • import只在dependencyManagement元素下才有效果,作用是将目标POM中的dependencyManagement配置导入并合并到当前POM的dependencyManagement元素中。

在父模块parent中定义的pom.xml如下:

<?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.demo</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1</version>
    <packaging>pom</packaging>
  
    <name>parent</name>
    <description>parent demo</description>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <druid.version>1.2.8</druid.version>
        <fastjson.version>1.2.76</fastjson.version>
        <commons.collections.version>3.2.2</commons.collections.version>
    </properties>
	
    <!-- 依赖声明 -->
    <dependencyManagement>
        <dependencies>

            <!-- SpringBoot的依赖配置,和上例中parent标签的作用相同,这样做可以让子模块定义自己需要的parent-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.13.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- 阿里数据库连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.version}</version>
            </dependency>

            <!-- collections工具类 -->
            <dependency>
                <groupId>commons-collections</groupId>
                <artifactId>commons-collections</artifactId>
                <version>${commons.collections.version}</version>
            </dependency>

            <!-- 阿里JSON解析器 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <modules>
        <module>a-module</module>
        <module>b-module</module>
    </modules>
  
    <dependencies>

    </dependencies>

    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>

2.3 dependencies标签

在子模块中可以使用dependencies标签引入需要使用的jar包,如果是公共依赖(即在父模块dependencyManagement中已经定义的jar),则不需要指定版本号。如果父模块定义了dependencies依赖,子模块会自动引入这些依赖,但不会自动引入dependencyManagement的依赖。

子模块的pom.xml定义如下:

<?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">
    <parent>
        <artifactId>parent</artifactId>
        <groupId>com.demo</groupId>
        <version>0.0.1</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>
    <artifactId>a-module</artifactId>

    <description>
        A模块
    </description>

    <dependencies>
            <!-- 阿里数据库连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
            </dependency>

            <!-- collections工具类 -->
            <dependency>
                <groupId>commons-collections</groupId>
                <artifactId>commons-collections</artifactId>
            </dependency>

            <!-- 阿里JSON解析器 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
            </dependency>
    </dependencies>

</project>

在dependencies标签中,根据需要引用需要的依赖,如果是父模块定义的公共依赖,则无须声明版本号。在子模块pom.xml文件中,jar的版本判断的两种途径:

  1. 如果dependencies里的dependency自己没有声明version元素,那么maven就会到dependencyManagement里面去找有没有对该artifactId和groupId进行过版本声明,如果有,就继承它,如果没有就会报错,告诉你必须为dependency声明一个version。
  2. 如果dependencies中的dependency声明了version,那么无论dependencyManagement中有无对该jar的version声明,都以dependency里的version为准。

2.4 dependencyManagement与dependencies区别:

  1. dependencyManagement里只是声明依赖,并不自动实现引入,因此子项目需要显示的声明需要用的依赖。
  2. dependencies相对于dependencyManagement,所有声明在dependencies里的依赖都会自动引入,并默认被所有的子项目继承。
  3. 子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目的dependencyManagement中继承下来的。
  4. 只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom,如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
0

评论区