dependencyManager中的import scope

最近发现了一些新的东西:使用阿里SpringBoot初始化SpringBoot项目时,并不需要继承SpringBoot的starter-parent就可以完成版本裁决。我观察其为我们生成的pom.xml文件,其核心代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13

<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>

这些知识已将超出了我的知识范围,所以我决定花点时间搞懂这些东西。

搞懂值为import的scope

Maven是不支持多重集成的,如果我们想要多重继承的效果,我们就需要import scope。我们可以将dependencyManagement放到单独的专门用来管理依赖的pom中,然后在需要使用依赖的模块中通过import scope依赖,就可以引入dependencyManagement。

我决定使用Idea多Maven项目的方式来验证一下这个问题(先创建一个普通项目,再创建多个Maven的模块,这样方便代码的管理)。在project_01中,我们准备如下的pom文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

<?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>org.example</groupId>
    <artifactId>project_01</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter-api</artifactId>
                <version>5.7.2</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.16</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

在project_02中,我们准备如下的pom文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

<?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>org.example</groupId>
    <artifactId>project_02</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.example</groupId>
                <artifactId>project_01</artifactId>
                <version>1.0-SNAPSHOT</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

最终实验结果如我们所期待的一致,我们的project_02项目拿到了正确的预设的:

2021-07-21-16-30-39

需要注意的是import scope只能用在dependencyManagemen里面。

import scope会导入properties么

这部分我所关注的问题在于:

  1. 我有办法修改import scope中的版本么
  2. 我可以利用import scope中定义的变量么(意义不大,仅实验)

使用import scope方式的表现

了解了这些后,我产生了一个问题:import scope会帮我们导入properties标签中定义的各种标签么,为了验证这一点,我在project_01的pom文件中加入了如下内容:

1
2
3

<j.fastjson.version>1.2.76</j.fastjson.version>

并在project_02的pom文件中添加了如下的依赖:

1
2
3
4
5
6
7

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>${j.fastjson.version}</version>
</dependency>

实验的过程中,Idea无法找到j.fastjson.version,这个和使用继承的方式的表现有点不一样。

parent标签的表现

现在来验证一下继承,我创建了project_03,并准备了如下的pom文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

<?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>

    <parent>
        <artifactId>project_01</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>project_03</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${j.fastjson.version}</version>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </dependency>
    </dependencies>
</project>

最终发现变量被正确的继承了:

2021-07-21-16-44-53

这个是符合我的预期的。

验证import scope的版本号是否可修改

实验中我先将project_01的版本信息抽取成property,然后调整project_02的代码,使其可以正常的拿到版本信息。然后我定义了如下的变量:

1
2
3
4

<j.junit-jupiter-api.version>5.6.3</j.junit-jupiter-api.version>
<j.log4j.version>2.14.1</j.log4j.version>

实验的过程中发现,我没有办法覆盖掉import scope中的配置。

我对这个结果是不太满意的,因为在我们的日常开发过程中,是存在通过修改property变量来替换掉SpringBoot给我们预定义的版本的需求的(用于升级某个组件或者降级),如果import scope不支持这种操作的话,会给我们带来很大的麻烦。

参考资料

  1. 使用import scope解决maven继承(单)问题