本节将更详细地介绍如何使用 Spring Boot。它涵盖了构建系统、自动配置以及如何运行应用程序等主题。我们还介绍了一些 Spring Boot 最佳实践。尽管 Spring Boot 没有什么特别之处(它只是您可以使用的另一个库),但有一些建议,如果遵循这些建议,将使您的开发过程变得更容易一些。

如果您开始使用 Spring Boot,您可能应该在深入本节之前阅读入门指南。

1. 构建系统

强烈建议您选择支持依赖关系管理并且可以使用发布到“Maven Central”存储库的工件的构建系统。我们建议您选择 Maven 或 Gradle。Spring Boot 可以与其他构建系统(例如 Ant)一起使用,但它们并没有得到很好的支持。

1.1. 依赖管理

Spring Boot 的每个版本都提供了它支持的依赖项的精选列表。实际上,您不需要在构建配置中为任何这些依赖项提供版本,因为 Spring Boot 会为您管理它。当您升级 Spring Boot 本身时,这些依赖项也会以一致的方式升级。

如果需要,您仍然可以指定版本并覆盖 Spring Boot 的建议。

精选列表包含可与 Spring Boot 一起使用的所有 Spring 模块以及第三方库的精炼列表。该列表作为标准物料清单 (Bill of Materials) 提供,可与MavenGradlespring-boot-dependencies一起使用。

Spring Boot 的每个版本都与 Spring 框架的基本版本相关联。我们强烈建议您不要指定其版本。

1.2. 梅文

要了解如何将 Spring Boot 与 Maven 结合使用,请参阅 Spring Boot 的 Maven 插件的文档:

1.3. 摇篮

要了解如何将 Spring Boot 与 Gradle 结合使用,请参阅 Spring Boot 的 Gradle 插件的文档:

1.4. 蚂蚁

可以使用 Apache Ant+Ivy 构建 Spring Boot 项目。“AntLib”模块spring-boot-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="3.1.5" />

    <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>
如果您不想使用该spring-boot-antlib模块,请参阅howto.html “操作方法”。

1.5. 初学者

Starters 是一组方便的依赖描述符,您可以将其包含在应用程序中。您可以获得所需的所有 Spring 和相关技术的一站式商店,而无需寻找示例代码和复制粘贴依赖描述符负载。例如,如果您想开始使用 Spring 和 JPA 进行数据库访问,请spring-boot-starter-data-jpa在项目中包含依赖项。

启动器包含许多使项目快速启动和运行所需的依赖项,并具有一致的、受支持的托管传递依赖项集。

名字里有什么

所有正式启动器都遵循类似的命名模式;spring-boot-starter-*,其中*是特定类型的应用程序。这种命名结构旨在帮助您找到入门者。许多 IDE 中的 Maven 集成允许您按名称搜索依赖项。例如,安装了适当的 Eclipse 或 Spring Tools 插件后,您可以ctrl-space在 POM 编辑器中按 并键入“spring-boot-starter”以获得完整列表。

正如“创建您自己的启动器”部分中所述,第三方启动器不应以 开头spring-boot,因为它是为官方 Spring Boot 工件保留的。相反,第三方启动器通常以项目名称开头。例如,名为 的第三方启动项目thirdpartyproject通常会命名为thirdpartyproject-spring-boot-starter

Spring Boot 在该组下提供了以下应用程序启动器org.springframework.boot

表 1. Spring Boot 应用程序启动器
姓名 描述

spring-boot-starter

核心启动器,包括自动配置支持、日志记录和 YAML

spring-boot-starter-activemq

使用 Apache ActiveMQ 的 JMS 消息传递入门

spring-boot-starter-amqp

使用 Spring AMQP 和 Rabbit MQ 的入门程序

spring-boot-starter-aop

使用 Spring AOP 和 AspectJ 进行面向方面编程的入门程序

spring-boot-starter-artemis

使用 Apache Artemis 的 JMS 消息传递入门程序

spring-boot-starter-batch

使用 Spring Batch 的启动器

spring-boot-starter-cache

使用 Spring 框架的缓存支持的入门程序

spring-boot-starter-data-cassandra

使用 Cassandra 分布式数据库和 Spring Data Cassandra 的入门程序

spring-boot-starter-data-cassandra-reactive

使用 Cassandra 分布式数据库和 Spring Data Cassandra Reactive 的入门程序

spring-boot-starter-data-couchbase

使用 Couchbase 面向文档的数据库和 Spring Data Couchbase 的入门程序

spring-boot-starter-data-couchbase-reactive

使用 Couchbase 面向文档的数据库和 Spring Data Couchbase Reactive 的入门程序

spring-boot-starter-data-elasticsearch

使用 Elasticsearch 搜索和分析引擎以及 Spring Data Elasticsearch 的入门程序

spring-boot-starter-data-jdbc

使用 Spring Data JDBC 的入门程序

spring-boot-starter-data-jpa

将 Spring Data JPA 与 Hibernate 结合使用的入门程序

spring-boot-starter-data-ldap

使用 Spring Data LDAP 的入门程序

spring-boot-starter-data-mongodb

使用 MongoDB 面向文档的数据库和 Spring Data MongoDB 的入门程序

spring-boot-starter-data-mongodb-reactive

