章节 III. 使用 Spring Boot

本节将详细介绍如何使用 Spring Boot。它涵盖了构建系统、自动配置以及如何运行应用等主题。我们还介绍了一些 Spring Boot 的最佳实践。虽然 Spring Boot 没有什么特别的东西(它只是另一个你可以使用的库),但接下来的一些建议可以让你的开发过程更简单一点。

如果你刚开始使用 Spring Boot,那么在进入本节之前应该先阅读 新手入门 部分。

13. 构建系统

强烈建议你选择一个支持 依赖管理 并能使用 “Maven Central” 仓库中发布的构件的构建系统。我们建议你选择 Maven 或 Gradle。Spring Boot 也可以与其它构建系统(例如 Ant)协同工作,但它们不会得到很好的支持。

13.1 依赖管理

Spring Boot 每一个发布版本都会提供它支持的依赖列表。实际应用时,在你的构建配置中不需要提供这些依赖的版本,因为 Spring Boot 会帮你进行管理。当你升级 Spring Boot 时,这些依赖也会随之进行升级。

[Note] Note

如果有必要的话,你仍可以指定一个版本并覆盖 Spring Boot 的建议。

精选列表包含了所有你在 Spring Boot 中可以使用的 Spring 模块以及精选的第三方库列表。这个列表可以作为一个标准的 材料清单 (spring-boot-dependencies),它们在 Maven 和 Gradle 都是可用。

[Warning] Warning

Spring Boot 的每个发行版本都与 Spring Framework 的基本版本相关联,因此我们强烈建议你不要自行指定它的版本。

13.2 Maven

Maven 用户可以继承 spring-boot-starter-parent 工程来获得合理的默认配置。父工程提供了下面的特性:

  • Java 1.8 为默认的编译级别。
  • UTF-8 源码编码。
  • 从 spring-boot-dependencies pom 继承的 依赖管理部分,它管理着公用依赖的版本信息。这种依赖管理允许你忽略 pom 中依赖的 <version> 标签。
  • 合理的 资源过滤。
  • 合理的插件配置(exec plugin、Git commit ID 和 shade)。
  • 对有特定格式的 application.properties 和 application.yml 配置文件进行合理的资源过滤(例如,application-dev.properties 和 application-dev.yml)。

需要注意的是,由于 application.properties 和 application.yml 文件采用了 Spring 风格的占位符 (${…​}),Maven 过滤则改成了使用 @..@ 占位符(你可以使用 Maven 属性 resource.delimiter 来覆盖)。

13.2.1 继承父启动器

若要将项目配置为继承 spring-boot-starter-parent,请将 parent 设置如下:

<!-- Inherit defaults from Spring Boot -->
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.1.0.BUILD-SNAPSHOT</version>
</parent>
[Note] Note

你只需要在这个依赖中指定 Spring Boot 的版本号。当你导入其它的启动器时可以安全地忽略版本号。

使用这个设置,你也可以通过在自己项目中重写一个属性来覆盖单个依赖项。例如,为了升级到 Spring Data 的另一个发行版本,你将需要在你的 pom.xml 中添加以下内容:

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

支持的属性清单请查看 spring-boot-dependencies pom。

13.2.2 不继承父 POM 使用 Spring Boot

不是每个人都喜欢继承 spring-boot-starter-parent POM。你可能需要使用公司标准的父 POM,或者你可能更喜欢明确地声明所有 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.0.BUILD-SNAPSHOT</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

这个设置不允许你使用上面阐述的属性来重写单个依赖项。为了达到同样的效果,你需要在项目的 dependencyManagement 中的 spring-boot-dependencies 入口之前添加一个入口。例如,为了升级到 Spring Data 的另一个发行版本,你将需要在你的 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>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-dependencies</artifactId>
			<version>2.1.0.BUILD-SNAPSHOT</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>
[Note] Note

在上面的例子中,我们指定了一个 BOM,但是任何类型的依赖都可以用这种方式重写。

13.2.3 使用 Spring Boot Maven 插件

Spring Boot 包含了一个 Maven 插件,这个插件可以将项目打包为一个可执行的 jar 包。如果你想使用它的话,将它添加到你的 <plugins> 部分,如下面示例所示:

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>
[Note] Note

