# 用 Spring boot 开发

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

如果你是从 Spring boot 开始的，那么在深入讨论这一部分之前，你可能应该阅读 *[开始](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 框架的基本版本相关联。<br/>我们**高度**建议你不要指定其版本。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------|

### 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`文件类似于以下示例：

```
<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.6.4" />

    <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](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 和兔 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 数据 CouchBase 的启动器|
|[]()`spring-boot-starter-data-couchbase-reactive`|用于使用 CouchBase 面向文档的数据库和 Spring CouchBase 数据库的启动器|
|  []()`spring-boot-starter-data-elasticsearch`   |Spring 用于使用 ElasticSearch 搜索和分析引擎的启动器和数据 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 数据的启动器|
|      []()`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 Reactive 和 Lettuce 客户端|
|       []()`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 的 OAuth2Resource Server 特性的启动器|
|        []()`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’s Actuator 的启动器，它提供了生产就绪功能，可帮助你监视和管理你的应用程序|

最后， 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`]使用的默认 Servlet 容器启动器（# Spring-boot-starter-web）|
|  []()`spring-boot-starter-undertow`   |用于使用 Undertow 作为嵌入式 Servlet 容器的启动器。[`spring-boot-starter-tomcat`]（# Spring-boot-starter- Tomcat）的替代方案）|

要了解如何交换技术方面，请参阅[交换 Web 服务器](howto.html#howto.webserver.use-another)和[测井系统](howto.html#howto.logging.log4j)的操作文档。

|   |有关其他社区贡献的启动器的列表，请参见 Github 上`spring-boot-starters`模块中的[自述文件](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 配置的配置示例。<br/>如果可能的话，总是尝试使用等效的基于 Java 的配置。<br/>搜索`Enable*`注释可以是一个很好的起点。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

### 3.1.导入额外的配置类 ###

你不需要将所有的`@Configuration`都放入一个类中。`@Import`注释可用于导入其他配置类。或者，你可以使用`@ComponentScan`来自动拾取所有 Spring 组件，包括`@Configuration`类。

### 3.2.导入 XML 配置

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

## 4. 自动配置

Spring 引导自动配置尝试基于你已添加的 jar 依赖项自动配置你的 Spring 应用程序。例如，如果`HSQLDB`在你的 Classpath 上，并且你还没有手动配置任何数据库连接 bean，那么 Spring 引导自动配置内存中的数据库。

你需要通过将`@EnableAutoConfiguration`或`@SpringBootApplication`注释添加到你的`@Configuration`类中来 OPT 到自动配置中。

|   |你应该只添加一个`@SpringBootApplication`或`@EnableAutoConfiguration`注释。<br/>我们通常建议你只在主`@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 的方面是可用于禁用自动配置的类的名称，<br/>这些类的实际内容，例如嵌套配置类或 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`的属性。|
|---|------------------------------------------------------------------------------------------------------------------------------|

|   |这些特性都不是强制性的，你可以选择用它启用的任何特性来替换这个注释。<br/>例如，你可能不希望在应用程序中使用组件扫描或配置属性扫描：<br/><br/>```<br/>import org.springframework.boot.SpringApplication;<br/>import org.springframework.boot.SpringBootConfiguration;<br/>import org.springframework.boot.autoconfigure.EnableAutoConfiguration;<br/>import org.springframework.context.annotation.Import;<br/><br/>@SpringBootConfiguration(proxyBeanMethods = false)<br/>@EnableAutoConfiguration<br/>@Import({ SomeConfiguration.class, AnotherConfiguration.class })<br/>public class MyApplication {<br/><br/>    public static void main(String[] args) {<br/>        SpringApplication.run(MyApplication.class, args);<br/>    }<br/><br/>}<br/><br/>```<br/>在此示例中，`MyApplication`就像任何其他 Spring 启动应用程序一样，除了`@Component`-带注释的类和`@Configuration属性`-带注释的类不会自动检测到，并且显式地导入了用户定义的 bean（参见`@Import`）。|
|---| |

## 7. 运行你的应用程序

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

|   |本节只讨论基于 jar 的打包。<br/>如果你选择将应用程序打包为 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 为[各种 IDE](https://docs.gradle.org/current/userguide/userguide.html)提供插件。

|   |如果你不小心运行了一个 Web 应用程序两次，你会看到一个“Port Already in Use”错误。<br/> Spring Tools 用户可以使用`Relaunch`按钮，而不是`Run`按钮，以确保任何现有实例都已关闭。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

### 7.2.以打包应用程序的形式运行

如果使用 Spring 引导 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

```
<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")
}
```

|   |DevTools 可能会导致类加载问题，特别是在多模块项目中。[诊断类加载问题](#using.devtools.diagnosing-classloading-issues)解释了如何诊断和解决它们。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

|   |在运行完全打包的应用程序时，开发人员工具会自动禁用。<br/>如果你的应用程序是从`java -jar`启动的，或者是从一个特殊的类加载器启动的，然后，它被认为是一个“生产应用程序”，<br/>你可以通过使用`spring.devtools.restart.enabled`系统属性来控制这种行为，<br/>可以启用 DevTools，而不考虑启动应用程序所使用的类装入器，设置`-Dspring.devtools.restart.enabled=true`系统属性。<br/>在运行 DevTools 存在安全风险的生产环境中，不能这样做。<br/>要禁用 DevTools，排除依赖关系或设置`-Dspring.devtools.restart.enabled=false`系统属性。|
|---| |

|   |在 Maven 中将依赖标记为可选的，或者在 Gradle 中使用`developmentOnly`配置（如上图所示），可以防止将 DevTools 传递地应用于使用你的项目的其他模块。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

|   |重新打包的归档文件默认情况下不包含 DevTools。<br/>如果你想使用[某些远程 DevTools 功能](#using.devtools.remote-applications)，则需要包含它。<br/>在使用 Maven 插件时，将`excludeDevtools`属性设置为`false`。在使用 Gradle 插件时，<br/>，[将任务的 Classpath 配置为包括`developmentOnly`配置]（https://DOCS. Spring.io/ Spring-boot/DOCS/2.6.4/ Gradle-plugin/reference/htmlsingle/#packaging-executable-configuring-inuiting-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 Project`）具有相同的效果。

