spring-boot-starter-parent 项目的作用
前言
当我们使用 Spring Initializr 创建 Spring Boot 项目时,发现总会继承一个 spring-boot-starter-parent 作用父类。假如不继承就不能用了吗?这个父类的作用是什么呢?

在深入探究之前我们需要先了解一下 Maven 的继承特性。
Maven 继承
Maven 在设计时,借鉴了 Java 面向对象思想,提出了 POM 继承的概念。当一个项目中包含多个子模块时,可以在子模块的 POM 中通过 <parent/> 标签指明其父项目,同时在父模块(项目)中通过 <modules/> 指定它包含哪些子模块。这样就确定不同模块之间的继承关系。其带来的好处是,只需要在父模块中指定依赖模块的版本,子模块不用关心,方便统一管理,减少不同模块相同依赖项版本相互冲突的问题。需要指明的是,如果一个模块定义为父模块,则其 <pakaging/> 属性必须为 pom。
spring-boot-starter-parent
回答上面的问题:如果不继承 spring-boot-starter-parent 就不能使用 Springboot 项目了吗?
答案肯定是否定的。如果我们打开 spring-boot-starter-parent 项目的 POM 文件就会发现,其实它又继承了另外一个 POM,而它本身只引入了 spring-boot-starter 一个依赖项(如果在 initializr的时候没有选择其它依赖项),另外还指定了 java 版本和两个 compiler 插件。
完整的 spring-boot-starter-parent 项目POM文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath>../spring-boot-dependencies</relativePath>
</parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-parent</artifactId>
<version>2.0.5.RELEASE</version>
<packaging>pom</packaging>
<name>Spring Boot Parent</name>
<description>Spring Boot Parent</description>
<url>https://projects.spring.io/spring-boot/#/spring-boot-parent</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>https://spring.io</url>
</organization>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<developers>
<developer>
<name>Pivotal</name>
<email>info@pivotal.io</email>
<organization>Pivotal Software, Inc.</organization>
<organizationUrl>http://www.spring.io</organizationUrl>
</developer>
</developers>
<prerequisites>
<maven>3.5</maven>
</prerequisites>
<scm>
<connection>scm:git:git://github.com/spring-projects/spring-boot.git</connection>
<developerConnection>scm:git:ssh://git@github.com/spring-projects/spring-boot.git</developerConnection>
<url>http://github.com/spring-projects/spring-boot</url>
</scm>
<issueManagement>
<system>Github</system>
<url>https://github.com/spring-projects/spring-boot/issues</url>
</issueManagement>
</project>
会发现它其实继承了 spring-boot-dependencies 。
spring-boot-dependencies
既然 sprin-boot-starter-parent 继承了 dependencies,那么 dependencies 里又做了些什么呢?因为 dependencies 的 POM 文件内容太长就不在这里列出了。其主要内容就是 <dependencyManagement/> 和 <pluginManagement/> 两个标签。
可以这么说:dependencies 通过 <DependencyManagement/> 和 <pluginManagement/> 两个标签统一指定了很多依赖并明确了它们的版本号,实现了上面我们说的统一版本管理,但其实并未真的引入这些依赖项。
dependencyManagement 和 pluginManagement
Maven 通过这种 xxxManagement 标签,或者说组件对依赖进行管理,它具有以下2大特性:
- 在该元素下声明的依赖不会实际引入到模块中,只有在 dependencies 元素下同样声明了该依赖,才会引入到模块中。
- 该元素能够约束 dependencies 下依赖的使用,即 dependencies 声明的依赖若未指定版本,则使用 dependencyManagement 中指定的版本,否则将覆盖 dependencyManagement 中的版本。
综上,spring-boot-dependencies 项目,或者说 spring-boot-starter-parent 项目只是给我们提供了一个管理依赖的 POM,而这些依赖是在当前 springboot 版本下进行验证过的一个依赖合集。
如果不引入(继承)spring-boot-starter-parent
我们新建一个空的 Maven 项目,依赖中引入 spring-boot-starter 框架(注意指定 version),然后在启动类上加上@SpringBootApplication 注解,照样可以成功启动:

Maven单继承问题
有人可能会问,如果我想使用 spring-boot-starter-parent 提供的依赖管理,但又不想继承它,可不可以?
答案是肯定的。
单继承:maven和Java一样都是单继承机制,maven当中有 <type>pom</type> 和 <scope>import</scope> ,通过这两个标签在dependencyManagement中声明依赖,可以替代继承(达到类似parent标签的作用,解决了单继承问题)。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.4.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
注意上面是官方推荐的方式,即引入 spring-boot-dependencies,而不是 spring-boot-starter-parent。但这样并不等价于继承 parent 的方式,原因是 import 依赖范围只能与 dependencyManagement 元素配合使用才会有效,其功能是将目标 pom.xml 中的 dependencyManagement 配置导入合并到当前 pom.xml 的 dependencyManagement 中,所以这种方式并没有把 parent 中引用的 plugin 一并继承过来,所以还需要我们自己声明打包插件的引用:
<build>
<plugings>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.8.1</version>
</plugin>
</plugins>
</build>

浙公网安备 33010602011771号