如果你使用的是 Spring Boot 的父启动器 pom,那么只需添加插件,并不需要配置它,除非你想更改父 POM 中定义的设置。

13.3 Gradle

学习如何在 Gradle 中使用 Spring Boot,请参阅 Spring Boot 的 Gradle 插件相关文档。

  • 参考文档 (HTML 和 PDF)
  • API

13.4 Ant

使用 Apache Ant+Ivy 来创建一个 Spring Boot 项目是可能的。spring-boot-antlib “AntLib” 模块也可以用来帮助 Ant 创建可执行的 jar。

为了声明依赖,一个典型的 ivy.xml 文件看起来就像这样:

<ivy-module version="2.0">
	<info organisation="org.springframework.boot" module="spring-boot-sample-ant" />
	<configurations>
		<conf name="compile" description="everything needed to compile this module" />
		<conf name="runtime" extends="compile" description="everything needed to run this module" />
	</configurations>
	<dependencies>
		<dependency org="org.springframework.boot" name="spring-boot-starter"
			rev="${spring-boot.version}" conf="compile" />
	</dependencies>
</ivy-module>

一个典型的 build.xml 看起来会像这样:

<project
	xmlns:ivy="antlib:org.apache.ivy.ant"
	xmlns:spring-boot="antlib:org.springframework.boot.ant"
	name="myapp" default="build">

	<property name="spring-boot.version" value="2.1.0.BUILD-SNAPSHOT" />

	<target name="resolve" description="--> retrieve dependencies with ivy">
		<ivy:retrieve pattern="lib/[conf]/[artifact]-[type]-[revision].[ext]" />
	</target>

	<target name="classpaths" depends="resolve">
		<path id="compile.classpath">
			<fileset dir="lib/compile" includes="*.jar" />
		</path>
	</target>

	<target name="init" depends="classpaths">
		<mkdir dir="build/classes" />
	</target>

	<target name="compile" depends="init" description="compile">
		<javac srcdir="src/main/java" destdir="build/classes" classpathref="compile.classpath" />
	</target>

	<target name="build" depends="compile">
		<spring-boot:exejar destfile="build/myapp.jar" classes="build/classes">
			<spring-boot:lib>
				<fileset dir="lib/runtime" />
			</spring-boot:lib>
		</spring-boot:exejar>
	</target>
</project>
[Tip] Tip

如果你不想使用 spring-boot-antlib 模块,请查看 章节 88.9, “使用 Ant 而不使用 spring-boot-antlib 编译可执行文件” “How-to”。

13.5 启动器

启动器是一系列你可以包含进自己应用中的实用依赖描述符。你可以得到所有 Spring 和你需要的相关技术的一站式服务,而无需查找示例代码和复制粘贴的依赖描述符。例如,如果你想开始使用 Spring 和 JPA 来进行数据库链接,只需要在你的工程中包含 spring-boot-starter-data-jpa 依赖,你便可以很好的前行了。

启动器包含许多你需要启动并快速运行一个工程的依赖,并持续支持一系列管理传递的依赖。

名称中有什么

所有官方的启动器都有一个类似的命名模式:spring-boot-starter-*,*是应用的特性类型。这个命名结构用来在你需要时帮助你发现一个启动器。Maven 在许多 IDE 中进行了集成,允许你通过名字来搜索依赖。例如,安装了合适的 Eclipse 或 STS 插件,你可以简单的在 POM 编辑器中点击 ctrl-space 并输入 “spring-boot-starter” 来查找一个完整的列表。

正如在“创建你自己的启动器”部分讲述的那样,第三方启动器不应该以 spring-boot 开始,因为它是预留给官方 Spring Boot 构建的。第三方名为 thirdpartyproject 的启动器通常命名为 thirdpartyproject-spring-boot-starter。

下面的应用启动器由 Spring Boot 提供,在 org.springframework.boot 组下:

表格 13.1. Spring Boot 应用的启动器

名称 描述 Pom

spring-boot-starter

核心启动器, 包含自动配置支持,日志和 YAML

Pom

spring-boot-starter-activemq

使用 Apache ActiveMQ 的 JMS 消息的启动器

Pom

spring-boot-starter-amqp

使用 Spring AMQP 和 Rabbit MQ 的启动器