* 如果使用构建插件，对 Maven 运行`mvn compile`或对 Gradle 运行`gradle build`将触发重新启动。

|   |如果使用 Maven 或 Gradle 使用构建插件重新启动，则必须将`forking`设置为`enabled`。<br/>如果禁用分叉，将不会创建 DevTools 使用的隔离应用程序类装入器，并且重新启动将无法正常运行。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

|   |当与 LiveReload 一起使用时，自动重启非常有效。[参见 LiveReload 部分](#using.devtools.livereload)有关详细信息。<br/>如果使用 JRebel，自动重启将被禁用，以利于动态类重新加载。<br/>其他 DevTools 功能（例如 LiveReload 和 Property overrides）仍然可以使用。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

|   |DevTools 依赖应用程序上下文的关机钩子在重新启动时关闭它。<br/>如果禁用了关机钩子（`SpringApplication.setRegisterShutdownHook(false)`），它将无法正常工作。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

|   |DevTools 需要自定义`ApplicationContext`所使用的`ResourceLoader`。<br/>如果你的应用程序已经提供了一个，它将被包装。<br/>不支持`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`中更改资源不会触发重启，但会触发[实时重新加载](#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)来控制附加路径下方的更改是否触发完全重新启动或[实时重新加载](#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`设置为[全局设置](#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"
```

|   |所有属性键必须是唯一的。<br/>只要一个属性以`restart.include.`或`restart.exclude.`开头，就被认为是唯一的。|
|---|----------------------------------------------------------------------------------------------------------------------------------|

|   |Classpath 中的所有`META-INF/spring-devtools.properties`都已加载。<br/>你可以将文件打包到你的项目中，或者打包到项目使用的库中。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|

#### 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 服务器。<br/>在启动应用程序之前，请确保没有其他 LiveReload 服务器在运行。<br/>如果你从 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 配置为始终使用[触发器文件](#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`文件。<br/>这允许你与不支持`$HOME/.config/spring-boot`位置的旧版本 Spring 启动上的应用程序共享 DevTools 全局配置。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

|   |在 DevTools Properties/YAML 文件中不支持配置文件。<br/><br/>在`.spring-boot-devtools.properties`中激活的任何配置文件都不会影响[特定于配置文件的配置文件](features.html#features.external-config.files.profile-specific)的加载。<br/>配置文件特定的文件名（`spring-boot-devtools-<profile>.properties`）和`spring.config.activate.on-profile`文件在 YAML 和属性文件中都不受支持。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

#### 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`包含在重新打包的归档文件中，如以下清单所示：

```
<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`属性。像任何重要的密码或秘密一样，该值应该是唯一的和强大的，以便它不能被猜测或暴力强迫。

远程 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 因为远程客户端使用的是与实际应用相同的应用程序，所以它可以直接读取应用程序属性。<br/>这就是`spring.devtools.remote.secret`属性的读取方式，并将其传递给服务器以进行身份验证。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

|   |始终建议使用`https://`作为连接协议，以便对流量进行加密，并且不能拦截密码。|
|---|--------------------------------------------------------------------------------------------------------------------------------------|

|   |如果需要使用代理来访问远程应用程序，请配置`spring.devtools.remote.proxy.host`和`spring.devtools.remote.proxy.port`属性。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------|

#### 8.6.2.远程更新

远程客户端以与[本地重启](#using.devtools.restart)相同的方式监视你的应用程序 Classpath 的更改。任何更新的资源都会被推送到远程应用程序，并（* 如果需要 *）触发重新启动。如果你迭代使用本地不具备的云服务的功能，这将很有帮助。通常，远程更新和重启要比完整的重建和部署周期快得多。

在较慢的开发环境中，可能会出现静默期不够的情况，并且类中的更改可能会被分解为批处理。上载第一批类更改后，服务器将重新启动。由于服务器正在重新启动，下一个批处理不能发送到应用程序。

这通常表现为`RemoteSpringApplication`日志中有关于未能上载某些类的警告，以及随后的重试。但这也可能导致应用程序代码不一致，以及在上传第一批更改后无法重新启动。如果你经常观察到这样的问题，请尝试将`spring.devtools.restart.poll-interval`和`spring.devtools.restart.quiet-period`参数增加到适合你的开发环境的值。有关这些属性的配置，请参见[配置文件系统监视器](#using.devtools.globalsettings.configuring-file-system-watcher)小节。

|   |只有在远程客户端运行时才会监视文件。<br/>如果在启动远程客户端之前更改了文件，则不会将其推送到远程服务器。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------|

## 9. 包装你的应用程序以进行生产

可执行 JAR 可用于生产部署。由于它们是自包含的，因此也非常适合基于云的部署。

对于额外的“生产就绪”特性，例如健康状态、审计和度量休息或 JMX 端点，可以考虑添加`spring-boot-actuator`。详见 *[actuator.html](actuator.html#actuator)*。

## 10. 接下来要读什么？

你现在应该了解如何使用 Spring 引导和一些你应该遵循的最佳实践。你现在可以继续深入了解特定的 *[Spring Boot features](features.html#features)*，或者你可以跳过并阅读 Spring boot 的“[生产准备就绪](actuator.html#actuator)”方面。
