基于 maven 的 Spring Boot 项目,我们通常会指定 spring-boot-starter-parent 作为当前项目 pom 的 parent,大多数人都知道这可以用于依赖管理,以便引入依赖时可以省略版本号,这篇我们聊点不一样的。

maven 中的继承

spring-boot-starter-parent 作为 maven pom 中的 parent,我们需要先了解下 maven pom 中的 parent 有什么作用。

我们经常在多个项目中引入相同的依赖,如 Spring MVC 相关依赖。

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.2.7.RELEASE</version></dependency></dependencies>

对于相同的部分,作为程序员的我们下意识的会将其提取到公共的部分,maven 提供了类似 Java 的继承机制,只要将依赖加入到 parent,继承 parent 的项目会自动引入 parent 中的依赖。

定义如下的 parent:

<?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.zzuhkp</groupId><artifactId>project-parent</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.2.7.RELEASE</version></dependency></dependencies></project>

这里定义了一个名为 project-parent 的 maven 项目,并引入了 spring-boot-starter-web,再创建一个子项目。

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.zzuhkp</groupId><artifactId>project-parent</artifactId><version>1.0-SNAPSHOT</version><relativePath>../pom.xml</relativePath></parent><groupId>com.zzuhkp</groupId><artifactId>spring-boot-child1</artifactId><version>1.0-SNAPSHOT</version></project>

子项目 spring-boot-child1 项目中仅引入了上面我们定义的 parent,以相同的方式定义一个子项目 spring-boot-child2,借助 idea 内置 maven 支持功能,查看各项目的依赖情况。
可以看到,两个子项目都成功引入了 parent 中引入的依赖。不过可能不是所有的子项目都想要依赖 parent 中的依赖,maven 还支持在 parent 中定义依赖,子项目可以有选择性的引入 parent 的依赖。修改 parent 定义如下。

<?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.zzuhkp</groupId><artifactId>project-parent</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.2.7.RELEASE</version></dependency></dependencies></dependencyManagement></project>

和原始版本相比,这里唯一的变化是将 dependencies 元素移到了 dependencyManagement 元素内部。修改 spring-boot-child1 项目如下。

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.zzuhkp</groupId><artifactId>project-parent</artifactId><version>1.0-SNAPSHOT</version><relativePath>../pom.xml</relativePath></parent><groupId>com.zzuhkp</groupId><artifactId>spring-boot-child1</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies></project>

与原始版本不同的是这里添加了 spring-boot-starter-web 依赖,由于 parent dependencyManagement 已经定义了依赖的 version,因此子项目直接进行了继承从而可以省略。再借助 idea 看下依赖。
这时 parent 和 spring-boot-child2 中的依赖都已经不见了,只有我们显式在 spring-boot-child1 中定义的依赖还在。

上面只是介绍了 maven dependencies 依赖与 dependencyManagement 依赖版本的继承,还有很多其他可以继承的元素,就不具体介绍了,我们重点关注的可以继承的元素如下。

  • groupId:项目组ID,项目坐标元素之一。
  • version:项目版本号,项目坐标元素之一。
  • properties:maven 属性信息,可以在其他标签中引入。
  • dependencies:项目依赖描述。
  • dependencyManagement:项目依赖管理描述。
  • build:构建相关配置,如源码目录、输出目录、插件等。

spring-boot-starter-parent

spring-boot-starter-parent 只用来作为其他 maven 项目的 parent,因此它除了 pom 文件并没有什么有效的内容,要理解 spring-boot-starter-parent,还得看它的 pom 文件定义。由于 pom 文件内容过长,下面我们分别进行介绍它主要引入的功能。

1. 依赖版本管理

spring-boot-starter-parent 自身并没有定义 dependencyManagement,依赖管理依托于它的 parent spring-boot-dependencies,见下图。
spring-boot-dependencies 内部定义了很多依赖,这样我们就不用关心依赖的版本了。
依赖管理是我们用的最多的功能,示例代码如下。

<?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><version>2.2.7.RELEASE</version><artifactId>spring-boot-starter-parent</artifactId><groupId>org.springframework.boot</groupId></parent><groupId>com.zzuhkp</groupId><artifactId>project-parent</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
</project>