Pom

spring-boot-starter-aop

使用 Spring AOP 和 AspectJ 面向切面编程的启动器

Pom

spring-boot-starter-artemis

使用 Apache Artemis 的 JMS 消息的启动器

Pom

spring-boot-starter-batch

使用 Spring Batch 的启动器

Pom

spring-boot-starter-cache

使用 Spring Framework 缓存支持的启动器

Pom

spring-boot-starter-cloud-connectors

使用 Spring Cloud Connectors 以简化连接到像 Cloud Foundry 和 Heroku 的云平台的启动器

Pom

spring-boot-starter-data-cassandra

使用 Cassandra 分布式数据库和 Spring Data Cassandra 的启动器

Pom

spring-boot-starter-data-cassandra-reactive

使用 Cassandra 分布式数据库和 Spring Data Cassandra Reactive 的启动器

Pom

spring-boot-starter-data-couchbase

使用 Couchbase 面向文档数据库和 Spring Data Couchbase 的启动器

Pom

spring-boot-starter-data-couchbase-reactive

使用 Couchbase 面向文档数据库和 Spring Data Couchbase Reactive 的启动器

Pom

spring-boot-starter-data-elasticsearch

使用 Elasticsearch 搜索与分析引擎和 Spring Data Elasticsearch 的启动器

Pom

spring-boot-starter-data-jdbc

使用 Spring Data JDBC 的启动器

Pom

spring-boot-starter-data-jpa

使用 Spring Data JPA 与 Hibernate 的启动器

Pom

spring-boot-starter-data-ldap

使用 Spring Data LDAP 的启动器

Pom

spring-boot-starter-data-mongodb

使用 MongoDB 面向文档数据库和 Spring Data MongoDB 的启动器

Pom

spring-boot-starter-data-mongodb-reactive

使用 MongoDB 面向文档数据库和 Spring Data MongoDB Reactive 的启动器

Pom

spring-boot-starter-data-neo4j

使用 Neo4j 图形数据库和 Spring Data Neo4j 的启动器

Pom

spring-boot-starter-data-redis

使用 Redis 键值数据存储与 Spring Data Redis 和 Jedis client 的启动器

Pom

spring-boot-starter-data-redis-reactive

使用 Redis 键值数据存储与 Spring Data Redis reactive 和 Lettuce client 的启动器

Pom

spring-boot-starter-data-rest

使用 Spring Data REST 将 Spring Data 仓库放在 REST 上的启动器

Pom

spring-boot-starter-data-solr

使用 Apache Solr 搜索平台与 Spring Data Solr 的启动器

Pom

spring-boot-starter-freemarker

使用 FreeMarker 视图构建 MVC web 应用的启动器

Pom

spring-boot-starter-groovy-templates

使用 Groovy 模版视图构建 MVC web 应用的启动器

Pom

spring-boot-starter-hateoas

使用 Spring MVC 和 Spring HATEOAS 构建基于超媒体的 RESTful web 应用的启动器

Pom

spring-boot-starter-integration

使用 Spring Integration 的启动器

Pom

spring-boot-starter-jdbc

使用 JDBC 与 HikariCP 连接池的启动器

Pom

spring-boot-starter-jersey

使用 JAX-RS 和 Jersey 构建 RESTful web 应用的启动器。一种 spring-boot-starter-web 的替代方案

Pom

spring-boot-starter-jooq

使用 jOOQ 访问 SQL 数据库的启动器。一种 spring-boot-starter-data-jpa 或 spring-boot-starter-jdbc 的替代方案

Pom

spring-boot-starter-json

读写 json 的启动器

Pom

spring-boot-starter-jta-atomikos

使用 Atomikos 的 JTA 事务的启动器

Pom

spring-boot-starter-jta-bitronix

使用 Bitronix 的 JTA 事务的启动器

Pom

spring-boot-starter-mail

使用 Java Mail 和 Spring Framework 的邮件发送支持的启动器

Pom

spring-boot-starter-mustache

使用 Mustache 视图构建 web 应用的启动器

Pom

spring-boot-starter-oauth2-oidc-client

使用 Spring Security 的 OAuth2/OpenID 连接客户端特性的启动器

Pom

spring-boot-starter-quartz

使用 Quartz scheduler 的启动器

