# 用 Spring boot 开发
本节将更详细地介绍如何使用 Spring 引导。它涵盖了诸如构建系统、自动配置以及如何运行应用程序等主题。我们还介绍了一些引导最佳实践。虽然 Spring boot 并没有什么特别之处(它只是另一个你可以使用的库),但有一些建议,如果遵循这些建议,将使你的开发过程变得更容易一些。
如果你是从 Spring boot 开始的,那么在深入了解本节之前,你可能应该阅读*[Getting Started](getting-started.html#getting-started)*指南。
## 1. 建立系统
强烈建议你选择一个支持[* 扶养管理 *](#using.build-systems.dependency-management)并且可以使用发布到“ Maven Central”存储库的工件的构建系统。我们建议你选择 Maven 或 Gradle。让 Spring 引导与其他构建系统(例如 Ant)一起工作是可能的,但是它们没有得到特别好的支持。
### 1.1.依赖管理
Spring 启动的每个版本都提供了它所支持的依赖关系的精心策划的列表。在实践中,你不需要在构建配置中为这些依赖项中的任何一个提供版本,因为 Spring boot 为你管理这些依赖项。当你升级 Spring 引导本身时,这些依赖关系也会以一致的方式进行升级。
| |你仍然可以指定一个版本,并在需要时重写 Spring Boot 的建议。|
|---|------------------------------------------------------------------------------------------------|
这个精心策划的列表包含你可以在 Spring 启动时使用的所有 Spring 模块,以及第三方库的完善列表。这份清单是一份标准的材料清单(` Spring-boot-dependencies`),可用于[Maven](#using.build-systems.maven)和[Gradle](#using.build-systems.gradle)。
| |Spring 启动的每个版本都与 Spring 框架的基本版本相关联。
我们**高度**建议你不要指定其版本。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------|
### 1.2. Maven
要了解如何在 Maven 中使用 Spring boot,请参阅 Spring boot 的 Maven 插件的文档:
* 参考文献([HTML](https://docs.spring.io/spring-boot/docs/2.6.4/maven-plugin/reference/htmlsingle/)和[PDF](https://docs.spring.io/spring-boot/docs/2.6.4/maven-plugin/reference/pdf/spring-boot-maven-plugin-reference.pdf))
* [API](https://docs.spring.io/spring-boot/docs/2.6.4/maven-plugin/api/)
### 1.3. Gradle
要了解如何在 Gradle 中使用 Spring boot,请参阅 Spring boot 的 Gradle 插件的文档:
* 参考文献([HTML](https://docs.spring.io/spring-boot/docs/2.6.4/gradle-plugin/reference/htmlsingle/)和[PDF](https://docs.spring.io/spring-boot/docs/2.6.4/gradle-plugin/reference/pdf/spring-boot-gradle-plugin-reference.pdf))
* [API](https://docs.spring.io/spring-boot/docs/2.6.4/gradle-plugin/api/)
### 1.4. Ant
可以使用 Apache Ant +Ivy 构建 Spring 引导项目。`spring-boot-antlib`“antlib”模块也可用于帮助 Ant 创建可执行 JAR。
要声明依赖关系,典型的`ivy.xml`文件类似于以下示例:
```
```
一个典型的`build.xml`看起来像以下示例:
```
```
| |如果你不想使用`spring-boot-antlib`模块,请参阅*[howto.html](howto.html#howto.build.build-an-executable-archive-with-ant-without-using-spring-boot-antlib)*“how-to”。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### 1.5.初学者
启动器是一组方便的依赖关系描述符,你可以将它们包含在应用程序中。你可以获得所需的所有 Spring 和相关技术的一站式服务,而无需搜索示例代码和复制粘贴依赖描述符的负载。例如,如果你希望开始使用 Spring 和 JPA 进行数据库访问,那么在你的项目中包含`spring-boot-starter-data-jpa`依赖项。
启动器包含许多依赖项,你需要这些依赖项才能使项目快速启动和运行,并具有一组一致的、受支持的托管传递依赖项。
名字里的含义是什么?
所有**官员**启动器都遵循类似的命名模式;`spring-boot-starter-*`,其中`*`是一种特定类型的应用程序。此命名结构旨在帮助你在需要查找启动器时使用。 Maven 在许多 IDE 中的集成允许你按名称搜索依赖项。例如,在安装了适当的 Eclipse 或 Spring Tools 插件后,你可以在 POM 编辑器中按`ctrl-space`并输入“ Spring-boot-starter”以获得完整的列表。
正如在“[创建自己的启动器](features.html#features.developing-auto-configuration.custom-starter)”部分中所解释的,第三方启动器不应该以`spring-boot`开头,因为它是为官方 Spring 引导工件保留的。相反,第三方启动程序通常以项目的名称开始。例如,一个名为`thirdpartyproject`的第三方启动项目通常被命名为`thirdpartyproject-spring-boot-starter`。
Spring Boot 在`org.springframework.boot`组下提供了以下应用程序启动器:
| Name |说明|
|-------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| []()`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 批的启动器|
| []()`spring-boot-starter-cache` |使用 Spring Framework 的缓存支持的入门工具|
| []()`spring-boot-starter-data-cassandra` |用于使用 Cassandra 分布式数据库和 Spring 数据的启动器 Cassandra|
|[]()`spring-boot-starter-data-cassandra-reactive`|用于使用 Cassandra 分布式数据库的启动器和 Spring 数据 Cassandra 反应|
| []()`spring-boot-starter-data-couchbase` |用于使用 CouchBase 面向文档的数据库和 Spring DataCouchBase 的启动器|
|[]()`spring-boot-starter-data-couchbase-reactive`|Spring 用于使用 CouchBase 文档的面向数据库和 CouchBase 数据库的启动器|
| []()`spring-boot-starter-data-elasticsearch` |用于使用 ElasticSearch 搜索和分析引擎的启动器和 Spring 数据 ElasticSearch|
| []()`spring-boot-starter-data-jdbc` |用于使用 Spring 数据 JDBC 的启动器|
| []()`spring-boot-starter-data-jpa` |用于使用 Spring 数据 JPA 和 Hibernate 的启动器|
| []()`spring-boot-starter-data-ldap` |用于使用 Spring 数据 LDAP 的启动器|
| []()`spring-boot-starter-data-mongodb` |用于使用 MongoDB 面向文档的数据库和 Spring 数据 MongoDB 的启动器|
| []()`spring-boot-starter-data-mongodb-reactive` |用于使用 MongoDB 面向文档的数据库的启动器和 Spring 数据 MongoDB Active|
| []()`spring-boot-starter-data-neo4j` |用于使用 NEO 的启动器 4j 图数据库和 Spring 数据 NEO4j|
| []()`spring-boot-starter-data-r2dbc` |用于使用 Spring 数据 R2DBC 的启动器|
| []()`spring-boot-starter-data-redis` |用 Spring 数据 Redis 和生菜客户机使用 Redis 键值数据存储的启动器|
| []()`spring-boot-starter-data-redis-reactive` |用于使用 Redis 键值数据存储的启动器 Spring 数据 Redis 是被动的和生菜客户机|
| []()`spring-boot-starter-data-rest` |用于使用 Spring 数据 REST 在 REST 上公开 Spring 数据存储库的启动器|
| []()`spring-boot-starter-freemarker` |使用 Freemarker 视图构建 MVC Web 应用程序的启动器|
| []()`spring-boot-starter-groovy-templates` |使用 Groovy Templates 视图构建 MVC Web 应用程序的入门工具|
| []()`spring-boot-starter-hateoas` |用 Spring MVC 和 Spring Hateoas 构建基于超媒体的 RESTful Web 应用程序的启动器|
| []()`spring-boot-starter-integration` |用于使用 Spring 集成的启动器|
| []()`spring-boot-starter-jdbc` |使用 JDBC 和 HikarICP 连接池的启动器|
| []()`spring-boot-starter-jersey` |使用 JAX-RS 和 Jersey 构建 RESTful Web 应用程序的入门工具。[`spring-boot-starter-web`](#spring-boot-starter-web)的一种替代方法|
| []()`spring-boot-starter-jooq` |使用 Jooq 使用 JDBC 访问 SQL 数据库的启动器。[`spring-boot-starter-data-jpa`](#spring-boot-starter-data-jpa)或[`spring-boot-starter-jdbc`](#spring-boot-starter-jdbc)的替代方案|
| []()`spring-boot-starter-json` |读写 JSON 的启动器|
| []()`spring-boot-starter-jta-atomikos` |使用 Atomikos 的 JTA 事务启动器|
| []()`spring-boot-starter-mail` |使用 Java Mail 的启动器和 Spring Framework 的电子邮件发送支持|
| []()`spring-boot-starter-mustache` |使用 Mustache 视图构建 Web 应用程序的入门工具|
| []()`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 客户机和服务器的启动器|
| []()`spring-boot-starter-security` |使用 Spring 安全性的启动器|
| []()`spring-boot-starter-test` |用包括 JUnit Jupiter、Hamcrest 和 Mockito 在内的库测试 Spring 引导应用程序的启动器|
| []()`spring-boot-starter-thymeleaf` |使用 ThymeLeaf 视图构建 MVC Web 应用程序的启动器|
| []()`spring-boot-starter-validation` |用 Hibernate 验证器使用 Java Bean 验证的启动器|
| []()`spring-boot-starter-web` |用于使用 Spring MVC 构建 Web(包括 RESTful)应用程序的启动器。使用 Tomcat 作为默认的嵌入式容器|
| []()`spring-boot-starter-web-services` |用于使用 Spring Web 服务的启动器|
| []()`spring-boot-starter-webflux` |使用 Spring 框架的反应性 Web 支持构建 WebFlux 应用程序的启动器|
| []()`spring-boot-starter-websocket` |用于使用 Spring 框架的 WebSocket 支持构建 WebSocket 应用程序的启动器|
除了应用程序启动器之外,还可以使用以下启动器添加*[生产准备就绪](actuator.html#actuator)*特性:
| Name |说明|
|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------|
|[]()`spring-boot-starter-actuator`|使用 Spring Boot 的执行器的启动器,该执行器提供了生产就绪的功能,以帮助你监视和管理你的应用程序|
最后, Spring 引导还包括以下启动器,如果你想要排除或交换特定的技术方面,可以使用这些启动器:
| Name |说明|
|---------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
| []()`spring-boot-starter-jetty` |用于使用 Jetty 作为嵌入式 Servlet 容器的启动器。[`spring-boot-starter-tomcat`](#spring-boot-starter-tomcat)的一种替代方法|
| []()`spring-boot-starter-log4j2` |使用 log4j2 进行日志记录的启动器。[`spring-boot-starter-logging`](#spring-boot-starter-logging)的一种替代方法|
| []()`spring-boot-starter-logging` |使用日志记录的启动器。默认日志启动器|
|[]()`spring-boot-starter-reactor-netty`|使用反应器网络作为嵌入式反应性 HTTP 服务器的启动器。|
| []()`spring-boot-starter-tomcat` |用于使用 Tomcat 作为嵌入式 Servlet 容器的启动器。由[`spring-boot-starter-web`](#spring-boot-starter-web)使用的默认 Servlet 容器启动器|
| []()`spring-boot-starter-undertow` |用于使用 Undertow 作为嵌入式 Servlet 容器的启动器。[`spring-boot-starter-tomcat`](#spring-boot-starter-tomcat)的一种替代方法|
要了解如何交换技术方面,请参阅[交换 Web 服务器](howto.html#howto.webserver.use-another)和[logging system](howto.html#howto.logging.log4j)的操作文档。
| |有关其他社区贡献的启动器的列表,请参见 Github 上`spring-boot-starters`模块中的[README file](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-starters/README.adoc)。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
## 2. 构建你的代码
Spring 启动不需要任何特定的代码布局来工作。然而,有一些最佳实践是有帮助的。
### 2.1.使用“默认”包
当一个类不包含`package`声明时,它被认为是在“缺省包”中。“默认包”的使用通常是不鼓励的,应该避免。对于使用`@ComponentScan`、`@Configuration属性Scan`、`@EntityScan`或`@SpringBootApplication`注释的 Spring 引导应用程序来说,这可能会导致特殊的问题,因为每个 jar 中的每个类都被读取。
| |我们建议你遵循 Java 推荐的包命名约定,并使用一个反向域名(例如,`com.example.project`)。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------|
### 2.2.定位主应用程序类
我们通常建议你将主应用程序类定位在一个根包中,而不是其他类。[@SpringBootApplication](#using.using-the-springbootapplication-annotation)通常放在主类上,它隐式地为某些项定义了一个基本的“搜索包”。例如,如果你正在编写 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`方法,以及基本的`@SpringBootApplication`,如下所示:
```
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);
}
}
```
## 3. 配置类
Spring 引导有利于基于 Java 的配置。尽管在 XML 源中可以使用`SpringApplication`,但我们通常建议你的主要源是一个单独的`@Configuration`类。通常,定义`main`方法的类是作为主要`@Configuration`方法的很好的候选者。
| |Spring 互联网上已经发布了许多使用 XML 配置的配置示例。
如果可能的话,总是尝试使用等效的基于 Java 的配置。
搜索`Enable*`注释可以是一个很好的起点。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### 3.1.导入额外的配置类 ###
你不需要将所有的`@Configuration`都放入一个类中。`@Import`注释可用于导入其他配置类。或者,你可以使用`@ComponentScan`来自动拾取所有 Spring 组件,包括`@Configuration`类。
### 3.2.导入 XML 配置
如果你绝对必须使用基于 XML 的配置,我们建议你仍然从`@Configuration`类开始。然后可以使用`@ImportResource`注释来加载 XML 配置文件。
## 4. 自动配置
Spring 引导自动配置尝试基于你已添加的 jar 依赖项自动配置你的 Spring 应用程序。例如,如果`HSQLDB`在你的 Classpath 上,并且你还没有手动配置任何数据库连接 bean,那么 Spring 引导自动配置内存中的数据库。
你需要通过向你的`@Configuration`类中的一个添加`@EnableAutoConfiguration`或`@SpringBootApplication`注释来 OPT 到自动配置中。
| |你应该只添加一个`@SpringBootApplication`或`@EnableAutoConfiguration`注释。
我们通常建议你只在主`@Configuration`类中添加一个或另一个。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### 4.1.逐步取代自动配置
自动配置是非侵入性的。在任何时候,你都可以开始定义自己的配置,以替换自动配置的特定部分。例如,如果你添加了自己的`DataSource` Bean,那么默认的嵌入式数据库支持就退后了。
如果需要找出当前正在应用的自动配置,以及为什么,请使用`--debug`开关启动应用程序。这样做可以为选择的核心记录器启用调试日志,并将一个条件报告给控制台。
### 4.2.禁用特定的自动配置类
如果你发现你不想要的特定自动配置类正在被应用,那么你可以使用`@SpringBootApplication`的 exclude 属性来禁用它们,如下面的示例所示:
```
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class MyApplication {
}
```
如果类不在 Classpath 上,则可以使用注释的`excludeName`属性并指定完全限定的名称。如果你更喜欢使用`@EnableAutoConfiguration`而不是`@SpringBootApplication`,也可以使用`exclude`和`excludeName`。最后,还可以使用`spring.autoconfigure.exclude`属性控制要排除的自动配置类列表。
| |你可以在注释级别和通过使用属性来定义排除。|
|---|---------------------------------------------------------------------------------|
| |尽管自动配置类是`public`,但该类中唯一被认为是公共 API 的方面是可用于禁用自动配置的类的名称,
这些类的实际内容,例如嵌套配置类或 Bean 方法仅供内部使用,我们不建议直接使用这些方法。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
## 5. Spring bean 和依赖注入
你可以自由地使用任何标准的 Spring 框架技术来定义你的 bean 及其注入的依赖项。我们通常建议使用构造函数注入连接依赖项,并使用`@ComponentScan`查找 bean。
如果按照上面的建议构造代码(将应用程序类定位在一个顶级包中),则可以添加`@ComponentScan`而不带任何参数,或者使用`@SpringBootApplication`注释,其中隐式地包含它。你的所有应用程序组件(“@component”、`@Service`、`@Repository`、`@Controller`等)都会自动注册为 Spring bean。
下面的示例显示了一个`@Service` Bean,它使用构造函数注入来获得所需的`RiskAssessor` Bean:
```
import org.springframework.stereotype.Service;
@Service
public class MyAccountService implements AccountService {
private final RiskAssessor riskAssessor;
public MyAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}
// ...
}
```
如果 Bean 具有多个构造函数,则需要将希望 Spring 使用的构造函数标记为`@Autowired`:
```
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;
}
// ...
}
```
| |请注意,如何使用构造函数注入使`riskAssessor`字段标记为`final`,这表明它不能随后进行更改。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------|
## 6. 使用 @SpringBootApplication 注释
Spring 许多引导开发人员喜欢他们的应用程序使用自动配置、组件扫描,并能够在他们的“应用程序类”上定义额外的配置。可以使用一个`@SpringBootApplication`注释来启用这三个特性,即:
* `@EnableAutoConfiguration`:启用[Spring Boot’s auto-configuration mechanism](#using.auto-configuration)
* `@ComponentScan`:在应用程序所在的包上启用`@Component`扫描(参见[最佳实践](#using.structuring-your-code))
* `@SpringBootConfiguration`:允许在上下文中注册额外的 bean 或导入额外的配置类。 Spring 的标准`@Configuration`的一种替代方法,它在集成测试中帮助[配置检测](features.html#features.testing.spring-boot-applications.detecting-configuration)。
```
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);
}
}
```
| |`@SpringBootApplication`还提供别名来定制`@EnableAutoConfiguration`和`@ComponentScan`的属性。|
|---|------------------------------------------------------------------------------------------------------------------------------|
| |这些功能都不是强制性的,你可以选择用它启用的任何功能替换这一条注释。,例如,
,你可能不希望在应用程序中使用组件扫描或配置属性扫描:
``
导入 org.springframework.boot.springapplication;
导入 org.springframework.boof.autform.autofconfigure.enableautofconfiguration;
import.springtr.contexform.context.org.org.context.import;<<><<<<<>>>配置 =“156”Bootframmetation"/><}
}
``
在本例中,`MyApplication`就像任何其他 Spring 启动应用程序一样,除了`@Component`-注释的类和`@Configuration属性`-注释的类未被检测到,并且显式地导入了用户定义的 bean(参见`@Import`)。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
## 7. 运行你的应用程序
将应用程序打包为 jar 并使用嵌入式 HTTP 服务器的最大优势之一是,你可以像运行其他应用程序一样运行你的应用程序。该示例应用于调试 Spring 引导应用程序。你不需要任何特殊的 IDE 插件或扩展。
| |本节仅涵盖基于 jar 的打包。
如果你选择将应用程序打包为 WAR 文件,请参阅你的服务器和 IDE 文档。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------|
### 7.1.从 IDE 中运行
你可以将 IDE 中的 Spring 引导应用程序作为 Java 应用程序运行。然而,你首先需要导入你的项目。导入步骤根据你的 IDE 和构建系统而有所不同。大多数 IDE 可以直接导入 Maven 项目。例如,Eclipse 用户可以从`File`菜单中选择`Import…``Existing Maven Projects`。
如果不能直接将项目导入 IDE,则可以使用构建插件生成 IDE 元数据。 Maven 包括用于[Eclipse](https://maven.apache.org/plugins/maven-eclipse-plugin/)和[IDEA](https://maven.apache.org/plugins/maven-idea-plugin/)的插件。 Gradle 为[various IDEs](https://docs.gradle.org/current/userguide/userguide.html)提供插件。
| |如果你不小心运行了一个 Web 应用程序两次,你会看到一个“端口已在使用”错误。
Spring 工具用户可以使用`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 引导 Maven 插件包括一个`run`目标,该目标可用于快速编译和运行你的应用程序。应用程序以分块的形式运行,就像它们在你的 IDE 中一样。下面的示例显示了用于运行 Spring 引导应用程序的典型 Maven 命令:
```
$ mvn spring-boot:run
```
你可能还希望使用`MAVEN_OPTS`操作系统环境变量,如以下示例所示:
```
$ export MAVEN_OPTS=-Xmx1024m
```
### 7.4.使用 Gradle 插件
Spring boot Gradle 插件还包括一个`bootRun`任务,该任务可用于以扩展形式运行你的应用程序。每当你应用`org.springframework.boot`和`java`插件时,都会添加`bootRun`任务,如下例所示:
```
$ gradle bootRun
```
你可能还希望使用`JAVA_OPTS`操作系统环境变量,如以下示例所示:
```
$ export JAVA_OPTS=-Xmx1024m
```
### 7.5.热交换
Spring 由于引导应用程序是普通的 Java 应用程序,所以 JVM 热交换应该是开箱即用的。JVM 热交换在一定程度上受到它可以替换的字节码的限制。对于更完整的解决方案,可以使用[JRebel](https://www.jrebel.com/products/jrebel)。
`spring-boot-devtools`模块还包括对快速应用程序重启的支持。有关详细信息,请参见[热点交换“操作”](howto.html#howto.hotswapping)。
## 8. 开发工具
Spring 启动包括一组额外的工具,这些工具可以使应用程序的开发体验稍微更愉快一些。`spring-boot-devtools`模块可以包含在任何项目中,以提供额外的开发时功能。要包含 DevTools 支持,请将模块依赖项添加到构建中,如以下 Maven 和 Gradle 的清单所示:
Maven
```
org.springframework.boot
spring-boot-devtools
true
```
Gradle
```
dependencies {
developmentOnly("org.springframework.boot:spring-boot-devtools")
}
```
| |DevTools 可能会导致类加载问题,特别是在多模块项目中。[诊断类加载问题](#using.devtools.diagnosing-classloading-issues)解释了如何诊断和解决它们。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |在运行完全打包的应用程序时,开发人员工具会自动禁用。
如果你的应用程序是从`java -jar`启动的,或者是从一个特殊的类加载器启动的,然后它被认为是一个“生产应用程序”,
你可以通过使用`spring.devtools.restart.enabled`系统属性来控制这种行为,
来启用 DevTools,而不考虑启动应用程序所使用的类加载器,设置`-Dspring.devtools.restart.enabled=true`系统属性。
在运行 DevTools 存在安全风险的生产环境中,不能这样做。
要禁用 DevTools,排除依赖关系或设置`-Dspring.devtools.restart.enabled=false`系统属性。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |在 Maven 中将依赖标记为可选的,或在 Gradle 中使用`developmentOnly`配置(如上图所示),可以防止将 DevTools 传递地应用于使用你的项目的其他模块。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |重新打包的归档文件默认不包含 DevTools。
如果你想使用[某些远程 DevTools 功能](#using.devtools.remote-applications),则需要包含它。
在使用 Maven 插件时,将`excludeDevtools`属性设置为`false`。
在使用 Gradle 插件时,[configure the task’s classpath to include the `developmentOnly` configuration](https://docs.spring.io/spring-boot/docs/2.6.4/gradle-plugin/reference/htmlsingle/#packaging-executable-configuring-including-development-only-dependencies)。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### 8.1.诊断类加载问题
如[重新启动 VS 重新加载](#using.devtools.restart.restart-vs-reload)小节中所述,重新启动功能是通过使用两个类装入器来实现的。对于大多数应用程序来说,这种方法效果很好。然而,它有时会导致类加载问题,特别是在多模块项目中。
要诊断类加载问题是否确实是由 DevTools 及其两个类加载器引起的,[尝试禁用重新启动](#using.devtools.restart.disable)。如果这解决了你的问题,[自定义重新启动类装入器](#using.devtools.restart.customizing-the-classload)将包含你的整个项目。
### 8.2.属性默认值
Spring 引导支持的几个库使用缓存来提高性能。例如,[模板引擎](web.html#web.servlet.spring-mvc.template-engines)缓存已编译的模板,以避免重复解析模板文件。另外, Spring MVC 可以在提供静态资源时将 HTTP 缓存头添加到响应中。
虽然缓存在生产中非常有益,但在开发过程中可能会适得其反,从而使你无法看到刚刚在应用程序中所做的更改。出于这个原因, Spring-boot-devtools 默认禁用缓存选项。
缓存选项通常由`application.properties`文件中的设置来配置。例如,ThymeLeaf 提供`spring.thymeleaf.cache`属性。不需要手动设置这些属性,`spring-boot-devtools`模块会自动应用合理的开发时配置。
由于在开发 Spring MVC 和 Spring WebFlux 应用程序时需要有关 Web 请求的更多信息,因此 Developer Tools 建议你为`DEBUG`日志记录组启用`web`日志记录。这将为你提供有关传入请求的信息、处理该请求的处理程序、响应结果以及其他详细信息。如果希望记录所有请求详细信息(包括可能敏感的信息),可以打开`spring.mvc.log-request-details`或`spring.codec.log-request-details`配置属性。
| |如果不希望应用属性默认值,可以在`application.properties`中将`spring.devtools.add-properties`设置为`false`。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------|
| |有关 DevTools 应用的属性的完整列表,请参见[DevToolsPropertyDefaultSpostProcessor](https://github.com/spring-projects/spring-boot/tree/v2.6.4/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java)。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### 8.3.自动重启
每当 Classpath 上的文件发生更改时,使用`spring-boot-devtools`的应用程序会自动重新启动。在 IDE 中工作时,这可能是一个有用的特性,因为它为代码更改提供了非常快的反馈循环。默认情况下, Classpath 上指向某个目录的任何条目都会被监视以进行更改。请注意,某些资源,例如静态资产和视图模板,[不需要重新启动应用程序](#using.devtools.restart.excluding-resources)。
触发重新启动
由于 DevTools 监视 Classpath 资源,触发重启的唯一方法是更新 Classpath。使 Classpath 更新的方式取决于你使用的 IDE:
* 在 Eclipse 中,保存修改后的文件会导致 Classpath 被更新并触发重新启动。
* 在 IntelliJ IDEA 中,构建项目(“Build++Build 项目”)具有相同的效果。
* 如果使用构建插件,对 Maven 运行`mvn compile`或对 Gradle 运行`gradle build`将触发重新启动。
| |如果使用 Maven 或 Gradle 使用构建插件重新启动,则必须将`forking`设置为`enabled`。
如果禁用分叉,将不会创建 DevTools 使用的隔离应用程序类装入器,并且重新启动将无法正常运行。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |与 LiveReload 一起使用时,自动重启非常有效。[参见 LiveReload 部分](#using.devtools.livereload)有关详细信息。
如果使用 JRebel,自动重启将被禁用,以利于动态类重新加载。
其他 DevTools 功能(例如 LiveReload 和 Property overrides)仍然可以使用。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |DevTools 依赖应用程序上下文的关闭钩子在重新启动时关闭它。
如果你禁用了关闭钩子,它将无法正常工作。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |DevTools 需要自定义`ApplicationContext`所使用的`ResourceLoader`。
如果你的应用程序已经提供了一个,它将被包装。
不支持`getResource`方法上的`getResource`直接覆盖。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |使用 AspectJ 编织时不支持自动重新启动。|
|---|--------------------------------------------------------------|
重新启动 VS 重新加载
Spring Boot 提供的重启技术通过使用两个类装入器来工作。不会更改的类(例如,来自第三方 JAR 的类)被加载到*基座*类装入器中。你正在积极开发的类被加载到*重新启动*类装入器中。当重新启动应用程序时,将丢弃*重新启动*类装入器,并创建一个新的类装入器。这种方法意味着应用程序的重新启动通常比“冷启动”快得多,因为*基座*类装入器已经可用并填充了。
如果你发现应用程序的重新启动速度不够快,或者遇到类加载问题,那么可以考虑重新加载 ZeroTurnaround 中的[JRebel](https://jrebel.com/software/jrebel/)等技术。这些工作是在加载时重写类,以使它们更易于重新加载。
#### 8.3.1.状态评估中的测井变化
默认情况下,每次应用程序重新启动时,都会记录一份显示条件评估增量的报告。当你进行添加或删除 bean 和设置配置属性等更改时,该报告将显示对应用程序自动配置的更改。
要禁用报告的日志记录,请设置以下属性:
属性
```
spring.devtools.restart.log-condition-evaluation-delta=false
```
Yaml
```
spring:
devtools:
restart:
log-condition-evaluation-delta: false
```
#### 8.3.2.不包括资源
某些资源在被更改时不一定需要触发重新启动。例如,胸腺叶模板可以就地编辑。默认情况下,在`/META-INF/maven`、`/META-INF/resources`、`/resources`、`/static`、`/public`或`/templates`中更改资源不会触发重启,但会触发[live reload](#using.devtools.livereload)。如果希望自定义这些排除,可以使用`spring.devtools.restart.exclude`属性。例如,要仅排除`/static`和`/public`,你需要设置以下属性:
属性
```
spring.devtools.restart.exclude=static/**,public/**
```
Yaml
```
spring:
devtools:
restart:
exclude: "static/**,public/**"
```
| |如果你希望保留这些默认值和*添加*附加排除项,请使用`spring.devtools.restart.additional-exclude`属性。|
|---|------------------------------------------------------------------------------------------------------------------------------------------|
#### 8.3.3.观看其他路径
当你对不在 Classpath 上的文件进行更改时,你可能希望你的应用程序被重新启动或重新加载。要做到这一点,请使用`spring.devtools.restart.additional-paths`属性来配置其他路径,以监视更改。你可以使用`spring.devtools.restart.exclude`属性[前面描述的](#using.devtools.restart.excluding-resources)来控制附加路径下方的更改是否触发完全重新启动或[live reload](#using.devtools.livereload)。
#### 8.3.4.禁用重新启动
如果不想使用 Restart 特性,可以使用`spring.devtools.restart.enabled`属性禁用它。在大多数情况下,你可以在`application.properties`中设置此属性(这样做仍然会初始化 Restart 类装入器,但它不会监视文件更改)。
如果需要*完全*禁用重启支持(例如,因为它不能与特定的库一起工作),则需要在调用`spring.devtools.restart.enabled``System`之前将`false`属性设置为`false`,如以下示例所示:
```
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);
}
}
```
#### 8.3.5.使用触发器文件
如果你使用的 IDE 不断编译更改的文件,那么你可能更喜欢只在特定的时间触发重启。要做到这一点,你可以使用“触发器文件”,这是一种特殊的文件,当你想要实际触发重新启动检查时,必须对其进行修改。
| |对该文件的任何更新都会触发检查,但只有在 DevTools 检测到有事情要做时,才会真正重新启动。|
|---|------------------------------------------------------------------------------------------------------------------------------|
要使用触发器文件,请将`spring.devtools.restart.trigger-file`属性设置为触发器文件的名称(不包括任何路径)。触发器文件必须出现在你的 Classpath 上的某个地方。
例如,如果你的项目具有以下结构:
```
src
+- main
+- resources
+- .reloadtrigger
```
那么你的`trigger-file`属性将是:
属性
```
spring.devtools.restart.trigger-file=.reloadtrigger
```
Yaml
```
spring:
devtools:
restart:
trigger-file: ".reloadtrigger"
```
现在只有更新`src/main/resources/.reloadtrigger`时才会重新启动。
| |你可能希望将`spring.devtools.restart.trigger-file`设置为[global setting](#using.devtools.globalsettings),以便所有项目都以相同的方式运行。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
有些 IDE 有一些特性,可以使你不必手动更新触发器文件。[Spring Tools for Eclipse](https://spring.io/tools)和[Intellij Idea(终极版)](https://www.jetbrains.com/idea/)都有这样的支持。使用 Spring 工具,你可以使用控制台视图中的“Reload”按钮(只要你的`trigger-file`被命名为`.reloadtrigger`)。对于 IntelliJ IDEA,你可以遵循[文件中的说明](https://www.jetbrains.com/help/idea/spring-boot.html#application-update-policies)。
#### 8.3.6.自定义重新启动类装入器
如前面[重新启动 VS 重新加载](#using.devtools.restart.restart-vs-reload)小节中所述,重新启动功能是通过使用两个类装入器来实现的。如果这会导致问题,你可能需要定制由哪个类装入器加载的内容。
默认情况下,你的 IDE 中的任何打开的项目都是用“restart”类加载器加载的,而任何常规的`.jar`文件都是用“base”类加载器加载的。如果使用`mvn spring-boot:run`或`gradle bootRun`,情况也是如此:包含`@SpringBootApplication`的项目是用“重新启动”类装入器加载的,其他所有内容都是用“基本”类装入器加载的。
通过创建`META-INF/spring-devtools.properties`文件,你可以指示 Spring boot 使用不同的类装入器加载项目的部分内容。`spring-devtools.properties`文件可以包含以`restart.exclude`和`restart.include`为前缀的属性。`include`元素是应该被拉到“重新启动”类装入器中的项,而`exclude`元素是应该被下推到“基本”类装入器中的项。该属性的值是应用于 Classpath 的正则表达式模式,如以下示例所示:
属性
```
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.`开头,就被认为是唯一的。|
|---|----------------------------------------------------------------------------------------------------------------------------------|
| |Classpath 中的所有`META-INF/spring-devtools.properties`都已加载。
你可以将文件打包到你的项目中,或者打包到项目使用的库中。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 8.3.7.已知限制
对于使用标准`ObjectInputStream`进行反序列化的对象,重启功能不能很好地工作。如果需要反序列化数据,则可能需要结合使用 Spring 的`ConfigurableObjectInputStream`和`Thread.currentThread().getContextClassLoader()`。
遗憾的是,一些第三方库在反序列化时没有考虑上下文类装入器。如果你发现了这样的问题,你需要向原始作者请求修复。
### 8.4.LiveReload
`spring-boot-devtools`模块包括一个嵌入式 LiveReload 服务器,该服务器可用于在更改资源时触发浏览器刷新。LiveReload 浏览器扩展从[livereload.com](http://livereload.com/extensions/)免费提供给 Chrome、Firefox 和 Safari。
如果不想在应用程序运行时启动 LiveReload 服务器,可以将`spring.devtools.livereload.enabled`属性设置为`false`。
| |一次只能运行一个 LiveReload 服务器。
在启动应用程序之前,请确保没有其他 LiveReload 服务器在运行。
如果你从 IDE 启动多个应用程序,则只有第一个应用程序具有 LiveReload 支持。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |要在文件更改时触发 LiveReload,必须启用[自动重启](#using.devtools.restart)。|
|---|--------------------------------------------------------------------------------------------------------|
### 8.5.全局设置
你可以通过向`$HOME/.config/spring-boot`目录中添加以下任意一个文件来配置全局 devtools 设置:
1. `spring-boot-devtools.properties`
2. `spring-boot-devtools.yaml`
3. `spring-boot-devtools.yml`
添加到这些文件中的任何属性都适用于机器上使用 DevTools 的*全部* Spring 引导应用程序。例如,要将 Restart 配置为始终使用[trigger file](#using.devtools.restart.triggerfile),你可以将以下属性添加到`spring-boot-devtools`文件中:
Properties
```
spring.devtools.restart.trigger-file=.reloadtrigger
```
Yaml
```
spring:
devtools:
restart:
trigger-file: ".reloadtrigger"
```
默认情况下,`$HOME`是用户的主目录。要自定义此位置,请设置`SPRING_DEVTOOLS_HOME`环境变量或`spring.devtools.home`系统属性。
| |如果在`$HOME/.config/spring-boot`中未找到 DevTools 配置文件,在`$HOME`目录的根目录中搜索是否存在`.spring-boot-devtools.properties`文件。
这允许你与不支持`$HOME/.config/spring-boot`位置的旧版本 Spring 启动上的应用程序共享 DevTools 全局配置。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |DevTools Properties/YAML 文件不支持配置文件。
在`.spring-boot-devtools.properties`中激活的任何配置文件都不会影响[特定于配置文件的配置文件](features.html#features.external-config.files.profile-specific)的加载。
配置文件特定的文件名(`spring-boot-devtools-.properties`)和`spring.config.activate.on-profile`文件在 YAML 和 Properties 文件中都不受支持。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 8.5.1.配置文件系统监视器
[Filesystemwatcher](https://github.com/spring-projects/spring-boot/tree/v2.6.4/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/FileSystemWatcher.java)的工作原理是轮询具有一定时间间隔的类更改,然后等待预定义的静默期,以确保没有更多更改。由于 Spring 引导完全依赖于 IDE 来编译和复制文件到 Spring 引导可以读取它们的位置,所以当 DevTools 重新启动应用程序时,你可能会发现有时某些更改没有得到反映。如果你经常观察到这样的问题,请尝试将`spring.devtools.restart.poll-interval`和`spring.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"
```
Classpath 监视的目录现在每 2 秒对更改进行一次轮询,并保持 1 秒的静默期,以确保没有额外的类更改。
### 8.6.远程应用程序
Spring 引导开发人员工具不限于本地开发。在远程运行应用程序时,你还可以使用几个功能。远程支持是 OPT 的,因为启用它可能会带来安全风险。只有在运行在受信任的网络上或使用 SSL 进行安全保护时,才应启用它。如果这两个选项都不对你可用,那么你不应该使用 DevTools 的远程支持。你永远不应该在生产部署中启用支持。
要启用它,你需要确保`devtools`包含在重新打包的归档文件中,如以下清单所示:
```
org.springframework.boot
spring-boot-maven-plugin
false
```
然后需要设置`spring.devtools.remote.secret`属性。像任何重要的密码或秘密一样,该值应该是唯一的和强大的,以便它不能被猜测或暴力强迫。
远程 DevTools 支持由两部分提供:接受连接的服务器端端点和在 IDE 中运行的客户机应用程序。设置`spring.devtools.remote.secret`属性后,服务器组件将自动启用。客户端组件必须手动启动。
| |Spring WebFlux 应用程序不支持远程 DevTools。|
|---|-----------------------------------------------------------------|
#### 8.6.1.运行远程客户端应用程序
远程客户机应用程序被设计为在你的 IDE 中运行。你需要以与所连接的远程项目相同的 Classpath 运行`org.springframework.boot.devtools.RemoteSpringApplication`。应用程序唯一需要的参数是它所连接的远程 URL。
例如,如果你正在使用 Eclipse 或 Spring 工具,并且你有一个名为`my-app`的项目已部署到 Cloud Foundry,那么你将执行以下操作:
* 从`Run`菜单中选择`Run Configurations…`。
* 创建一个新的`Java Application`“启动配置”。
* 浏览`my-app`项目。
* 使用`org.springframework.boot.devtools.RemoteSpringApplication`作为主类。
* 将`https://myapp.cfapps.io`添加到`Program arguments`(或你的远程 URL 是什么)。
正在运行的远程客户端可能类似于以下清单:
```
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \
\\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) )
' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / /
=========|_|==============|___/===================================/_/_/_/
:: Spring Boot Remote :: 2.6.4
2015-06-10 18:25:06.632 INFO 14938 --- [ main] o.s.b.devtools.RemoteSpringApplication : Starting RemoteSpringApplication on pwmbp with PID 14938 (/Users/pwebb/projects/spring-boot/code/spring-boot-project/spring-boot-devtools/target/classes started by pwebb in /Users/pwebb/projects/spring-boot/code)
2015-06-10 18:25:06.671 INFO 14938 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.spring[email protected]2a17b7b6: startup date [Wed Jun 10 18:25:06 PDT 2015]; root of context hierarchy
2015-06-10 18:25:07.043 WARN 14938 --- [ main] o.s.b.d.r.c.RemoteClientConfiguration : The connection to http://localhost:8080 is insecure. You should use a URL starting with 'https://'.
2015-06-10 18:25:07.074 INFO 14938 --- [ main] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2015-06-10 18:25:07.130 INFO 14938 --- [ main] o.s.b.devtools.RemoteSpringApplication : Started RemoteSpringApplication in 0.74 seconds (JVM running for 1.105)
```
| |因为远程客户端使用的是与实际应用相同的 Classpath,所以它可以直接读取应用程序属性。
这就是`spring.devtools.remote.secret`属性的读取方式,并将其传递给服务器以进行身份验证。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |始终建议使用`https://`作为连接协议,以便对流量进行加密,并且不能拦截密码。|
|---|--------------------------------------------------------------------------------------------------------------------------------------|
| |如果需要使用代理来访问远程应用程序,请配置`spring.devtools.remote.proxy.host`和`spring.devtools.remote.proxy.port`属性。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 8.6.2.远程更新
远程客户端以与[local restart](#using.devtools.restart)相同的方式监视你的应用程序 Classpath 的更改。任何更新的资源都会被推送到远程应用程序,并(* 如果需要 *)触发重新启动。如果你迭代使用本地没有的云服务的功能,这将很有帮助。通常,远程更新和重启要比完整的重建和部署周期快得多。
在较慢的开发环境中,可能会出现静默期不够的情况,并且类中的更改可能会被分解为批处理。上载第一批类更改后,服务器将重新启动。由于服务器正在重新启动,下一个批处理不能发送到应用程序。
这通常表现为`RemoteSpringApplication`日志中有关于未能上载某些类的警告,以及随后的重试。但这也可能导致应用程序代码不一致,以及在上传第一批更改后无法重新启动。如果你经常观察到这样的问题,请尝试将`spring.devtools.restart.poll-interval`和`spring.devtools.restart.quiet-period`参数增加到适合你的开发环境的值。有关这些属性的配置,请参见[配置文件系统监视器](#using.devtools.globalsettings.configuring-file-system-watcher)小节。
| |只有在远程客户端运行时才会监视文件。
如果在启动远程客户端之前更改了文件,则不会将其推送到远程服务器。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
## 9. 包装你的应用程序以进行生产
可执行 JAR 可用于生产部署。由于它们是自包含的,因此也非常适合基于云的部署。
对于额外的“生产就绪”特性,例如健康状态、审计和度量休息或 JMX 端点,可以考虑添加`spring-boot-actuator`。详见*[actuator.html](actuator.html#actuator)*。
## 10. 接下来读什么?
你现在应该了解如何使用 Spring 引导和一些你应该遵循的最佳实践。你现在可以继续深入了解特定的*[Spring Boot features](features.html#features)*,或者你可以跳过并阅读 Spring 引导的“[生产准备就绪](actuator.html#actuator)”方面。