2. 属性配置

spring-boot-starter-parent 添加了一些默认的配置,如指定了使用的 JDK 版本号为 1.8,编译时使用 UTF-8 编码方式。

3. 资源过滤

spring-boot-starter-parent 指定了编译资源文件时将 **/application*.properties**/application*.yml**/application*.yaml 中的 maven 占位符替换为具体的属性值。具体如下。
如果没有引入 spring-boot-starter-parent,需要在 application.properties 文件中使用 maven 占位符时切记要手动配置 resource

4. 插件配置

spring-boot-starter-parent 内置了不少插件配置,我们重点关注 maven-compiler-pluginspring-boot-maven-plugin

对于 maven-compiler-pluginspring-boot-starter-parent 主要配置了 parameters 参数,以便将方法参数名写入 class 文件。
对于 spring-boot-maven-plugin 插件,spring-boot-starter-parent 为其配置了 repackage 目标。
spring-boot-maven-plugin 插件 repackage 目标默认绑定 maven 声明周期中的 package 阶段,这样当打包后这个插件就会进一步将所有依赖的 jar 包以及当前项目的代码打包到一个 jar 包中,从而支持 jar -jar 启动 Spring Boot 项目。

spring-boot-starter-parent 指定 spring-boot-maven-plugin 插件目标后,当我们的项目指定了 parent 为 spring-boot-starter-parent 后,就可以省略插件目标配置了。

    <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.7.RELEASE</version></parent><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>

spring-boot-dependencies

spring-boot-dependenciesspring-boot-starter-parent 的好兄弟,由于 maven 只支持单继承,如果项目本身已经指定了其他 parent,则只能用 spring-boot-dependencies 进行依赖管理。

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

加入上面的代码就可以注解引入 spring-boot-dependencies 中定义的依赖不用指定版本号了。

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

依赖版本升级

spring-boot-starter-parentspring-boot-dependencies 都进行了依赖管理,如果依赖中存在漏洞我们就需要紧急进行修复,它们之间的升级方式有所不同。

对于 spring-boot-starter-parent 而言,我们可以直接在 properties 中指定依赖的版本。以前段时间暴露出来的 log4j 2 漏洞为例,为了升级 log4j 2 版本号,我们可以在自己的项目中进行如下配置。

    <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.7.RELEASE</version></parent><properties><log4j2.version>2.17.2</log4j2.version></properties>

指定 log4j2.version 属性是因为在 spring-boot-dependenciesloj4j 2 的坐标使用了这个属性值作为版本号,如下。
对于 spring-boot-dependencies,如果要进行依赖升级,配置属性是不行的,需要在 spring-boot-dependencies 前面加上要升级的依赖的坐标,示例如下。

    <dependencyManagement><dependencies><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-to-slf4j</artifactId><version>2.17.2</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.2.7.RELEASE</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

如果要升级的依赖不是 spring-boot-starter-parentspring-boot-dependencies 管理的依赖,还可以直接把它加到 dependencies 标签下,这样依据最短路径原则,我们直接配置的依赖会覆盖间接引入的依赖,示例如下。

    <dependencies><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.17.2</version></dependency></dependencies>

总结

本文从 maven 中的继承开始讲起,然后介绍 spring-boot-starter-parent 与替代它的 spring-boot-dependencies,最后还介绍了 Spring Boot 项目的依赖版本升级。

在介绍 spring-boot-starter-parent 的时候我们提到了一个插件 spring-boot-maven-plugin 可以将项目打成可执行的 jar 包,这个插件除了打包,还具有在开发环境运行 Spring Boot 的项目的功能,下篇会重点介绍这个插件如何运行 Spring Boot 项目的。

如果本文对你产生了少许帮助,不妨动动小手点个赞支持一下,同时也欢迎留言讨论。

