一、前言

我们平常时开发springboot项目时,pom文件中引入的依赖,总是少不了spring-boot-starter-parent 或 spring-boot-dependencies(仅其一),若未引入,会导致我们的项目缺包,今天我们来探讨一些两者的区别。

当我们使用 spring 或 spring-boot 开发项目时,需要引入很多依赖,包括 spring 本身的组件、各种 spring-boot-starter、以及其它第三方依赖(如:slf4j、redis)。

依赖多了,版本的选择是个问题,就怕哪个版本选择的不对导致出现一些意想不到的 BUG。

比如下面这个例子:

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.26</version>
    </dependency>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.2.14</version>
    </dependency>
</dependencies>

slf4j 的 1.7.26 版本、postgresql 的 42.2.14 版本和 spring 的 5.2.10.RELEASE 版本会不会有冲突呢???

Spring Boot的每个发布版本都会规划它所支持的依赖项。实际上,你不用指定这些依赖项的版本号,因为Spring Boot都为你管理好了。当更新Spring Boot时,会相应的更新依赖。

二、spring-boot-starter-parent

简述

Maven用户可以继承spring-boot-starter-parent项目,来获取最佳依赖。这个父项目提供了以下几个功能:

  • 默认Java 1.6编译
  • UTF-8编码格式
  • 依赖管理部分,可让你对公共依赖省略version标签。继承自spring-boot-dependencies POM。
  • 良好的资源过滤
  • 良好的插件配置
  • 对于application.properties和application.yml包括profile-specific文件,良好的资源过滤
  • 最后一点:因为默认配置文件接受Spring风格的占位符(${}),Maven过滤器换成了@…@占位符。(可以通过Maven属性resource.delimiter替换)
 <parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>2.1.3.RELEASE</version>
   <relativePath/> <!-- lookup parent from repository -->
</parent>

只需要在这里指定Spring Boot的版本号。如果导入其他的starters,你可以完全省略版本号。

使用这个配置,你还可以通过property覆盖内部的依赖。例如,在pom.xml中升级Spring Data release train。

<properties>
    <spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version>
</properties>

可以通过spring-boot-dependencies pom,查看支持的属性列表。

完整案例

<?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>springboot-rabbitmq-fanout-producer</artifactId>
    <version>1.0-SNAPSHOT</version>

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

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

三、spring-boot-dependencies

简述

可能有人不喜欢继承spring-boot-starter-parent POM。你可能有自己的企业标准parent,或者你可能只是比较喜欢明确声明所有的Maven配置。

如果你不想使用spring-boot-starter-parent,你依然可以通过使用scope=import利用依赖管理的便利:

<dependencyManagement>
     <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.1.3.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

这种方式不能使用property的形式覆盖原始的依赖项。要达到同样的效果,需要在dependencyManagement里面的spring-boot-dependencies之前添加依赖的东西。例如,要升级Spring Data release train,pom.xml应该是这样的:

<dependencyManagement>
    <dependencies>
        <!-- Override Spring Data release train provided by Spring Boot -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-releasetrain</artifactId>
            <version>Fowler-SR2</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.1.3.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

完整案例

<?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>springboot-rabbitmq-fanout-producer</artifactId>
    <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.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.3.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

只需在 dependencyManagement 里面配置好 spring-boot-dependencies 的版本,在 dependencies 里面就不用再指定其它版本号了,其实 spring-boot-dependencies 就是一个 pom.xml,里面管理了很多常见第三方的依赖和版本,当然你也可以重新指定版本号。

四、总结

由上述,我们已经知道,开发springboot项目,引入spring-boot-starter-parent 与 spring-boot-dependencies两者之一是必须的,但这里还需要看下这两个依赖的源码,让我们能对它们的认知更加深刻。
首先,我们从spring-boot-starter-parent进入
在这里插入图片描述

可以看到,spring-boot-starter-parent 其实继承了spring-boot-dependencies ,我们再进入spring-boot-dependencies 内:

在这里插入图片描述
可以看到的是spring-boot-dependencies内为我们管理着许多依赖,也统一管理着一些依赖的版本号,因此才有我们上述所说的,后续引入的这些依赖就不需要重新指定版本号了(前提是spring-boot-dependencies有管理)。

还有一个问题为什么两者对<spring-data-releasetrain.version>的覆写方式不一样?
因为spring-boot-starter-parent 继承了spring-boot-dependencies ,并提供支持使用实现重写。

五、参考

文章借鉴了下面两位博主的文章。

https://www.cnblogs.com/sjshare/p/10669001.html

https://blog.csdn.net/qq_34246965/article/details/119729115?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