使用 MongoDB 面向文档的数据库和 Spring Data MongoDB Reactive 的入门程序

spring-boot-starter-data-neo4j

使用 Neo4j 图形数据库和 Spring Data Neo4j 的入门程序

spring-boot-starter-data-r2dbc

使用 Spring Data R2DBC 的入门程序

spring-boot-starter-data-redis

通过 Spring Data Redis 和 Lettuce 客户端使用 Redis 键值数据存储的入门程序

spring-boot-starter-data-redis-reactive

使用 Redis 键值数据存储与 Spring Data Redis 反应式和 Lettuce 客户端的入门程序

spring-boot-starter-data-rest

使用 Spring Data REST 和 Spring MVC 通过 REST 公开 Spring Data 存储库的入门程序

spring-boot-starter-freemarker

使用 FreeMarker 视图构建 MVC Web 应用程序的入门程序

spring-boot-starter-graphql

使用 Spring GraphQL 构建 GraphQL 应用程序的入门程序

spring-boot-starter-groovy-templates

使用 Groovy 模板视图构建 MVC Web 应用程序的入门程序

spring-boot-starter-hateoas

使用 Spring MVC 和 Spring HATEOAS 构建基于超媒体的 RESTful Web 应用程序的入门程序

spring-boot-starter-integration

使用 Spring Integration 的入门程序

spring-boot-starter-jdbc

将 JDBC 与 HikariCP 连接池结合使用的入门程序

spring-boot-starter-jersey

使用 JAX-RS 和 Jersey 构建 RESTful Web 应用程序的入门程序。替代方案spring-boot-starter-web

spring-boot-starter-jooq

使用 jOOQ 通过 JDBC 访问 SQL 数据库的入门程序。spring-boot-starter-data-jpa或 的替代方案spring-boot-starter-jdbc

spring-boot-starter-json

读取和写入 json 的 Starter

spring-boot-starter-mail

使用 Java Mail 和 Spring Framework 的电子邮件发送支持的入门程序

spring-boot-starter-mustache

使用 Mustache 视图构建 Web 应用程序的入门程序

spring-boot-starter-oauth2-authorization-server

使用 Spring 授权服务器功能的入门程序

spring-boot-starter-oauth2-client

使用 Spring Security 的 OAuth2/OpenID Connect 客户端功能的入门程序

spring-boot-starter-oauth2-resource-server

使用 Spring Security 的 OAuth2 资源服务器功能的入门程序

spring-boot-starter-quartz

使用 Quartz 调度程序的入门程序

spring-boot-starter-rsocket

用于构建 RSocket 客户端和服务器的 Starter

spring-boot-starter-security

使用 Spring Security 的入门程序

spring-boot-starter-test

用于使用 JUnit Jupiter、Hamcrest 和 Mockito 等库测试 Spring Boot 应用程序的 Starter

spring-boot-starter-thymeleaf

使用 Thymeleaf 视图构建 MVC Web 应用程序的入门程序

spring-boot-starter-validation

使用 Hibernate Validator 进行 Java Bean 验证的入门指南

spring-boot-starter-web

用于使用 Spring MVC 构建 Web(包括 RESTful)应用程序的入门程序。使用Tomcat作为默认的嵌入式容器

spring-boot-starter-web-services

使用 Spring Web 服务的入门程序

spring-boot-starter-webflux

使用 Spring Framework 的 Reactive Web 支持构建 WebFlux 应用程序的入门程序

spring-boot-starter-websocket

使用 Spring Framework 的 MVC WebSocket 支持构建 WebSocket 应用程序的入门程序

除了应用程序启动器之外,还可以使用以下启动器来添加生产就绪功能:

表 2. Spring Boot 生产启动器
姓名 描述

spring-boot-starter-actuator

使用 Spring Boot 的 Actuator 的入门程序,它提供生产就绪的功能来帮助您监视和管理应用程序

最后,Spring Boot 还包括以下启动器,如果您想排除或交换特定的技术方面,可以使用它们:

表 3. Spring Boot 技术入门
姓名 描述

spring-boot-starter-jetty

使用 Jetty 作为嵌入式 servlet 容器的入门程序。替代方案spring-boot-starter-tomcat

spring-boot-starter-log4j2

使用 Log4j2 进行日志记录的入门程序。替代方案spring-boot-starter-logging

spring-boot-starter-logging

使用 Logback 进行日志记录的启动器。默认日志记录启动器

spring-boot-starter-reactor-netty

使用 Reactor Netty 作为嵌入式反应式 HTTP 服务器的入门程序。

spring-boot-starter-tomcat

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

spring-boot-starter-undertow

使用 Undertow 作为嵌入式 servlet 容器的入门程序。替代方案spring-boot-starter-tomcat

有关其他社区贡献的入门者的列表,请参阅GitHub 上模块 中的自述文件。spring-boot-starters

2. 构建代码

Spring Boot 不需要任何特定的代码布局即可工作。不过,有一些最佳实践可以提供帮助。

2.1. 使用“默认”包

当一个类不包含package声明时,它被认为位于“默认包”中。通常不鼓励并且应该避免使用“默认包”。对于使用@ComponentScan@ConfigurationPropertiesScan@EntityScan@SpringBootApplication注释的 Spring Boot 应用程序,它可能会导致特定问题,因为每个 jar 中的每个类都会被读取。