Spring Boot 第三篇:理解 spring-boot-starter-parent相关推荐

  1. Spring Boot (三)集成spring security

    项目GitHub地址 : https://github.com/FrameReserve/TrainingBoot Spring Boot (三)集成spring security,标记地址: htt ...

  2. spring cloud连载第二篇之Spring Cloud Config

    Spring Cloud Config Spring Cloud Config为分布式服务提供了服务侧和客户侧的外部配置支持.通过Spring Cloud Config你可以有一个统一的地方来管理所有 ...

  3. 【Spring 数据访问终篇】Spring + Hibernate + Mysql

    说来惭愧,数月没有更新博客,今天带来spring访问数据的最终篇,spring + hibernate. 本篇文章将用maven创建一个简答的java项目,并结合spring框架中的hibernate ...

  4. Spring相关文章汇总篇【Spring,SpringBoot,SpringCloud等】

      因为Spring框架包含的组件比较多,写的博客内容也比较多,虽然有分专栏但是依然不方便查找,所以专门用一篇文章来记录相关文章,会不定期更新. 一.Spring 1.基础内容 Spring介绍 Sp ...

  5. Spring学习第3篇:Spring容器的基本使用

    大家家好,我是一名网络怪咖,北漂五年.相信大家和我一样,都有一个大厂梦,作为一名资深Java选手,深知Spring重要性,现在普遍都使用SpringBoot来开发,面试的时候SpringBoot原理也 ...

  6. Spring之(三)用Spring改造打印机

    三.用Spring改造打印机 问题描述:打印机是由墨盒和纸张确定的,墨盒中又有不同的颜色,纸张中又有不同的纸张类型,打印机通过墨盒的颜色来确定要打印的颜色,根据纸张的类型来确定打印纸张的类型. 问题分 ...

  7. 请简述什么是spring的ioc和di_理解Spring中的IoC和DI

    什么是IoC和DI IoC(Inversion of Control 控制反转):是一种面向对象编程中的一种设计原则,用来减低计算机代码之间的耦合度.其基本思想是:借助于"第三方" ...

  8. Spring Boot 第三篇:SpringBoot用JdbcTemplates访问Mysql

    本文介绍springboot通过jdbc访问关系型mysql,通过spring的JdbcTemplate去访问. 准备工作 jdk 1.8 maven 3.0 idea mysql 初始化mysql: ...

  9. 第三篇:Spring Boot整合Servlet

    一.Springboot整合Servlet 第一种方案: 1.创建一个自定义的servlet,继承HttpServlet添加@WebServlet注解 以前ssm中的web.xml配置文件中的serv ...

最新文章

  1. Ubuntu下编译ffmpeg+openh264+x264
  2. 【django轻量级框架】用Mysql的各种项目响应速度慢?一招解决!
  3. js unix时间戳转换
  4. php对角线数组代码,php数组内容查找代码
  5. MegaCli命令总结
  6. 国土空间规划师提升指南
  7. java 求向量的均值,标准数组——向量
  8. 程序员如何年薪百万?深度学习必读书籍!
  9. epoll编程实例客户端_网络编程:epoll
  10. [Angular2 Animation] Control Undefined Angular 2 States with void State
  11. C++字符串输入输出操作
  12. CentOS7 ftp服务离线安装
  13. 什么是孤独?。。。一款只有6个用户的APP
  14. configure配置安装详解
  15. Unity 应用的消息推送《一》本地推送
  16. DETR系列大盘点 | 端到端Transformer目标检测算法汇总!
  17. 张五常和蒙代尔的对话
  18. 联想拯救者y7000充电一闪一闪,接触不良
  19. 【高等数学】加减关系下可以用等价无穷小替换的情况
  20. C语言的if语句!!!

热门文章

  1. Unity HDRP_No more space in the 2D Cookie Texture Atlas
  2. Java byte[]与List转换工具 | Java工具类
  3. python文件第三关
  4. java计算机毕业设计手机电子商城源码+系统+数据库+lw文档+mybatis+运行部署
  5. RHCOS设置允许远程登录
  6. 数据增强:随机HSV增强
  7. QDialog概率卡死问题
  8. ✔️连读(略读)规则:
  9. 关于二手车交易预测的数据探索性分析
  10. dell 620 服务器Linux,dell t620服务器安装linux系统