前面的文章直观的展示了,使用Spring Boot 集成 Hibernate 和手动集成 Hibernate 之间差距。
一个比喻
工作中使用过Spring Boot一段时间后,我越来越感觉到Spring Boot Starter带来的便利性。
使用手动集成 Hibernate, 就像去电脑城配电脑:
- 你不仅要找齐所有必备的部件,比如CPU、内存、主板、显卡等等:
- 你还要保证各个零部件是相互兼容的,比如太老的主板不支持某些显卡等等
这样导致,组装电脑的成本很大,费时费力!这和我们开发中手动集成某个模块非常类似。
但是如果使用 Spring Boot Starter,就像我们买电脑时,直接买笔记本电脑或者一体机。
用一个词形容就是 开箱即用。
Starter的依赖管理
Spring Boot Starter 是Spring Boot 中非常重要的概念,它是一种提供依赖项的方式,可以帮助开发人员快速集成各种第三方库和框架。
它应该包含两方面的内容:
- 依赖管理
- 自动配置
今天我们主要讨论的是其中的 依赖管理 部分。
前面博文说到,只要在在pom.xml中加一个依赖项,我们就几乎把持久层的所有依赖都自动加到我们的项目了(当然你还需要加数据库驱动):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
但是这是怎么做到的呢?今天我们就来一探究竟。
什么是 Maven POM
pom.xml 这个我们经常打交道的文件,今天我们来深入学习它。
POM ( Project Object Model,项目对象模型 ) 是 Maven 工程的基本工作单元,是一个XML文件,包含了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。
POM 中做很多很多事,这些事都是和项目构建相关的,比如:
- 声明和管理项目依赖
- 配置各种插件
- 执行目标
- 项目构建 profile
- 指定项目版本
当然我们最最常用的是声明和管理项目用到的各种依赖。
它的主要结构如下:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.companyname.project-group</groupId>
<artifactId>project</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
</dependencies>
</project>
这里只是列出了最核心的元素,也是和我们本文相关的。
pom.xml 文件详解请看这里
其中的 <dependencies>
是我们重点关注的对象,它定义了项目相关的所有依赖。
这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载(比如你配置了阿里云仓库,或者默认的maven中央仓库)。
什么是 Maven 依赖传递
想象一下,在很久很久以前,在没有Maven等构建工具时,我们要手动下载三方jar包,然后放到我们的项目的lib目录下。
如果这些三方的jar包是这种依赖关系时。
- 如果我们的项目用到了A包,那么我们需要手动下载A、B、C、D、E包到lib目录
- 如果我们项目用到了B包,那么我们需要手动下载B、C、E包到lib目录下
- ……
好在,Maven 引入了一个依赖传递传递机制,帮我们大大简化了这个问题。
有了这个机制,当我们项目中用到A.jar时,我们只需要在pom.xml的声明A,至于它依赖的其它jar包,都会被自动的依赖进来,包括它依赖的依赖。
当然传递依赖会引发一些问题,关于排除依赖等不在本文的范围。
Spring Boot Starter的依赖
通过学习上面的知识,我们就很容易理解为什么声明一个依赖,就会自动把所有的持久层依赖都自动加入进来了。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
平时我们声明其它依赖时,都需要指定版本,但是为什么可以不指定?因为默认不指定时,它会根据项目的父级依赖管理来确定依赖项的版本。
我们在pom.xml的上面部分可以看到父级项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
可以看到父级项目版本是3.2.4
, 所以相当于:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>3.2.4</version>
</dependency>
这个依赖我们可以按住ctrl键 加鼠标左键,可以跳转到它的pom.xml中去
这个pom.xml文件在你的本地的maven 仓库的某个目录下,比如:
这个包和普通我们依赖的包看上去并没有没什么区别。
要说最大的区别,就是它虽然是一个jar,但是并不包含java代码,在IDEA的依赖中可以看到,里面只有一些声明文件
这是因为,这个jar存在的唯一意义,就是定义一组依赖。
所以我们重点看 spring-boot-starter-data-jpa-3.2.4.pom
文件的 dependencies
:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>3.2.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>3.2.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.4.4.Final</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>3.2.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>6.1.5</version>
<scope>compile</scope>
</dependency>
</dependencies>
可以看到,它依赖5个包:
- spring-boot-starter-aop
- spring-boot-starter-jdbc
- hibernate-core
- spring-data-jpa
- spring-aspects
这五个包,前面两个也是 starter
,后面3个是普通的包。
然后这些依赖又会递归
的把它们的依赖包含进来。
最终的依赖图
根据pom.xml中的依赖传递,我们可以得到一个依赖关系图
是不是非常眼熟呢?对的,就是我们前文中贴出来的IDEA生成的依赖:
Spring Boot 做了什么
前面可以看到,定义一个spring-boot-starter-data-jpa
依赖就把我们持久层的所有依赖都搞定,其实是 maven 做到的,确切的说是maven的依赖传递机制完成的,并不是Spring Boot的新特性。
那么Spring Boot在这里做了什么呢?
其实它主要的是任务是打包,它按一般的场景划分成多个模块,然后定义每个模块下的一组依赖。就比如前面的 spring-boot-starter-data-jpa-3.2.4
它定义了:
- spring-boot-starter-aop-3.2.4
- spring-boot-starter-jdbc-3.2.4
- hibernate-core-6.4.4.Final
- spring-data-jpa-3.2.4
- spring-aspects-6.1.5
它不仅指示某个模块下,哪些依赖是必须的;
还指定了依赖具体的版本号。
这些版本的依赖都是经 Spring Boot 官方测试过的,我们可以放心的使用。
Spring Boot 官方提供的Starter
Spring Boot 官方提供了几十个开箱即用的Starter,几乎涵盖了所有项目常见的场景。
有了这些starter,你再也不用到处找演示文档了,不用再一个个配置必备的依赖了,也不用担心版本兼容问题。使用某个模块,直接使用这个模块的starter即可。
我们可以把这些starter 理解成套餐,大部分项目都会这么用spring-web, 这么用redis等等,Spring Boot已经帮我们打包好了,你直接享用即可。
1. 应用相关的Starter
Name | Description |
---|---|
spring-boot-starter | Core starter, including auto-configuration support, logging and YAML |
spring-boot-starter-activemq | Starter for JMS messaging using Apache ActiveMQ |
spring-boot-starter-amqp | Starter for using Spring AMQP and Rabbit MQ |
spring-boot-starter-aop | Starter for aspect-oriented programming with Spring AOP and AspectJ |
spring-boot-starter-artemis | Starter for JMS messaging using Apache Artemis |
spring-boot-starter-batch | Starter for using Spring Batch |
spring-boot-starter-cache | Starter for using Spring Framework’s caching support |
spring-boot-starter-data-cassandra | Starter for using Cassandra distributed database and Spring Data Cassandra |
spring-boot-starter-data-cassandra-reactive | Starter for using Cassandra distributed database and Spring Data Cassandra Reactive |
spring-boot-starter-data-couchbase | Starter for using Couchbase document-oriented database and Spring Data Couchbase |
spring-boot-starter-data-couchbase-reactive | Starter for using Couchbase document-oriented database and Spring Data Couchbase Reactive |
spring-boot-starter-data-elasticsearch | Starter for using Elasticsearch search and analytics engine and Spring Data Elasticsearch |
spring-boot-starter-data-jdbc | Starter for using Spring Data JDBC |
spring-boot-starter-data-jpa | Starter for using Spring Data JPA with Hibernate |
spring-boot-starter-data-ldap | Starter for using Spring Data LDAP |
spring-boot-starter-data-mongodb | Starter for using MongoDB document-oriented database and Spring Data MongoDB |
spring-boot-starter-data-mongodb-reactive | Starter for using MongoDB document-oriented database and Spring Data MongoDB Reactive |
spring-boot-starter-data-neo4j | Starter for using Neo4j graph database and Spring Data Neo4j |
spring-boot-starter-data-r2dbc | Starter for using Spring Data R2DBC |
spring-boot-starter-data-redis | Starter for using Redis key-value data store with Spring Data Redis and the Lettuce client |
spring-boot-starter-data-redis-reactive | Starter for using Redis key-value data store with Spring Data Redis reactive and the Lettuce client |
spring-boot-starter-data-rest | Starter for exposing Spring Data repositories over REST using Spring Data REST and Spring MVC |
spring-boot-starter-freemarker | Starter for building MVC web applications using FreeMarker views |
spring-boot-starter-graphql | Starter for building GraphQL applications with Spring GraphQL |
spring-boot-starter-groovy-templates | Starter for building MVC web applications using Groovy Templates views |
spring-boot-starter-hateoas | Starter for building hypermedia-based RESTful web application with Spring MVC and Spring HATEOAS |
spring-boot-starter-integration | Starter for using Spring Integration |
spring-boot-starter-jdbc | Starter for using JDBC with the HikariCP connection pool |
spring-boot-starter-jersey | Starter for building RESTful web applications using JAX-RS and Jersey. An alternative to spring-boot-starter-web |
spring-boot-starter-jooq | Starter for using jOOQ to access SQL databases with JDBC. An alternative to spring-boot-starter-data-jpa or spring-boot-starter-jdbc |
spring-boot-starter-json | Starter for reading and writing json |
spring-boot-starter-mail | Starter for using Java Mail and Spring Framework’s email sending support |
spring-boot-starter-mustache | Starter for building web applications using Mustache views |
spring-boot-starter-oauth2-authorization-server | Starter for using Spring Authorization Server features |
spring-boot-starter-oauth2-client | Starter for using Spring Security’s OAuth2/OpenID Connect client features |
spring-boot-starter-oauth2-resource-server | Starter for using Spring Security’s OAuth2 resource server features |
spring-boot-starter-pulsar | Starter for using Spring for Apache Pulsar |
spring-boot-starter-pulsar-reactive | Starter for using Spring for Apache Pulsar Reactive |
spring-boot-starter-quartz | Starter for using the Quartz scheduler |
spring-boot-starter-rsocket | Starter for building RSocket clients and servers |
spring-boot-starter-security | Starter for using Spring Security |
spring-boot-starter-test | Starter for testing Spring Boot applications with libraries including JUnit Jupiter, Hamcrest and Mockito |
spring-boot-starter-thymeleaf | Starter for building MVC web applications using Thymeleaf views |
spring-boot-starter-validation | Starter for using Java Bean Validation with Hibernate Validator |
spring-boot-starter-web | Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container |
spring-boot-starter-web-services | Starter for using Spring Web Services |
spring-boot-starter-webflux | Starter for building WebFlux applications using Spring Framework’s Reactive Web support |
spring-boot-starter-websocket | Starter for building WebSocket applications using Spring Framework’s MVC WebSocket support |
2. 生产相关的starter
Name | Description |
---|---|
spring-boot-starter-actuator | Starter for using Spring Boot’s Actuator which provides production-ready features to help you monitor and manage your application |
3. 技术相关的starter
Name | Description |
---|---|
spring-boot-starter-jetty | Starter for using Jetty as the embedded servlet container. An alternative to spring-boot-starter-tomcat |
spring-boot-starter-log4j2 | Starter for using Log4j2 for logging. An alternative to spring-boot-starter-logging |
spring-boot-starter-logging | Starter for logging using Logback. Default logging starter |
spring-boot-starter-reactor-netty | Starter for using Reactor Netty as the embedded reactive HTTP server. |
spring-boot-starter-tomcat | Starter for using Tomcat as the embedded servlet container. Default servlet container starter used by spring-boot-starter-web |
spring-boot-starter-undertow | Starter for using Undertow as the embedded servlet container. An alternative to spring-boot-starter-tomcat |
总结
通过本文,我们深入学习了 Spring Boot Starter 依赖管理背后的 Maven的传递依赖机制是如何工作的,以及 Spring Boot 提供了哪些开箱即用的starter。
这是Spring Boot 系列专栏的第5篇,下一篇我们将深入学习Spring Boot的自动配置,关注我,和我一起学透 Spring Boot.