我们建议您遵循 Java 推荐的包命名约定并使用反向域名(例如com.example.project)。

2.2. 找到主应用程序类

我们通常建议您将主应用程序类放在根包中其他类之上。该@SpringBootApplication注释通常放置在您的主类上,它隐式地定义了某些项目的基本“搜索包”。例如,如果您正在编写 JPA 应用程序,@SpringBootApplication则使用带注释的类的包来搜索@Entity项目。使用根包还允许组件扫描仅应用于您的项目。

如果您不想使用@SpringBootApplication,它导入的 @EnableAutoConfiguration和注释定义了该行为,因此您也可以使用它们。@ComponentScan

以下清单显示了典型的布局:

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

MyApplication.java文件将声明该main方法以及 basic @SpringBootApplication,如下所示:

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

@SpringBootApplication
public class MyApplication {

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

}
Kotlin
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class MyApplication

fun main(args: Array<String>) {
    runApplication<MyApplication>(*args)
}

3. 配置类

Spring Boot 支持基于 Java 的配置。尽管可以使用SpringApplicationXML 源,但我们通常建议您的主要源是单个@Configuration类。通常,定义该方法的类main是作为主要类的良好候选者@Configuration

互联网上已经发布了许多使用 XML 配置的 Spring 配置示例。如果可能,请始终尝试使用等效的基于 Java 的配置。搜索Enable*注释可能是一个很好的起点。

3.1. 导入附加配置类

您无需将所有内容都@Configuration放入一个类中。该@Import注释可用于导入其他配置类。或者,您可以使用@ComponentScan自动获取所有 Spring 组件,包括@Configuration类。

3.2. 导入 XML 配置

如果您绝对必须使用基于 XML 的配置,我们建议您仍然从@Configuration类开始。然后,您可以使用@ImportResource注释来加载 XML 配置文件。

4. 自动配置

Spring Boot 自动配置尝试根据您添加的 jar 依赖项自动配置您的 Spring 应用程序。例如,如果HSQLDB位于您的类路径中,并且您尚未手动配置任何数据库连接 Bean,则 Spring Boot 会自动配置内存数据库。

您需要通过向您的类之一添加@EnableAutoConfiguration或注释来选择自动配置。@SpringBootApplication@Configuration

您应该只添加一个@SpringBootApplication@EnableAutoConfiguration注释。我们通常建议您仅将其中之一添加到您的主要@Configuration课程中。

4.1. 逐步取代自动配置

自动配置是非侵入性的。您可以随时开始定义自己的配置来替换自动配置的特定部分。例如,如果您添加自己的DataSourcebean,则默认的嵌入式数据库支持将消失。

如果您需要了解当前正在应用什么自动配置以及原因,请使用开关启动您的应用程序--debug。这样做可以启用所选核心记录器的调试日志,并将条件报告记录到控制台。

4.2. 禁用特定的自动配置类

如果您发现正在应用您不想要的特定自动配置类,您可以使用 的排除属性@SpringBootApplication来禁用它们,如以下示例所示:

Java
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class MyApplication {

}
Kotlin
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

@SpringBootApplication(exclude = [DataSourceAutoConfiguration::class])
class MyApplication

如果该类不在类路径上,则可以使用excludeName注释的属性并指定完全限定名称。如果您更喜欢使用@EnableAutoConfiguration而不是@SpringBootApplicationexcludeexcludeName也可用。最后,您还可以使用 属性控制要排除的自动配置类的列表spring.autoconfigure.exclude

您可以在注释级别和使用属性来定义排除。
尽管自动配置类是public,但该类被视为公共 API 的唯一方面是可用于禁用自动配置的类的名称。这些类的实际内容(例如嵌套配置类或 bean 方法)仅供内部使用,我们不建议直接使用它们。

5. Spring Bean 和依赖注入

您可以自由地使用任何标准 Spring 框架技术来定义您的 bean 及其注入的依赖项。我们通常建议使用构造函数注入来连接依赖项并@ComponentScan查找 bean。

如果您按照上面的建议构建代码(将应用程序类定位在顶级包中),则可以在@ComponentScan不添加任何参数的情况下添加或使用@SpringBootApplication隐式包含它的注释。您的所有应用程序组件(@Component@Service@Repository@Controller和其他)都会自动注册为 Spring Bean。

以下示例显示了@Service使用构造函数注入来获取所需RiskAssessorbean 的 Bean:

Java
import org.springframework.stereotype.Service;

@Service
public class MyAccountService implements AccountService {

    private final RiskAssessor riskAssessor;

    public MyAccountService(RiskAssessor riskAssessor) {
        this.riskAssessor = riskAssessor;
    }

    // ...

}
Kotlin
import org.springframework.stereotype.Service

@Service
class MyAccountService(private val riskAssessor: RiskAssessor) : AccountService

如果一个 bean 有多个构造函数,您需要标记您希望 Spring 使用的构造函数@Autowired

Java
import java.io.PrintStream;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyAccountService implements AccountService {

    private final RiskAssessor riskAssessor;

    private final PrintStream out;

    @Autowired
    public MyAccountService(RiskAssessor riskAssessor) {
        this.riskAssessor = riskAssessor;
        this.out = System.out;
    }

    public MyAccountService(RiskAssessor riskAssessor, PrintStream out) {
        this.riskAssessor = riskAssessor;
        this.out = out;
    }

    // ...

}
Kotlin
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.io.PrintStream