Pom

spring-boot-starter-security

使用 Spring Security 的启动器

Pom

spring-boot-starter-test

使用一些库(包含 JUnit, Hamcrest 和 Mockito)测试 Spring Boot 应用的启动器

Pom

spring-boot-starter-thymeleaf

使用 Thymeleaf 视图构建 MVC web 应用的启动器

Pom

spring-boot-starter-validation

使用 Java Bean Validation 与 Hibernate Validator 的启动器

Pom

spring-boot-starter-web

使用 Spring MVC 构建 web(包含 RESTful)应用的启动器. 使用 Tomcat 作为默认的嵌入式容器

Pom

spring-boot-starter-web-services

使用 Spring Web Services 的启动器

Pom

spring-boot-starter-webflux

使用 Spring Framework 的 Reactive Web 支持构建 WebFlux 应用的启动器

Pom

spring-boot-starter-websocket

使用 Spring Framework 的 WebSocket 支持构建 WebSocket 应用的启动器

Pom


除了应用启动器之外,下面的启动器可以用来添加 生产就绪 特性:

表格 13.2. Spring Boot 生产启动器

名称 描述 Pom

spring-boot-starter-actuator

使用 Spring Boot 的执行器的启动器,它提供的生产就绪特性帮助你监视和管理应用

Pom


最后,如果你想排除或切换特定技术方面,Spring Boot 也包括一些可以使用的启动器:

表格 13.3. Spring Boot 技术启动器

名称 描述 Pom

spring-boot-starter-jetty

使用 Jetty 做为嵌入式 servlet 容器的启动器。一种 spring-boot-starter-tomcat 的替代方案

Pom

spring-boot-starter-log4j2

使用 Log4j2 日志服务的启动器。一种 spring-boot-starter-logging的替代方案

Pom

spring-boot-starter-logging

使用 Logback 日志服务的启动器。默认日志启动器

Pom

spring-boot-starter-reactor-netty

使用 Reactor Netty 做为嵌入式响应式 HTTP 服务器的启动器。

Pom

spring-boot-starter-tomcat

使用 Tomcat 做为嵌入式 servlet 容器的启动器。使用 spring-boot-starter-web 的默认 servlet 容器的启动器

Pom

spring-boot-starter-undertow

使用 Undertow 做为嵌入式 servlet 容器的启动器。一种 spring-boot-starter-tomcat 的替代方案

Pom


[Tip] Tip

对于额外的社区共享的启动器列表,请参阅 GitHub 上 spring-boot-starters 模块的 README 文件。

14. 组织代码

Spring Boot 工作时不要求任何特定的代码布局。但是,有一些最佳实践是很有帮助的。

14.1 使用 “default” 包

当一个类不包含 package 声明时,它被当作是在 “default package” 中,通常情况下不建议使用 “default package”,应该避免使用它。当 Spring Boot 应用使用 @ComponentScan、@EntityScan 或 @SpringBootApplication 注解时,它会引起一些特别的问题,因为 Spring Boot 会读取每个 jar 中的每个类。

[Tip] Tip

我们建议你遵循 Java 推荐的包命名规范,使用一个反转域名命名(例如,com.example.project)。

14.2 定位应用主方法

我们一般建议你将应用主类放在其它类之上的根包中。@SpringBootApplication 注解往往是放在你的主类中,它隐含地定义了一些项目的基础 “search package”。例如,如果你正在写一个 JPA 应用,@SpringBootApplication 注解的类所在的包将被用来搜索 @Entity 项。使用根包也允许只在你的项目上进行组件扫描。

[Tip] Tip

如果你不想使用 @SpringBootApplication、@EnableAutoConfiguration 和 @ComponentScan 注解,它们也定义了相同的导入定义,你可以使用它们来替代。

下面是一个典型的布局:

com
 +- example
     +- myapplication
         +- Application.java
         |
         +- customer
         |   +- Customer.java
         |   +- CustomerController.java
         |   +- CustomerService.java
         |   +- CustomerRepository.java
         |
         +- order
             +- Order.java
             +- OrderController.java
             +- OrderService.java
             +- OrderRepository.java

Application.java 文件将声明主方法,以及基本的 @SpringBootApplication,如下:

package com.example.myapplication;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

}