using.md 59.9 KB
Newer Older
茶陵後's avatar
茶陵後 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851
# 用 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)”方面。