@Service
class MyAccountService : AccountService {

    private val riskAssessor: RiskAssessor

    private val out: PrintStream

    @Autowired
    constructor(riskAssessor: RiskAssessor) {
        this.riskAssessor = riskAssessor
        out = System.out
    }

    constructor(riskAssessor: RiskAssessor, out: PrintStream) {
        this.riskAssessor = riskAssessor
        this.out = out
    }

    // ...

}
请注意如何使用构造函数注入将riskAssessor字段标记为final,表示随后无法对其进行更改。

6.使用@SpringBootApplication注解

许多 Spring Boot 开发人员喜欢他们的应用程序使用自动配置、组件扫描并能够在其“应用程序类”上定义额外的配置。可以使用单个@SpringBootApplication注释来启用这三个功能,即:

  • @EnableAutoConfiguration:启用Spring Boot的自动配置机制

  • @ComponentScan@Component对应用程序所在的包启用扫描(请参阅最佳实践

  • @SpringBootConfiguration:允许在上下文中注册额外的bean或导入额外的配置类。Spring 标准的替代方案@Configuration,有助于集成测试中的配置检测。

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

// Same as @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
@SpringBootApplication
public class MyApplication {

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

}
Kotlin
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

// same as @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
@SpringBootApplication
class MyApplication

fun main(args: Array<String>) {
    runApplication<MyApplication>(*args)
}
@SpringBootApplication@EnableAutoConfiguration还提供别名来自定义和的属性@ComponentScan

这些功能都不是强制性的,您可以选择用它启用的任何功能来替换此单个注释。例如,您可能不想在应用程序中使用组件扫描或配置属性扫描:

Java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Import;

@SpringBootConfiguration(proxyBeanMethods = false)
@EnableAutoConfiguration
@Import({ SomeConfiguration.class, AnotherConfiguration.class })
public class MyApplication {

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

}
Kotlin
import org.springframework.boot.SpringBootConfiguration
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.docs.using.structuringyourcode.locatingthemainclass.MyApplication
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Import

@SpringBootConfiguration(proxyBeanMethods = false)
@EnableAutoConfiguration
@Import(SomeConfiguration::class, AnotherConfiguration::class)
class MyApplication

fun main(args: Array<String>) {
    runApplication<MyApplication>(*args)
}

在此示例中,MyApplication与任何其他 Spring Boot 应用程序一样,只是不会自动检测@Component-annotated 类和@ConfigurationProperties-annotated 类,并且显式导入用户定义的 bean(请参阅 参考资料@Import)。

7. 运行您的应用程序

将应用程序打包为 jar 并使用嵌入式 HTTP 服务器的最大优点之一是您可以像运行任何其他应用程序一样运行您的应用程序。该示例适用于调试Spring Boot应用程序。您不需要任何特殊的 IDE 插件或扩展。

本节仅涵盖基于 jar 的包装。如果您选择将应用程序打包为 war 文件,请参阅您的服务器和 IDE 文档。

7.1. 从 IDE 运行

您可以从 IDE 将 Spring Boot 应用程序作为 Java 应用程序运行。但是,您首先需要导入您的项目。导入步骤因您的 IDE 和构建系统而异。大多数IDE都可以直接导入Maven项目。例如,Eclipse 用户可以从菜单中选择Import…​→ 。Existing Maven ProjectsFile

如果您无法直接将项目导入 IDE,则可以使用构建插件生成 IDE 元数据。Maven 包括EclipseIDEA的插件。Gradle 为各种 IDE提供插件。

如果您不小心运行 Web 应用程序两次,您会看到“端口已在使用中”错误。Spring Tools 用户可以使用Relaunch按钮而不是Run按钮来确保关闭任何现有实例。

7.2. 作为打包应用程序运行

如果您使用 Spring Boot Maven 或 Gradle 插件创建可执行 jar,则可以使用 运行应用程序java -jar,如以下示例所示:

$ java -jar target/myapplication-0.0.1-SNAPSHOT.jar

还可以运行启用了远程调试支持的打包应用程序。这样做可以让您将调试器附加到打包的应用程序中,如以下示例所示:

$ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \
       -jar target/myapplication-0.0.1-SNAPSHOT.jar

7.3. 使用 Maven 插件

Spring Boot Maven 插件包含一个run可用于快速编译和运行应用程序的目标。应用程序以分解形式运行,就像在 IDE 中一样。以下示例显示了运行 Spring Boot 应用程序的典型 Maven 命令:

$ mvn spring-boot:run

您可能还想使用MAVEN_OPTS操作系统环境变量,如以下示例所示:

$ export MAVEN_OPTS=-Xmx1024m

7.4. 使用 Gradle 插件

Spring Boot Gradle 插件还包含一个bootRun可用于以分解形式运行应用程序的任务。bootRun每当您应用org.springframework.boot和插件时都会添加该任务java,如以下示例所示:

$ gradle bootRun

您可能还想使用JAVA_OPTS操作系统环境变量,如以下示例所示:

$ export JAVA_OPTS=-Xmx1024m

7.5。热插拔

由于 Spring Boot 应用程序是普通的 Java 应用程序,因此 JVM 热插拔应该可以开箱即用。JVM 热交换在某种程度上受到它可以替换的字节码的限制。对于更完整的解决方案,可以使用JRebel 。

spring-boot-devtools模块还包括对快速应用程序重新启动的支持。有关详细信息,请参阅热插拔“操作方法”

8. 开发者工具

Spring Boot 包含一组额外的工具,可以使应用程序开发体验更加愉快。该spring-boot-devtools模块可以包含在任何项目中以提供额外的开发时功能。要包含 devtools 支持,请将模块依赖项添加到您的构建中,如以下 Maven 和 Gradle 列表所示:

Maven
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>
Gradle
dependencies {
    developmentOnly("org.springframework.boot:spring-boot-devtools")
}
开发工具可能会导致类加载问题,特别是在多模块项目中。 诊断类加载问题解释了如何诊断和解决这些问题。
运行完全打包的应用程序时,开发人员工具会自动禁用。如果您的应用程序是从java -jar特殊的类加载器启动的,则它被视为“生产应用程序”。您可以使用spring.devtools.restart.enabled系统属性来控制此行为。要启用 devtools,无论用于启动应用程序的类加载器如何,请设置-Dspring.devtools.restart.enabled=true系统属性。不得在运行 devtools 存在安全风险的生产环境中执行此操作。要禁用开发工具,请排除依赖项或设置-Dspring.devtools.restart.enabled=false系统属性。
在 Maven 中将依赖项标记为可选或使用developmentOnlyGradle 中的配置(如上所示)可防止 devtools 传递应用于使用您的项目的其他模块。
重新打包的存档默认不包含开发工具。如果你想使用某个远程开发工具功能,你需要包含它。使用 Maven 插件时,将该excludeDevtools属性设置为false。使用 Gradle 插件时,配置任务的类路径以包含developmentOnly配置.

8.1. 诊断类加载问题

如重新启动与重新加载部分所述,重新启动功能是通过使用两个类加载器来实现的。对于大多数应用程序来说,这种方法效果很好。但是,它有时会导致类加载问题,特别是在多模块项目中。

要诊断类加载问题是否确实是由 devtools 及其两个类加载器引起的,请尝试禁用 restart。如果这解决了您的问题,请自定义重新启动类加载器以包含您的整个项目。

8.2. 属性默认值

Spring Boot 支持的一些库使用缓存来提高性能。例如,模板引擎会缓存编译后的模板,以避免重复解析模板文件。此外,Spring MVC 可以在提供静态资源时向响应添加 HTTP 缓存标头。

虽然缓存在生产中非常有益,但在开发过程中可能会适得其反,使您无法看到刚刚在应用程序中所做的更改。因此,spring-boot-devtools 默认禁用缓存选项。

缓存选项通常通过application.properties文件中的设置进行配置。例如,Thymeleaf 就提供该spring.thymeleaf.cache属性。该模块不需要手动设置这些属性,而是spring-boot-devtools自动应用合理的开发时配置。

下表列出了所有应用的属性:

姓名 默认值

server.error.include-binding-errors

always

server.error.include-message

always

server.error.include-stacktrace

always

server.servlet.jsp.init-parameters.development

true

server.servlet.session.persistent

true

spring.docker.compose.readiness.wait

only-if-started

spring.freemarker.cache

false

spring.graphql.graphiql.enabled

true

spring.groovy.template.cache

false

spring.h2.console.enabled

true

spring.mustache.servlet.cache

false

spring.mvc.log-resolved-exception

true

spring.reactor.netty.shutdown-quiet-period

0s

spring.template.provider.cache

false

spring.thymeleaf.cache

false

spring.web.resources.cache.period

0

spring.web.resources.chain.cache

false

如果您不希望应用属性默认值,您可以spring.devtools.add-properties在. falseapplication.properties

DEBUG由于您在开发 Spring MVC 和 Spring WebFlux 应用程序时需要有关 Web 请求的更多信息,因此开发人员工具建议您为日志记录组启用日志记录web。这将为您提供有关传入请求、正在处理该请求的处理程序、响应结果以及其他详细信息的信息。如果您希望记录所有请求详细信息(包括潜在的敏感信息),您可以打开spring.mvc.log-request-detailsspring.codec.log-request-details配置属性。

8.3. 自动重启

spring-boot-devtools每当类路径上的文件发生更改时,使用自动重新启动的应用程序。在 IDE 中工作时,这可能是一个有用的功能,因为它为代码更改提供了非常快速的反馈循环。默认情况下,类路径上指向目录的任何条目都会受到监视以了解更改。请注意,某些资源(例如静态资产和视图模板)不需要重新启动应用程序

触发重启

由于 DevTools 监视类路径资源,触发重新启动的唯一方法是更新类路径。无论您使用 IDE 还是构建插件之一,都必须重新编译修改的文件才能触发重新启动。更新类路径的方式取决于您使用的工具:

  • 在 Eclipse 中,保存修改的文件会导致类路径更新并触发重新启动。

  • 在 IntelliJ IDEA 中,构建项目 ( Build +→+ Build Project) 具有相同的效果。

  • 如果使用构建插件,运行mvn compileMaven 或gradle buildGradle 将触发重新启动。

如果您使用构建插件重新启动 Maven 或 Gradle,则必须将设置保留forkingenabled. 如果禁用分叉,则将不会创建 devtools 使用的隔离应用程序类加载器,并且重新启动将无法正常运行。
与 LiveReload 一起使用时,自动重启效果非常好。 有关详细信息,请参阅 LiveReload 部分。如果您使用 JRebel,则会禁用自动重新启动,以支持动态类重新加载。仍然可以使用其他开发工具功能(例如 LiveReload 和属性覆盖)。
DevTools 依赖应用程序上下文的关闭挂钩在重新启动期间将其关闭。如果您禁用了关闭挂钩 ( ),它将无法正常工作SpringApplication.setRegisterShutdownHook(false)
DevTools 需要自ResourceLoader定义ApplicationContext. 如果您的应用程序已经提供了一个,那么它将被包装。不支持 直接重写方法getResourceApplicationContext
使用 AspectJ 编织时不支持自动重启。
重新启动与重新加载

Spring Boot 提供的重启技术通过使用两个类加载器来工作。不更改的类(例如,来自第三方 jar 的类)将加载到类加载器中。您正在积极开发的类将加载到重新启动的类加载器中。当应用程序重新启动时,重新启动的类加载器将被丢弃并创建一个新的类加载器。这种方法意味着应用程序重新启动通常比“冷启动”快得多,因为基类加载器已经可用并已填充。

如果您发现应用程序的重新启动速度不够快或者遇到类加载问题,您可以考虑重新加载技术,例如ZeroTurnaround 的JRebel 。这些工作原理是在加载类时重写类,使它们更适合重新加载。

8.3.1. 记录条件评估的变化

默认情况下,每次应用程序重新启动时,都会记录一份显示条件评估增量的报告。当您进行更改(例如添加或删除 Bean 以及设置配置属性)时,该报告会显示应用程序自动配置的更改。

要禁用报告日志记录,请设置以下属性:

Properties
spring.devtools.restart.log-condition-evaluation-delta=false
Yaml
spring:
  devtools:
    restart:
      log-condition-evaluation-delta: false

8.3.2. 排除资源

某些资源在更改时不一定需要触发重新启动。例如,Thymeleaf 模板可以就地编辑。默认情况下,更改/META-INF/maven/META-INF/resources/resources/static/public或中的资源/templates不会触发重新启动,但会触发实时重新加载。如果您想自定义这些排除项,可以使用该spring.devtools.restart.exclude属性。例如,要仅排除/static/public您可以设置以下属性:

Properties
spring.devtools.restart.exclude=static/**,public/**
Yaml
spring:
  devtools:
    restart:
      exclude: "static/**,public/**"
如果您想保留这些默认值并添加其他排除项,请改用该spring.devtools.restart.additional-exclude属性。

8.3.3. 观看其他路径

当您对不在类路径上的文件进行更改时,您可能希望重新启动或重新加载应用程序。为此,请使用该spring.devtools.restart.additional-paths属性配置其他路径以监视更改。您可以使用前面描述的spring.devtools.restart.exclude属性来控制其他路径下的更改是否触发完全重新启动或实时重新加载

8.3.4. 禁用重新启动

如果您不想使用重新启动功能,可以使用 属性将其禁用spring.devtools.restart.enabled。在大多数情况下,您可以在您的文件中设置此属性application.properties(这样做仍然会初始化重新启动类加载器,但它不会监视文件更改)。

如果您需要完全禁用重新启动支持(例如,因为它不适用于特定库),则需要将该spring.devtools.restart.enabled System属性设置为falsebefore call SpringApplication.run(…​),如以下示例所示:

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

@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        System.setProperty("spring.devtools.restart.enabled", "false");
        SpringApplication.run(MyApplication.class, args);
    }

}
Kotlin
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication

@SpringBootApplication
object MyApplication {

    @JvmStatic
    fun main(args: Array<String>) {
        System.setProperty("spring.devtools.restart.enabled", "false")
        SpringApplication.run(MyApplication::class.java, *args)
    }

}

8.3.5. 使用触发文件

如果您使用连续编译更改的文件的 IDE,您可能更愿意仅在特定时间触发重新启动。为此,您可以使用“触发文件”,这是一个特殊文件,当您想要实际触发重新启动检查时必须修改该文件。

对文件的任何更新都会触发检查,但只有在 Devtools 检测到有事情要做时才会真正重新启动。

要使用触发器文件,请将该spring.devtools.restart.trigger-file属性设置为触发器文件的名称(不包括任何路径)。触发器文件必须出现在类路径上的某个位置。

例如,如果您有一个具有以下结构的项目:

src
+- main
   +- resources
      +- .reloadtrigger

那么你的trigger-file财产将是:

Properties
spring.devtools.restart.trigger-file=.reloadtrigger
Yaml
spring:
  devtools:
    restart:
      trigger-file: ".reloadtrigger"

现在只有在更新时才会重新启动src/main/resources/.reloadtrigger

您可能希望设置spring.devtools.restart.trigger-file全局设置,以便所有项目都以相同的方式运行。

某些 IDE 具有使您无需手动更新触发器文件的功能。 Spring Tools for EclipseIntelliJ IDEA(终极版)都有这样的支持。使用 Spring Tools,您可以使用控制台视图中的“重新加载”按钮(只要您的trigger-file名称为.reloadtrigger)。对于 IntelliJ IDEA,您可以按照其文档中的说明进行操作。

8.3.6. 自定义重启类加载器

如前面的“重新启动与重新加载”部分所述,重新启动功能是通过使用两个类加载器来实现的。如果这导致问题,您可能需要自定义由哪个类加载器加载的内容。

默认情况下,IDE 中任何打开的项目都会使用“重新启动”类加载器加载,任何常规.jar文件都会使用“基本”类加载器加载。mvn spring-boot:run如果您使用or ,情况也是如此gradle bootRun:包含您的项目使用@SpringBootApplication“重新启动”类加载器加载,其他所有内容都使用“基本”类加载器加载。

您可以通过创建文件来指示 Spring Boot 使用不同的类加载器加载项目的部分内容META-INF/spring-devtools.properties。该spring-devtools.properties文件可以包含前缀为restart.exclude和 的属性restart.include。这些include元素是应该被拉入“重新启动”类加载器的项目,这些exclude元素是应该被推入“基本”类加载器的项目。该属性的值是应用于类路径的正则表达式模式,如以下示例所示:

Properties
restart.exclude.companycommonlibs=/mycorp-common-[\\w\\d-\\.]+\\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w\\d-\\.]+\\.jar
Yaml
restart:
  exclude:
    companycommonlibs: "/mycorp-common-[\\w\\d-\\.]+\\.jar"
  include:
    projectcommon: "/mycorp-myproj-[\\w\\d-\\.]+\\.jar"
所有属性键必须是唯一的。只要一个属性以restart.include.或开始,restart.exclude.就被考虑。
所有META-INF/spring-devtools.properties来自类路径的内容都会被加载。您可以将文件打包到项目内或项目使用的库中。

8.3.7. 已知限制

重新启动功能不适用于使用标准ObjectInputStream. 如果您需要反序列化数据,您可能需要将 SpringConfigurableObjectInputStreamThread.currentThread().getContextClassLoader().

不幸的是,一些第三方库在不考虑上下文类加载器的情况下进行反序列化。如果您发现此类问题,您需要向原作者请求修复。

8.4. 实时重载

spring-boot-devtools模块包括一个嵌入式 LiveReload 服务器,可用于在资源更改时触发浏览器刷新。LiveReload 浏览器扩展可免费用于 Chrome、Firefox 和 Safari。您可以通过在所选浏览器的市场或商店中搜索“LiveReload”来找到这些扩展。

如果您不想在应用程序运行时启动 LiveReload 服务器,可以将该spring.devtools.livereload.enabled属性设置为false

您一次只能运行一台 LiveReload 服务器。在启动应用程序之前,请确保没有其他 LiveReload 服务器正在运行。如果您从 IDE 启动多个应用程序,则只有第一个应用程序具有 LiveReload 支持。
要在文件更改时触发 LiveReload,必须启用 自动重新启动。

8.5。全局设置

您可以通过将以下任意文件添加到$HOME/.config/spring-boot目录来配置全局 devtools 设置:

  1. spring-boot-devtools.properties

  2. spring-boot-devtools.yaml

  3. spring-boot-devtools.yml

添加到这些文件的任何属性都适用于您计算机上使用 devtools 的所有Spring Boot 应用程序。例如,要将重新启动配置为始终使用触发器文件,您可以将以下属性添加到spring-boot-devtools文件中:

Properties
spring.devtools.restart.trigger-file=.reloadtrigger
Yaml
spring:
  devtools:
    restart:
      trigger-file: ".reloadtrigger"

默认情况下,$HOME是用户的主目录。要自定义此位置,请设置SPRING_DEVTOOLS_HOME环境变量或spring.devtools.home系统属性。

如果在 中找不到 devtools 配置文件$HOME/.config/spring-boot,则会在目录的根目录中$HOME搜索是否存在.spring-boot-devtools.properties文件。这允许您与不支持该$HOME/.config/spring-boot位置的旧版本 Spring Boot 上的应用程序共享 devtools 全局配置。

devtools 属性/yaml 文件不支持配置文件。

激活的任何配置文件都不会影响特定于配置文件的配置文件.spring-boot-devtools.properties的加载。不支持 YAML 和 Properties 文件中的配置文件特定文件名(格式为)和文档。spring-boot-devtools-<profile>.propertiesspring.config.activate.on-profile

8.5.1. 配置文件系统观察器

FileSystemWatcher 的工作原理是按照一定的时间间隔轮询类更改,然后等待预定义的安静期以确保不再有更改。由于 Spring Boot 完全依赖 IDE 来编译文件并将文件复制到 Spring Boot 可以读取它们的位置,因此您可能会发现,有时当 devtools 重新启动应用程序时,某些更改不会反映出来。如果您经常观察到此类问题,请尝试将spring.devtools.restart.poll-intervalspring.devtools.restart.quiet-period参数增加到适合您的开发环境的值:

Properties
spring.devtools.restart.poll-interval=2s
spring.devtools.restart.quiet-period=1s
Yaml
spring:
  devtools:
    restart:
      poll-interval: "2s"
      quiet-period: "1s"

现在每 2 秒轮询一次受监视的类路径目录是否有更改,并保持 1 秒的安静期以确保没有其他类更改。

8.6。远程应用程序

Spring Boot开发者工具不仅限于本地开发。您还可以在远程运行应用程序时使用多种功能。远程支持是可选的,因为启用它可能会带来安全风险。仅当在受信任的网络上运行或使用 SSL 保护时才应启用它。如果您无法使用这些选项,则不应使用 DevTools 的远程支持。您永远不应该启用对生产部署的支持。

要启用它,您需要确保它devtools包含在重新打包的存档中,如下列表所示:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <excludeDevtools>false</excludeDevtools>
            </configuration>
        </plugin>
    </plugins>
</build>

然后你需要设置spring.devtools.remote.secret属性。与任何重要的密码或秘密一样,该值应该是唯一且强大的,以便无法猜测或暴力破解。

远程开发工具支持分为两部分:接受连接的服务器端端点和在 IDE 中运行的客户端应用程序。spring.devtools.remote.secret设置该属性后,服务器组件会自动启用。客户端组件必须手动启动。

Spring WebFlux 应用程序不支持远程开发工具。

8.6.1. 运行远程客户端应用程序

远程客户端应用程序设计为在 IDE 中运行。您需要使用org.springframework.boot.devtools.RemoteSpringApplication与连接到的远程项目相同的类路径来运行。应用程序的唯一必需参数是它连接的远程 URL。

例如,如果您使用 Eclipse 或 Spring Tools,并且您有一个名为my-app您已部署到 Cloud Foundry 的项目,则您将执行以下操作:

  • Run Configurations…​从菜单中选择Run

  • 创建一个新的Java Application“启动配置”。

  • 浏览该my-app项目。

  • org.springframework.boot.devtools.RemoteSpringApplication作为主类使用。

  • 添加https://myapp.cfapps.ioProgram arguments(或任何您的远程 URL)。

正在运行的远程客户端可能类似于以下列表:

  .   ____          _                                              __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _          ___               _      \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` |        | _ \___ _ __  ___| |_ ___ \ \ \ \
 \\/  ___)| |_)| | | | | || (_| []::::::[]   / -_) '  \/ _ \  _/ -_) ) ) ) )
  '  |____| .__|_| |_|_| |_\__, |        |_|_\___|_|_|_\___/\__\___|/ / / /
 =========|_|==============|___/===================================/_/_/_/
 :: Spring Boot Remote ::  (v3.1.5)

2023-10-19T12:18:09.696Z  INFO 37376 --- [           main] o.s.b.devtools.RemoteSpringApplication   : Starting RemoteSpringApplication v3.1.5 using Java 17.0.9 with PID 37376 (/Users/myuser/.m2/repository/org/springframework/boot/spring-boot-devtools/3.1.5/spring-boot-devtools-3.1.5.jar started by myuser in /opt/apps/)
2023-10-19T12:18:09.701Z  INFO 37376 --- [           main] o.s.b.devtools.RemoteSpringApplication   : No active profile set, falling back to 1 default profile: "default"
2023-10-19T12:18:10.039Z  INFO 37376 --- [           main] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2023-10-19T12:18:10.071Z  INFO 37376 --- [           main] o.s.b.devtools.RemoteSpringApplication   : Started RemoteSpringApplication in 0.833 seconds (process running for 1.2)
由于远程客户端使用与真实应用程序相同的类路径,因此它可以直接读取应用程序属性。这就是spring.devtools.remote.secret读取属性并将其传递到服务器进行身份验证的方式。
始终建议使用https://作为连接协议,以便对流量进行加密并且密码无法被拦截。
如果需要使用代理访问远程应用程序,请配置spring.devtools.remote.proxy.hostspring.devtools.remote.proxy.port属性。

8.6.2. 远程更新

远程客户端以与本地重新启动相同的方式监视应用程序类路径的更改。任何更新的资源都会被推送到远程应用程序并(如果需要)触发重新启动。如果您迭代使用本地没有的云服务的功能,这会很有帮助。一般来说,远程更新和重新启动比完整的重建和部署周期要快得多。

在较慢的开发环境中,可能会出现安静期不够的情况,类中的更改可能会被分成批次。第一批类更改上传后,服务器将重新启动。由于服务器正在重新启动,因此无法将下一批发送到应用程序。

这通常通过日志中有关无法上传某些类的警告RemoteSpringApplication以及随后的重试来体现。但也可能导致应用代码不一致,第一批变更上传后无法重启。如果您经常观察到此类问题,请尝试将spring.devtools.restart.poll-intervalspring.devtools.restart.quiet-period参数增加到适合您的开发环境的值。有关配置这些属性的信息,请参阅配置文件系统观察器部分。

仅当远程客户端运行时才会监视文件。如果在启动远程客户端之前更改文件,则该文件不会推送到远程服务器。

9. 打包您的生产应用程序

可执行 jar 可用于生产部署。由于它们是独立的,因此也非常适合基于云的部署。

对于其他“生产就绪”功能,例如运行状况、审计和指标 REST 或 JMX 端点,请考虑添加spring-boot-actuator. 详细信息请参见actuator.html 。

10. 接下来读什么

您现在应该了解如何使用 Spring Boot 以及应该遵循的一些最佳实践。现在,您可以继续深入了解特定的Spring Boot 功能,或者您可以跳过并阅读 Spring Boot 的“生产就绪”方面。