Spring Boot启动参考指南(官方版)

java 同时被 3 个专栏收录
51 篇文章 2 订阅
35 篇文章 0 订阅
12 篇文章 1 订阅

Spring Boot启动参考指南

作者

Phillip Webb, Dave Syer, Josh Long, Stéphane Nicoll, Rob Winch, Andy Wilkinson, Marcel Overdijk, Christian Dupuis, Sébastien Deleuze, Michael Simons, VedranPavić, Jay Bryant, Madhura Bhave

2.1.0.BUILD-SNAPSHOT

版权(2012-2018年)

本文件的副本可供你自己使用及分发给他人,但你无须就该等副本收取任何费用,而每一份副本均须载有本版权公告,不论是以印刷形式或以电子方式分发。


目录

第一部分.Spring启动文档

1.关于文件

2.寻求帮助

3.第一步

4.使用SpringBoot

5.学习Spring启动特性

6.转向生产

7.高级专题

第二部分。开始

8.介绍弹簧启动

9.系统要求

9.1 servlet容器

10.安装弹簧启动

10.1 Java开发人员的安装说明

10.1.1 Maven安装

10.1.2分级安装

10.2安装SpringBootCLI

10.2.1手动安装

10.2.2用SDKMAN安装!

10.2.3 OSX自制设备

10.2.4 MacPorts安装

10.2.5指挥线完成

10.2.6 Windows SCOOP安装

10.2.7快速启动SpringCLI示例

10.3从较早版本的SpringBoot升级

11.开发您的第一个SpringBoot应用程序

11.1创建POM

11.2添加类路径依赖项

11.3编写守则

11.3.1@RestController和@Requestmap注释

11.3.2@EnableAutoConfiguration注释

11.3.3“主要”方法

11.4运行示例

11.5创建可执行的JAR

12.接下来要读什么?

第三部分。使用Spring Boot

13.构建系统

13.1抚养管理

13.2 Maven

13.2.1继承初学者父母

13.2.2在没有父POM的情况下使用SpringBoot

13.2.3使用SpringBootMaven插件

13.3级

13.4蚂蚁

13.5启动器

14.构造代码

14.1使用“默认”包

14.2定位主应用程序类

15.配置类

15.1导入其他配置类

15.2导入XML配置

16.自动配置

16.1逐步取代自动配置

16.2禁用特定的自动配置类

17.Springbean和依赖注入

18.使用@SpringBootApplication注释

19.运行您的应用程序

19.1从IDE运行

19.2作为打包应用程序运行

19.3使用Maven插件

19.4使用Gradle插件

19.5热交换

20.开发工具

20.1财产违约

20.2自动重启

20.2.1状态评估中的测井变化

20.2.2不包括资源

20.2.3观察其他路径

20.2.4禁用重新启动

20.2.5使用触发器文件

20.2.6自定义重新启动类加载程序

20.2.7已知限制

20.3 LiveReload

20.4全球设置

20.5远程应用程序

20.5.1运行远程客户端应用程序

20.5.2远程更新

21.包装生产申请

22.接下来要读什么?

第四部分。弹簧启动功能

23.Spring应用

23.1启动失败

23.2定制横幅

23.3定制Spring应用程序

23.4 FLUENT BuilderAPI

23.5应用程序事件和侦听器

23.6网络环境

23.7访问应用程序参数

23.8使用ApplicationRunner或CommandLineRunner

23.9申请出口

23.10行政特点

24.外化配置

24.1配置随机值

24.2访问命令行属性

24.3应用程序属性文件

24.4剖面特性

24.5属性中的占位符

24.6使用YAML代替属性

24.6.1装载YAML

24.6.2在Spring环境中将YAML公开为属性

24.6.3多概况YAML文件

24.6.4 YAML缺陷

24.7类型安全配置属性

24.7.1第三方配置

24.7.2放宽约束力

24.7.3合并复杂类型

24.7.4属性转换

24.7.5@ConfigurationProperties验证

24.7.6@ConfigurationProperties与@Value

25.剖面图

25.1添加活动概要文件

25.2以编程方式设置概要文件

25.3配置文件-特定配置文件

26.测井

26.1日志格式

26.2控制台输出

26.2.1彩色编码输出

26.3文件输出

26.4原木水平

26.5原木组

26.6自定义日志配置

26.7 Logback扩展

26.7.1配置文件-特定配置

26.7.2环境特性

27.开发Web应用程序

27.1“SpringWebMVC框架”

27.1.1 SpringMVC自动配置

27.1.2 HttpMessage转换器

27.1.3自定义JSON序列化程序和反序列化器

27.1.4消息代码解析器

27.1.5静态含量

27.1.6欢迎页

27.1.7海关偏袒

27.1.8路径匹配和内容协商

27.1.9 ConfigurableWebBindingInitiators

27.1.10模板引擎

27.1.11错误处理

27.1.12弹簧

27.1.13 CORS支持

27.2“SpringWebFlux框架”

27.2.1 SpringWebFlux自动配置

27.2.2带有HttpMessageReader和HttpMessageWriters的HTTP编解码器

27.2.3静态含量

27.2.4模板引擎

27.2.5错误处理

27.2.6 Web过滤器

27.3日航-斯普斯卡共和国和泽西岛

27.4嵌入式Servlet容器支持

27.4.1 servlet、过滤器和侦听器

27.4.2 servlet上下文初始化

27.4.3 ServletWebServerApplicationContext

27.4.4定制嵌入式servlet容器

27.4.5 JSP限制

28.保安

28.1 MVC安全性

28.2 WebFlux安全

28.3 OAuth2

28.3.1客户

28.3.2资源服务器

28.3.3授权服务器

28.4执行器安全

28.4.1跨站点请求伪造保护

29.使用SQL数据库

29.1配置数据源

29.1.1嵌入式数据库支持

29.1.2连接到生产数据库

29.1.3连接到JNDI数据源

29.2使用JdbcTemplate

29.3 JPA和Spring Data JPA

29.3.1实体类

29.3.2 Spring数据JPA存储库

29.3.3创建和删除JPA数据库

29.3.4视图中的OpenEntityManager

29.4 Spring数据JDBC

29.5使用H2的Web控制台

29.5.1更改H2控制台的路径

29.6使用jOOQ

29.6.1代码生成

29.6.2使用DSLContext

29.6.3 jOOQ SQL方言

29.6.4定制jOOQ

三十使用NoSQL技术

30.1 Redis

30.1.1连接到Redis

30.2 MongoDB

30.2.1连接到MongoDB数据库

30.2.2蒙古板

30.2.3 Spring数据MongoDB存储库

30.2.4嵌入式MONGO

30.3 Neo4j

30.3.1连接到Neo4j数据库

30.3.2使用嵌入式模式

30.3.3 Neo4jSession

30.3.4 Spring数据Neo4j存储库

30.4双子火

30.5 Solr

30.5.1连接到Solr

30.5.2 Spring数据Solr存储库

30.6弹性搜索

30.6.1通过REST客户端连接到弹性搜索

30.6.2使用JEST连接到弹性搜索

30.6.3使用Spring数据连接弹性搜索

30.6.4 Spring数据弹性搜索库

30.7卡桑德拉

30.7.1连接卡桑德拉

30.7.2 Spring数据库

30.8 Couchbase

30.8.1连接到Couchbase

30.8.2 Spring数据库

30.9 LDAP

30.9.1连接到LDAP服务器

30.9.2 Spring数据LDAP存储库

30.9.3嵌入式内存LDAP服务器

30.10 InfluxDB

30.10.1连接到InfluxDB

31.缓存

31.1支持缓存提供者

31.1.1通用

31.1.2 JCache(JSR-107)

31.1.3 EhCache 2.x

31.1.4哈泽尔广播公司

31.1.5无限

31.1.6 Couchbase

31.1.7 Redis

31.1.8咖啡因

31.1.9简单

31.1.10无

三十二信息传递

32.1 JMS

32.1.1 ActiveMQ支持

32.1.2 Artemis支持

32.1.3使用JNDI连接工厂

32.1.4发送消息

32.1.5接收消息

32.2 AMQP

32.2.1兔MQ支持

32.2.2发送消息

32.2.3接收消息

32.3 Apache Kafka支持

32.3.1发送信息

32.3.2接收消息

32.3.3 Kafka流

32.3.4额外的Kafka属性

33.调用REST服务RestTemplate

33.1餐厅模板定制

34.调用REST服务WebClient

34.1 WebClient运行时

34.2 Web客户端定制

35.验证

36.发送电子邮件

37.使用JTA的分布式事务

37.1使用Atomikos事务管理器

37.2使用Bitronix事务管理器

37.3使用JavaEE托管事务管理器

37.4混合XA和非XA JMS连接

37.5支持替代嵌入式事务管理器

38.哈泽尔卡斯特

39.石英调度器

四十任务执行和调度

41.弹簧集成

42.春季会议

43.对JMX的监测和管理

44.测试

44.1测试范围依赖项

44.2测试Spring应用程序

44.3测试SpringBoot应用程序

44.3.1检测Web应用程序类型

44.3.2检测测试配置

44.3.3不包括测试配置

44.3.4用模拟环境进行测试

44.3.5使用运行中的服务器进行测试

44.3.6使用JMX

44.3.7嘲弄和间谍豆

44.3.8自动配置测试

44.3.9自动配置的JSON测试

44.3.10自动配置的SpringMVC测试

44.3.11自动配置的SpringWebFlux测试

44.3.12自动配置的数据JPA测试

44.3.13自动配置的JDBC测试

44.3.14自动配置的数据JDBC测试

44.3.15自动配置的jOOQ测试

44.3.16自动配置的数据MongoDB测试

44.3.17自动配置的数据Neo4j测试

44.3.18自动配置的数据Redis测试

44.3.19自动配置的数据LDAP测试

44.3.20自动配置的REST客户端

44.3.21自动配置的SpringREST文档测试

44.3.22附加自动配置和切片

44.3.23用户配置和切片

44.3.24使用Spock测试SpringBoot应用程序

44.4测试实用程序

44.4.1 ConfigFileApplicationContextInitiizer

44.4.2 TestPropertyValue

44.4.3产出捕获

44.4.4 TestRestTemplate

45.WebSocket

46.Web服务

47.调用Web服务WebServiceTemplate

48.创建自己的自动配置

48.1理解自动配置bean

48.2自动配置候选人的位置

48.3条件注释

48.3.1类条件

48.3.2豆子条件

48.3.3财产条件

48.3.4资源条件

48.3.5 Web应用条件

48.3.6 Spel表达条件

48.4测试您的自动配置

48.4.1模拟Web上下文

48.4.2凌驾于Classpath之上

48.5创建自己的初学者

48.5.1命名

48.5.2 autoconfigure模块

48.5.3启动模块

49.Kotlin支持

49.1所需经费

49.2零-安全

49.3 Kotlin API

49.3.1运行应用程序

49.3.2扩展

49.4抚养管理

49.5 @ConfigurationProperties

49.6测试

49.7资源

49.7.1进一步阅读

49.7.2例子

五十接下来要读什么?

第五部分弹簧启动执行器:可生产的特性

51.启用生产准备功能

52.端点

52.1启用端点

52.2暴露终结点

52.3保护HTTP端点

52.4配置终结点

52.5用于执行器Web端点的超媒体

52.6 CORS支助

52.7实现自定义端点

52.7.1接收输入

52.7.2自定义Web终结点

52.7.3 servlet端点

52.7.4主计长端点

52.8卫生信息

52.8.1自动配置的HealthIndicator

52.8.2书写自定义健康指示器

52.8.3反应性健康指标

52.8.4自动配置的ReactiveHealthIndicator

52.9申请资料

52.9.1自动配置的InfoContributor

52.9.2自定义应用程序信息

52.9.3 Git提交信息

52.9.4构建信息

52.9.5编写自定义信息贡献者

53.HTTP上的监控与管理

53.1自定义管理端点路径

53.2自定义管理服务器端口

53.3配置特定于管理的SSL

53.4自定义管理服务器地址

53.5禁用HTTP端点

54.对JMX的监测和管理

54.1定制MBean名称

54.2禁用JMX端点

54.3通过HTTP为JMX使用Jolokia

54.3.1定制Jolokia

54.3.2禁用Jolokia

55.伐木工

55.1配置记录器

56.度量标准

56.1开始

56.2支持的监测系统

56.2.1 Atlas

56.2.2 Datadog

56.2.3 Dynatraces

56.2.4弹性

56.2.5神经节

56.2.6石墨

56.2.7流入

56.2.8 JMX

56.2.9新文物

56.2.10普罗米修斯

56.2.11 SignalFx

56.2.12简单

56.2.13国家统计d

56.2.14波前

56.3支助计量

56.3.1 SpringMVC度量

56.3.2 SpringWebFlux度量

56.3.3 HTTP客户端度量

56.3.4缓存度量

56.3.5数据源度量

56.3.6冬眠度量

56.3.7兔MQ计量

56.4注册自定义指标

56.5定制个人指标

56.5.1通用标签

每米56.5.2

56.6计量终点

57.审计

58.http跟踪

58.1自定义HTTP跟踪

59.过程监测

59.1扩展配置

59.2以编程方式

六十云铸造支架

60.1禁用扩展云铸造驱动器支持

60.2云铸造公司自签证书

60.3自定义上下文路径

61.接下来要读什么?

第六部分。部署SpringBoot应用程序

62.部署到云端

62.1云铸造

62.1.1绑定到服务

62.2 Heroku

62.3 OpenShift

62.4亚马逊网络服务(AWS)

62.4.1 AWS弹性豆柄

62.4.2摘要

62.5 BOXFUSE和AmazonWeb服务

62.6谷歌云

63.安装SpringBoot应用程序

63.1支持的操作系统

63.2 Unix/Linux服务

63.2.1安装为init.d服务(系统五)

63.2.2安装为systemd服务

63.2.3自定义启动脚本

63.3微软Windows服务

64.接下来要读什么?

第七部分弹簧启动CLI

65.安装CLI

66.使用CLI

66.1使用CLI运行应用程序

66.1.1推导出“抓取”属地

66.1.2推导出“抓取”坐标

66.1.3默认导入语句

66.1.4自动主法

66.1.5自定义依赖关系管理

66.2具有多源文件的应用程序

66.3包装您的应用程序

66.4启动一个新项目

66.5使用嵌入式Shell

66.6向CLI添加扩展

67.使用GroovyBeans DSL开发应用程序

68.配置CLIsettings.xml

69.接下来要读什么?

第八编构建工具插件

70.Spring Boot Maven插件

70.1包括插件

70.2包装可执行罐和战争文件

71.弹簧启动级插件

72.弹簧启动AntLib模块

72.1 Spring启动Ant任务

72.1.1 spring-boot:exejar

72.1.2实例

72.2 spring-boot:findmainclass

72.2.1实例

73.支持其他构建系统

73.1重新包装档案馆

73.2嵌套库

73.3找到主修班

73.4重新包装实现示例

74.接下来要读什么?

第九编“How-to”指南

75.弹簧引导应用

75.1创建自己的FailureAnalyzer

75.2自动配置故障排除

75.3在环境或ApplicationContext启动之前定制它

75.4构建ApplicationContext层次结构(添加父上下文或根上下文)

75.5创建一个非web应用程序

76.属性和配置

76.1在构建时自动展开属性

76.1.1使用Maven自动扩展属性

76.1.2使用分级自动扩展属性

76.2外部化SpringApplication

76.3更改应用程序外部属性的位置

76.4使用“短”命令行参数

76.5将YAML用于外部属性

76.6设置活动Spring配置文件

76.7根据环境变化配置

76.8发现外部属性的内置选项

77.嵌入式Web服务器

77.1使用另一个Web服务器

77.2禁用Web服务器

77.3更改HTTP端口

77.4使用随机未分配的HTTP端口

77.5在运行时发现HTTP端口

77.6启用HTTP响应压缩

77.7配置SSL

77.8配置HTTP/2

77.8.1带有以下内容的HTTP/2

77.8.2HTTP/2与Jetty

使用Tomcat的77.8.3 HTTP/2

77.8.4带有反应堆Netty的HTTP/2

77.9配置Web服务器

77.10向应用程序添加servlet、过滤器或侦听器

77.10.1使用SpringBean添加servlet、过滤器或侦听器

77.10.2使用Classpath扫描添加servlet、过滤器和侦听器

77.11配置访问日志记录

77.12运行在前端代理服务器后面

77.12.1自定义Tomcat的代理配置

77.13使用Tomcat启用多个连接器

77.14使用Tomcat的LegacyCookieProcessor

77.15使用以下方式启用多个侦听器

77.16使用@ServerEndpoint创建WebSocketEndpoint

78.SpringMVC

78.1编写JSON REST服务

78.2编写XML REST服务

78.3自定义Jackson ObjectMapper

78.4自定义@ResponseBody呈现

78.5处理多部分文件上载

78.6关闭SpringMVC DispatcherServlet

78.7关闭默认MVC配置

78.8自定义视图转换器

79.用Spring安全性进行测试

80.泽西

80.1使用Spring安全保护泽西端点

81.http客户端

81.1配置RestTemplate以使用代理

82.测井

82.1为日志配置Logback

82.1.1为纯文件输出配置Logback

82.2配置用于日志记录的Log4j

82.2.1使用YAML或JSON配置Log4j 2

83.数据存取

83.1配置自定义数据源

83.2配置两个DataSources

83.3使用Spring数据存储库

83.4将@实体定义与Spring配置分开

83.5配置JPA属性

83.6配置Hibernate命名策略

83.7使用自定义EntityManagerFactory

83.8使用两个实体管理器

83.9使用传统persistence.xml档案

83.10使用Spring数据JPA和MONGO存储库

83.11将Spring数据存储库公开为REST端点

83.12配置JPA使用的组件

83.13用两个DataSources配置jOOQ

84.数据库初始化

84.1使用JPA初始化数据库

84.2使用Hibernate初始化数据库

84.3初始化数据库

84.4初始化Spring批处理数据库

84.5使用高级数据库迁移工具

84.5.1启动时执行天桥数据库移动

84.5.2启动时执行Liquibase数据库迁移

85.信息传递

85.1禁用事务JMS会话

86.批处理应用程序

86.1启动时执行Spring批处理作业

87.致动器

87.1更改执行器端点的HTTP端口或地址

87.2自定义“白色标签”错误页

87.3消毒敏感值

88.保安

88.1关闭SpringBoot安全配置

88.2更改UserDetailsService并添加用户帐户

88.3在代理服务器后面运行时启用HTTPS

89.热交换

89.1重新发布静态内容

89.2在不重新启动容器的情况下重新发布模板

89.2.1 Thymeleaf模板

89.2.2 FreeMarker模板

89.2.3 Groovy模板

89.3快速应用程序重新启动

89.4不重新启动容器的Reload Java类

90.建房

90.1生成信息

90.2生成Git信息

90.3自定义依赖项版本

90.4用Maven创建可执行的JAR

90.5使用SpringBoot应用程序作为依赖项

90.6在可执行JAR运行时提取特定库

90.7创建一个包含排除的不可执行JAR。

90.8远程调试从Maven启动的SpringBoot应用程序

90.9在不使用Ant的情况下从Ant构建可执行存档spring-boot-antlib

91.传统部署

91.1创建可部署的战争文件

91.2将现有应用程序转换为SpringBoot

91.3将战争部署到WebLogic

91.4用吉迪斯代替生菜

第十部分附录

附录A.共同应用属性

附录B.配置元数据

B.1元数据格式

B.1.1组属性

B.1.2属性

B.1.3暗示属性

B.1.4重复元数据项目

B.2提供手册提示

B.2.1值提示

B.2.2价值提供者

B.3使用注释处理器生成自己的元数据

B.3.1嵌套属性

B.3.2添加额外元数据

附录C.自动配置类

c.1来自“Spring-启动-自动配置”模块

c.2来自“弹簧-启动-驱动器-自动配置”模块

附录D.测试自动配置注释

附录E.可执行的JAR格式

E.1嵌套JAR

E.1.1可执行的JAR文件结构

E.1.2可执行的战争档案结构

E.2 Spring Boot的“JarFile”类

E.2.1与标准Java“JarFile”的兼容性

E.3发射可执行的JAR

E.3.1发射器清单

E.3.2爆炸档案

E.4PropertiesLauncher特征

E.5可执行的Jar限制

E.6可供选择的单罐解决方案

附录F.受抚养人版本


第一部分.Spring启动文档

本节简要概述SpringBoot参考文档。它用作文档其余部分的地图。

1.关于文件

SpringBoot参考指南如下所示

最新的副本可在docs.spring.io/spring-boot/docs/current/reference.

本文件的副本可供你自己使用及分发给他人,但你无须就该等副本收取任何费用,而每一份副本均须载有本版权公告,不论是以印刷形式或以电子方式分发。

2.寻求帮助

如果你对SpringBoot有问题,我们愿意帮忙。

[Note]

所有SpringBoot都是开源的,包括文档。如果你发现文档有问题,或者你想改进它们,请介入.

3.第一步

如果您要开始使用SpringBoot或“Spring”,请从以下主题:

4.使用SpringBoot

准备好真正开始使用SpringBoot了吗?我们保护了你:

5.学习Spring启动特性

需要更多关于SpringBoot核心功能的详细信息吗?以下内容是给您的:

6.转向生产

当您准备将SpringBoot应用程序推向生产时,我们有一些技巧你可能会喜欢:

7.高级专题

最后,我们为更高级的用户提供了一些主题:

第二部分。开始

如果您要开始使用SpringBoot或一般的“Spring”,请从阅读本节开始。它回答了基本的“什么?”“怎么做”还有“为什么”问题。它包括对SpringBoot的介绍,以及安装说明。然后,我们将引导您构建您的第一个SpringBoot应用程序,同时讨论一些核心原则。

8.介绍弹簧启动

SpringBoot使得创建独立的、生产级的基于Spring的应用程序变得很容易,您可以运行这些应用程序。我们对Spring平台和第三方库有一个独断专行的看法,这样您就可以最小的小题大做开始了。大多数SpringBoot应用程序只需要很少的Spring配置。

可以使用SpringBoot创建可以通过以下方式启动的Java应用程序java -jar或者更传统的战争部署。我们还提供了一个运行“Spring脚本”的命令行工具。

我们的主要目标是:

  • 为所有Spring开发提供一个快速的、可广泛访问的入门体验。
  • 不要太固执己见,但当需求开始偏离缺省值时,请尽快离开。
  • 提供大类项目(如嵌入式服务器、安全性、度量、健康检查和外部化配置)常见的一系列非功能特性。
  • 绝对不需要生成代码,也不需要XML配置。

9.系统要求

SpringBoot2.1.0 BUILD-快照要求Java 8或9Spring Framework 5.1.0.RELEASE或者更高。

为下列构建工具提供了显式构建支持:

构建工具版本

马文

3.3+

梯度

4.4+

9.1 servlet容器

SpringBoot支持以下嵌入式servlet容器:

名字,姓名Servlet版本

Tomcat 9.0

4.0

Jetty 9.4

3.1

Undertow 2.0

4.0

您还可以将SpringBoot应用程序部署到任何与Servlet3.1+兼容的容器中。

10.安装弹簧启动

SpringBoot可以与“经典”Java开发工具一起使用,也可以作为命令行工具安装。不管怎样,你需要Java SDK v1.8或者更高。在开始之前,应该使用以下命令检查当前的Java安装:

$ java -version

如果您是Java开发新手,或者您想尝试SpringBoot,您可能需要尝试弹簧启动CLI(命令行接口)。否则,继续阅读“经典”安装说明。

10.1 Java开发人员的安装说明

您可以与任何标准Java库相同的方式使用SpringBoot。为此,请包括适当的spring-boot-*.jar你的类路径上的文件。SpringBoot不需要任何特殊的工具集成,所以您可以使用任何IDE或文本编辑器。此外,SpringBoot应用程序没有什么特别之处,因此您可以像其他Java程序一样运行和调试SpringBoot应用程序。

虽然你复制SpringBootJars,我们通常建议您使用支持依赖管理(如Maven或Gradle)的构建工具。

10.1.1 Maven安装

SpringBoot与ApacheMaven 3.3或更高版本兼容。如果您还没有安装Maven,可以按照maven.apache.org.

[Tip]

在许多操作系统上,Maven可以安装包管理器。如果您使用OSX自制,请尝试brew install maven。Ubuntu用户可以运行sudo apt-get install maven。Windows用户巧克力能跑choco install maven从提升的(管理员)提示符。

Spring引导依赖项使用org.springframework.boot groupId。通常,Maven POM文件从spring-boot-starter-parent项目并将依赖项声明为一个或多个。“起步者”。SpringBoot还提供了一个可选的Maven插件若要创建可执行的JAR,请执行以下操作。

下面的清单显示了一个典型的pom.xml档案:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.example</groupId>
	<artifactId>myproject</artifactId>
	<version>0.0.1-SNAPSHOT</version>

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

	<!-- Add typical dependencies for a web application -->
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	</dependencies>

	<!-- Package as an executable jar -->
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

	<!-- Add Spring repositories -->
	<!-- (you don't need this if you are using a .RELEASE version) -->
	<repositories>
		<repository>
			<id>spring-snapshots</id>
			<url>https://repo.spring.io/snapshot</url>
			<snapshots><enabled>true</enabled></snapshots>
		</repository>
		<repository>
			<id>spring-milestones</id>
			<url>https://repo.spring.io/milestone</url>
		</repository>
	</repositories>
	<pluginRepositories>
		<pluginRepository>
			<id>spring-snapshots</id>
			<url>https://repo.spring.io/snapshot</url>
		</pluginRepository>
		<pluginRepository>
			<id>spring-milestones</id>
			<url>https://repo.spring.io/milestone</url>
		</pluginRepository>
	</pluginRepositories>
</project>
[Tip]

这,这个,那,那个spring-boot-starter-parent是使用SpringBoot的一种很好的方式,但它可能并不总是合适的。有时,您可能需要从不同的父POM继承,或者您可能不喜欢我们的默认设置。在这种情况下,请参见第13.2.2节,“在没有父POM的情况下使用Spring Boot”对于使用import瞄准镜。

10.1.2分级安装

SpringBoot与Gradle 4.4及更高版本兼容。如果您还没有安装Gradle,可以按照gradle.org.

属性可以声明Spring启动依赖项。org.springframework.boot group。通常,项目将依赖项声明为一个或多个。“起步者”。Spring Boot提供了一个有用的Gradle插件它可以用来简化依赖声明和创建可执行的JAR。

梯度包装

当您需要构建一个项目时,Gradle包装提供了一种很好的“获取”Gradle的方法。这是一个很小的脚本和库,您可以将其与代码一起用于引导构建过程。看见docs.gradle.org/4.2.1/userguide/gradle_wrapper.html关于细节。

下面的示例显示了一个典型的build.gradle档案:

buildscript {
	repositories {
		jcenter()
		maven { url 'https://repo.spring.io/snapshot' }
		maven { url 'https://repo.spring.io/milestone' }
	}
	dependencies {
		classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.1.0.BUILD-SNAPSHOT'
	}
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

jar {
	baseName = 'myproject'
	version =  '0.0.1-SNAPSHOT'
}

repositories {
	jcenter()
	maven { url "https://repo.spring.io/snapshot" }
	maven { url "https://repo.spring.io/milestone" }
}

dependencies {
	compile("org.springframework.boot:spring-boot-starter-web")
	testCompile("org.springframework.boot:spring-boot-starter-test")
}

10.2安装SpringBootCLI

SpringBootCLI(命令行接口)是一个命令行工具,您可以使用它快速地使用Spring进行原型。它让你跑Groovy脚本,这意味着您有一个熟悉的类似Java的语法,而没有那么多样板代码。

您不需要使用CLI来使用SpringBoot,但这绝对是获得Spring应用程序的最快方法。

10.2.1手动安装

您可以从Spring软件存储库下载SpringCLI发行版:

刀刃快照分布也是可用的。

下载后,按照INSTALL.txt解压档案的说明。总之,有一个spring脚本(spring.bat)中的bin/目录中的.zip档案。或者,您可以使用java -jar带着.jar文件(脚本帮助您确保正确设置了类路径)。

10.2.2用SDKMAN安装!

SDKMAN!(SoftwareDevelopmentKitManager)可用于管理各种二进制SDK的多个版本,包括Groovy和SpringBootCLI。去找SDKMAN!从…sdkman.io并使用以下命令安装SpringBoot:

$ sdk install springboot
$ spring --version
Spring Boot v2.1.0.BUILD-SNAPSHOT

如果您为CLI开发特性并希望轻松访问您构建的版本,请使用以下命令:

$ sdk install springboot dev /path/to/spring-boot/spring-boot-cli/target/spring-boot-cli-2.1.0.BUILD-SNAPSHOT-bin/spring-2.1.0.BUILD-SNAPSHOT/
$ sdk default springboot dev
$ spring --version
Spring CLI v2.1.0.BUILD-SNAPSHOT

的本地实例spring称为dev举个例子。它指向您的目标构建位置,所以每次您重建SpringBoot时,spring是最新的。

通过运行以下命令可以看到它:

$ sdk ls springboot

================================================================================
Available Springboot Versions
================================================================================
> + dev
* 2.1.0.BUILD-SNAPSHOT

================================================================================
+ - local version
* - installed
> - currently in use
================================================================================

10.2.3 OSX自制设备

如果你在mac上使用自制,可以使用以下命令安装SpringBootCLI:

$ brew tap pivotal/tap
$ brew install springboot

自制安装spring/usr/local/bin.

[Note]

如果您没有看到公式,您的BREW安装可能是过时的。在这种情况下,运行brew update再试一次。

10.2.4 MacPorts安装

如果你在mac上使用麦克波特,可以使用以下命令安装SpringBootCLI:

$ sudo port install spring-boot-cli

10.2.5指挥线完成

SpringBootCLI包括为巴什兹什贝壳。你可以的。source脚本(也称为spring)在任何shell中,或将其放在个人或系统范围内的bash完成初始化中。在debian系统上,系统范围内的脚本位于/shell-completion/bash当一个新的shell启动时,该目录中的所有脚本都会被执行。例如,如果通过使用SDKMAN安装了脚本,则手动运行脚本!,使用以下命令:

$ . ~/.sdkman/candidates/springboot/current/shell-completion/bash/spring
$ spring <HIT TAB HERE>
  grab  help  jar  run  test  version
[Note]

如果使用HOMEBREW或MacPorts安装SpringBootCLI,命令行完成脚本将自动注册到shell中。

10.2.6 Windows SCOOP安装

如果您在Windows上并使用铲子,可以使用以下命令安装SpringBootCLI:

> scoop bucket add extras
> scoop install springboot

铲斗安装spring~/scoop/apps/springboot/current/bin.

[Note]

如果您没有看到应用程序清单,您安装的独家新闻可能是过时的。在这种情况下,运行scoop update再试一次。

10.2.7快速启动SpringCLI示例

您可以使用下面的web应用程序来测试您的安装。首先,创建一个名为app.groovy,如下:

@RestController
class ThisWillActuallyRun {

	@RequestMapping("/")
	String home() {
		"Hello World!"
	}

}

然后从shell运行它,如下所示:

$ spring run app.groovy
[Note]

随着依赖项的下载,应用程序的第一次运行是缓慢的。随后的运行要快得多。

打开localhost:8080在你最喜欢的网页浏览器里。您应该看到以下输出:

Hello World!

10.3从较早版本的SpringBoot升级

如果您正在从SpringBoot的早期版本进行升级,请检查项目wiki的“迁移指南”这提供了详细的升级说明。也检查“发布说明”关于每个版本的“新的和值得注意的”特性的列表。

升级到新的特性发行版时,一些属性可能已被重命名或删除。SpringBoot提供了一种在启动时分析应用程序环境和打印诊断信息的方法,但也为您提供了在运行时临时迁移属性的方法。若要启用该功能,请向项目中添加以下依赖项:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-properties-migrator</artifactId>
	<scope>runtime</scope>
</dependency>
[Warning]

晚添加到环境中的属性,例如当使用@PropertySource,不会被考虑在内。

[Note]

完成迁移后,请确保从项目的依赖项中删除此模块。

若要升级现有的CLI安装,请使用适当的包管理器命令(例如,brew upgrade)或者,如果手动安装了CLI,请按照标准指令,请记住更新PATH环境变量以删除任何旧的引用。

11.开发您的第一个SpringBoot应用程序

本节描述如何开发一个简单的“HelloWorld!”Web应用程序,它突出了SpringBoot的一些关键特性。我们使用Maven构建这个项目,因为大多数IDE都支持它。

[Tip]

这,这个,那,那个spring.io网站包含许多“入门”导轨使用Spring Boot。如果你需要解决一个具体的问题,首先检查那里。

您可以通过以下步骤转到start.spring.io并从依赖项搜索器中选择“Web”启动器。这样做会生成一个新的项目结构,这样您就可以立即开始编码。检查SpringInitializr文档更多细节。

在开始之前,打开一个终端并运行以下命令,以确保安装了有效版本的Java和Maven:

$ java -version
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
$ mvn -v
Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-17T14:33:14-04:00)
Maven home: /usr/local/Cellar/maven/3.3.9/libexec
Java version: 1.8.0_102, vendor: Oracle Corporation
[Note]

此示例需要在自己的文件夹中创建。后续说明假设您已经创建了一个合适的文件夹,并且它是您的当前目录。

11.1创建POM

我们需要从创建一个Maven开始pom.xml档案。这,这个,那,那个pom.xml用于构建项目的配方。打开您最喜欢的文本编辑器并添加以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.example</groupId>
	<artifactId>myproject</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.0.BUILD-SNAPSHOT</version>
	</parent>

	<!-- Additional lines to be added here... -->

	<!-- (you don't need this if you are using a .RELEASE version) -->
	<repositories>
		<repository>
			<id>spring-snapshots</id>
			<url>https://repo.spring.io/snapshot</url>
			<snapshots><enabled>true</enabled></snapshots>
		</repository>
		<repository>
			<id>spring-milestones</id>
			<url>https://repo.spring.io/milestone</url>
		</repository>
	</repositories>
	<pluginRepositories>
		<pluginRepository>
			<id>spring-snapshots</id>
			<url>https://repo.spring.io/snapshot</url>
		</pluginRepository>
		<pluginRepository>
			<id>spring-milestones</id>
			<url>https://repo.spring.io/milestone</url>
		</pluginRepository>
	</pluginRepositories>
</project>

上面的清单应该为您提供一个工作构建。您可以通过运行mvn package(现在,您可以忽略“jar将为空-没有标记为包含的内容!”警告)。

[Note]

此时,您可以将项目导入IDE(大多数现代Java IDE都包括对Maven的内置支持)。为了简单起见,我们继续为这个示例使用纯文本编辑器。

11.2添加类路径依赖项

SpringBoot提供了许多“启动器”,允许您在类路径中添加罐子。我们的示例应用程序已经使用了spring-boot-starter-parent在.。parentPOM的章节。这,这个,那,那个spring-boot-starter-parent是一个特殊的启动程序,它提供了有用的Maven默认值。它还提供了一个dependency-management节,以便您可以省略version标记用于“祝福”依赖项。

其他“启动程序”提供了您在开发特定类型应用程序时可能需要的依赖项。因为我们正在开发一个web应用程序,所以我们添加了一个spring-boot-starter-web依赖。在此之前,我们可以通过运行以下命令查看我们目前拥有的内容:

$ mvn dependency:tree

[INFO] com.example:myproject:jar:0.0.1-SNAPSHOT

这,这个,那,那个mvn dependency:tree命令打印项目依赖项的树表示形式。你可以看到spring-boot-starter-parent本身不提供依赖项。若要添加必要的依赖项,请编辑pom.xml并添加spring-boot-starter-web控件下面的依赖项。parent部分:

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
</dependencies>

如果你跑mvn dependency:tree您再次看到,现在有许多附加的依赖项,包括Tomcat Web服务器和SpringBoot本身。

11.3编写守则

要完成我们的应用程序,我们需要创建一个Java文件。默认情况下,Maven从src/main/java,所以您需要创建该文件夹结构,然后添加一个名为src/main/java/Example.java若要包含以下代码,请执行以下操作:

import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.web.bind.annotation.*;

@RestController
@EnableAutoConfiguration
public class Example {

	@RequestMapping("/")
	String home() {
		return "Hello World!";
	}

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

}

虽然这里没有太多的代码,但是正在发生很多事情。在接下来的几节中,我们将逐步了解重要的部分。

11.3.1@RestController和@Requestmap注释

我们的第一个注释Example类是@RestController。这被称为刻板印象注释它为阅读代码的人和Spring提供了提示,说明类扮演了特定的角色。在这种情况下,我们的类是一个web。@Controller,所以Spring在处理传入的Web请求时会考虑它。

这,这个,那,那个@RequestMapping注释提供“路由”信息。它告诉Spring,任何带有/路径应映射到home方法。这,这个,那,那个@RestController注释告诉Spring将结果字符串直接呈现给调用者。

[Tip]

这,这个,那,那个@RestController@RequestMapping注释是SpringMVC注释。(它们并不是SpringBoot特有的。)见MVC部分在Spring参考文档中获得更多细节。

11.3.2@EnableAutoConfiguration注释

第二个类级注释是@EnableAutoConfiguration。这个注释告诉SpringBoot根据您添加的JAR依赖项“猜测”如何配置Spring。自spring-boot-starter-web加上Tomcat和SpringMVC,自动配置假设您正在开发一个Web应用程序,并相应地设置Spring。

启动器和自动配置

自动配置被设计为与“启动器”很好地工作,但这两个概念并不是直接联系在一起的。您可以在启动程序之外自由选择JAR依赖项。SpringBoot仍然尽力自动配置您的应用程序。

11.3.3“主要”方法

应用程序的最后一部分是main方法。这只是应用程序入口点遵循Java约定的一个标准方法。我们的主要方法委托给SpringBootSpringApplication通过调用run.SpringApplication引导我们的应用程序,启动Spring,然后启动自动配置的Tomcat Web服务器。我们需要通过Example.class作为对run告知方法SpringApplication这是主要的Spring组件。这,这个,那,那个args数组也被传递到公开任何命令行参数。

11.4运行示例

此时,您的应用程序应该可以工作。因为你用了spring-boot-starter-parent波姆,你有个有用的run可以用来启动应用程序的目标。类型mvn spring-boot:run从根项目目录中启动应用程序。您应该看到类似于以下内容的输出:

$ mvn spring-boot:run

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::  (v2.1.0.BUILD-SNAPSHOT)
....... . . .
....... . . . (log output here)
....... . . .
........ Started Example in 2.222 seconds (JVM running for 6.514)

如果您打开web浏览器到localhost:8080,您将看到以下输出:

Hello World!

若要优雅地退出应用程序,请按ctrl-c.

11.5创建可执行的JAR

我们通过创建一个可以在生产中运行的完全独立的可执行JAR文件来完成我们的示例。可执行的JAR(有时称为“FAT JAR”)是包含编译类以及代码运行所需的所有JAR依赖项的档案。

可执行JAR和Java

Java没有提供加载嵌套JAR文件的标准方法(JAR文件本身包含在JAR中)。如果您希望分发一个独立的应用程序,这可能会有问题。

为了解决这个问题,许多开发人员使用“uber”JAR。一个uberjar将所有应用程序依赖项中的所有类打包到一个归档文件中。这种方法的问题是很难看出应用程序中有哪些库。如果在多个JAR中使用相同的文件名(但内容不同),也会出现问题。

春靴不同方法让你直接筑巢。

要创建一个可执行的JAR,我们需要添加spring-boot-maven-plugin敬我们pom.xml。为此,请在dependencies部分:

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

这,这个,那,那个spring-boot-starter-parentPOM包括<executions>配置来绑定repackage进球。如果不使用父POM,则需要自己声明此配置。见插件文档关于细节。

保存你的pom.xmlmvn package在命令行中,如下所示:

$ mvn package

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building myproject 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] .... ..
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ myproject ---
[INFO] Building jar: /Users/developer/example/spring-boot-example/target/myproject-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.1.0.BUILD-SNAPSHOT:repackage (default) @ myproject ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

如果你看看target目录中,您应该看到myproject-0.0.1-SNAPSHOT.jar。文件的大小应该在10 MB左右。如果你想窥视里面,你可以用jar tvf,如下:

$ jar tvf target/myproject-0.0.1-SNAPSHOT.jar

您还应该看到一个更小的文件,名为myproject-0.0.1-SNAPSHOT.jar.original在.。target目录。这是Maven在SpringBoot重新打包之前创建的原始JAR文件。

若要运行该应用程序,请使用java -jar命令如下:

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

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::  (v2.1.0.BUILD-SNAPSHOT)
....... . . .
....... . . . (log output here)
....... . . .
........ Started Example in 2.536 seconds (JVM running for 2.864)

如前所述,要退出应用程序,请按ctrl-c.

12.接下来要读什么?

希望本节提供了一些SpringBoot基础知识,并帮助您编写自己的应用程序。如果您是面向任务的开发人员,您可能需要跳到spring.io看看其中的一些开始解决具体问题的指南“我如何用Spring实现这一点?”问题。我们也有SpringBoot特有的“如何“参考文件。

这,这个,那,那个弹簧启动库也有一个一堆样本你可以跑了。示例独立于代码的其余部分(也就是说,您不需要构建其余的代码来运行或使用示例)。

否则,下一个逻辑步骤是读取第三部分,“使用Spring Boot”。如果你真的不耐烦的话,你也可以跳到前面去读。弹簧启动功能.

第三部分。使用Spring Boot

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

如果您是从SpringBoot开始的,您可能应该阅读开始在潜入这一段之前,导游。

13.构建系统

强烈建议您选择支持依赖性管理这可以使用发布到“Maven Central”存储库的工件。我们建议您选择Maven或Gradle。让SpringBoot与其他构建系统(例如Ant)一起工作是可能的,但它们并不是特别受支持的。

13.1抚养管理

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

[Note]

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

管理列表包含了您可以在SpringBoot中使用的所有Spring模块,以及一个完善的第三方库列表。该列表可作为标准提供。物料清单(spring-boot-dependencies)两者都可以使用的马文梯度.

[Warning]

SpringBoot的每个版本都与Spring框架的一个基本版本相关联。我们高度建议您不要指定其版本。

13.2 Maven

Maven用户可以从spring-boot-starter-parent项目以获得合理的默认值。父项目提供以下特性:

  • Java 1.8作为默认编译器级别。
  • UTF-8源编码。
  • 抚养管理科,继承自Spring-boot依赖项pom,该pom管理公共依赖项的版本。这种依赖关系管理允许您在自己的pom中使用时省略那些依赖项的标记。
  • 的执行repackage目标带着repackage行刑证明。
  • 感情用事资源过滤.
  • 合理的插件配置(EXEC插件Git提交ID,和遮荫).
  • 敏感资源过滤application.propertiesapplication.yml包括特定于配置文件的文件(例如,application-dev.propertiesapplication-dev.yml)

注意,因为application.propertiesapplication.yml文件接受Spring样式占位符(${…​}),则将Maven筛选更改为使用@..@占位符。(您可以通过设置名为resource.delimiter.)

13.2.1继承初学者父母

将项目配置为从spring-boot-starter-parent,设置parent详情如下:

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

您应该只需在此依赖项上指定SpringBoot版本号。如果您导入其他启动程序,则可以安全地省略版本号。

使用该设置,还可以通过重写自己项目中的属性来覆盖各个依赖项。例如,要升级到另一个Spring数据发布培训,您可以将以下内容添加到您的pom.xml:

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

检查spring-boot-dependencies波姆有关支持的属性列表。

13.2.2在没有父POM的情况下使用SpringBoot

不是每个人都喜欢从spring-boot-starter-parent波姆。您可能需要使用自己的企业标准父级,或者您可能更愿意显式声明所有Maven配置。

如果您不想使用spring-boot-starter-parent,仍然可以保留依赖关系管理(但不是插件管理)的好处,方法是使用scope=import依赖性如下:

<dependencyManagement>
		<dependencies>
		<dependency>
			<!-- Import dependency management from Spring Boot -->
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-dependencies</artifactId>
			<version>2.1.0.BUILD-SNAPSHOT</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

如前所述,前面的示例设置不允许您使用属性覆盖单个依赖项。要达到同样的结果,您需要在dependencyManagement你的项目以前这,这个,那,那个spring-boot-dependencies入场。例如,要升级到另一个Spring数据发布培训,可以向您的pom.xml:

<dependencyManagement>
	<dependencies>
		<!-- Override Spring Data release train provided by Spring Boot -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-releasetrain</artifactId>
			<version>Fowler-SR2</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-dependencies</artifactId>
			<version>2.1.0.BUILD-SNAPSHOT</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>
[Note]

在前面的示例中,我们指定了BOM,但是任何依赖类型都可以相同的方式被重写。

13.2.3使用SpringBootMaven插件

弹簧启动包括一个Maven插件它可以将项目打包为可执行的JAR。将插件添加到您的<plugins>如果您想使用它,如下面的示例所示:

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

如果您使用SpringBootStart父pom,则只需要添加插件。除非您想要更改父级中定义的设置,否则不需要配置它。

13.3级

要了解如何在Gradle中使用SpringBoot,请参阅SpringBoot的Gradle插件的文档:

13.4蚂蚁

可以使用ApacheAnt+Ivy构建SpringBoot项目。这,这个,那,那个spring-boot-antlib“AntLib”模块还可以帮助Ant创建可执行的JAR。

要声明依赖项,典型的ivy.xml文件如下所示:

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

典型build.xml如下示例所示:

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

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

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

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

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

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

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

如果您不想使用spring-boot-antlib模块,请参阅第90.9节,“在不使用Ant的情况下从Ant构建可执行的存档spring-boot-antlib“怎么做”。

13.5启动器

Starters是一组方便的依赖描述符,可以包含在应用程序中。您可以为您需要的所有Spring和相关技术提供一站式服务,而无需搜索示例代码和复制粘贴大量的依赖描述符。例如,如果您想开始使用Spring和JPA进行数据库访问,请将spring-boot-starter-data-jpa项目中的依赖项。

启动程序包含许多依赖项,您需要这些依赖项才能使项目快速启动和运行,并且具有一致的、受支持的托管传递依赖关系集。

名字里有什么

初学者遵循类似的命名模式;spring-boot-starter-*,在哪里*是一种特殊类型的应用程序。当您需要找到启动器时,此命名结构旨在帮助您。许多IDE中的Maven集成允许您按名称搜索依赖项。例如,安装了适当的Eclipse或STS插件后,可以按ctrl-space在POM编辑器中键入“Spring-boot-starter”以获得完整的列表。

如“创建自己的初学者“第三部分,第三人不应以spring-boot,因为它是为官方的SpringBoot文物保留的。相反,第三方启动程序通常以项目名称开始。例如,一个第三方启动项目称为thirdpartyproject通常被命名为thirdpartyproject-spring-boot-starter.

下面的应用程序启动程序由SpringBoot在org.springframework.boot小组:

表13.1.弹簧启动应用程序启动器

名字,姓名描述波姆

spring-boot-starter

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

波姆

spring-boot-starter-activemq

使用ApacheActiveMQ启动JMS消息传递

波姆

spring-boot-starter-amqp

使用SpringAMQP和兔子MQ的启动器

波姆

spring-boot-starter-aop

使用SpringAOP和AspectJ进行面向方面的编程

波姆

spring-boot-starter-artemis

使用ApacheArtemis启动JMS消息传递

波姆

spring-boot-starter-batch

弹簧批次起动器

波姆

spring-boot-starter-cache

开始使用Spring框架的缓存支持

波姆

spring-boot-starter-cloud-connectors

使用SpringCloud连接器的初学者,它简化了云平台(如CloudFoundry和Heroku)中的服务连接

波姆

spring-boot-starter-data-cassandra

开始使用Cassandra分布式数据库和Spring数据Cassandra

波姆

spring-boot-starter-data-cassandra-reactive

使用Cassandra分布式数据库和Spring数据的启动器-Cassandra反应性

波姆

spring-boot-starter-data-couchbase

开始使用Couchbase面向文档的数据库和Spring数据库

波姆

spring-boot-starter-data-couchbase-reactive

开始使用面向Couchbase文档的数据库和SpringDataCouchbase反应性

波姆

spring-boot-starter-data-elasticsearch

使用弹性搜索和分析引擎及Spring数据弹性搜索的启动器

波姆

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数据的启动

波姆

spring-boot-starter-data-neo4j

Neo4j图形数据库和Spring数据Neo4j的启动

波姆

spring-boot-starter-data-redis

启动使用Redis键值数据存储与Spring数据Redis和生菜客户端

波姆

spring-boot-starter-data-redis-reactive

启动使用Redis键值数据存储与SpringDataRedisReactiveand生菜客户端

波姆

spring-boot-starter-data-rest

开始使用Spring数据REST在REST上公开Spring数据存储库

波姆

spring-boot-starter-data-solr

Apache Solr搜索平台与Spring数据Solr的启动

波姆

spring-boot-starter-freemarker

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

波姆

spring-boot-starter-groovy-templates

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

波姆

spring-boot-starter-hateoas

用SpringMVC和SpringHATEOA构建基于超媒体的RESTfulweb应用程序

波姆

spring-boot-starter-integration

使用Spring集成的启动器

波姆

spring-boot-starter-jdbc

与HikariCP连接池一起使用JDBC的启动程序

波姆

spring-boot-starter-jersey

使用JAX-RS和泽西岛构建RESTful Web应用程序的初学者。替代物spring-boot-starter-web

波姆

spring-boot-starter-jooq

开始使用jOOQ访问SQL数据库。替代物spring-boot-starter-data-jpaspring-boot-starter-jdbc

波姆

spring-boot-starter-json

读写入门

波姆

spring-boot-starter-jta-atomikos

使用Atomikos启动JTA事务

波姆

spring-boot-starter-jta-bitronix

使用Bitronix启动JTA事务

波姆

spring-boot-starter-mail

启动使用Java邮件和Spring框架的电子邮件发送支持

波姆

spring-boot-starter-mustache

使用胡子视图构建Web应用程序的初学者

波姆

spring-boot-starter-oauth2-oidc-client

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

波姆

spring-boot-starter-quartz

使用Quartz调度程序的启动程序

波姆

spring-boot-starter-security

使用Spring安全性的启动器

波姆

spring-boot-starter-test

使用包括JUnit、Hamcrest和Mockito在内的库测试SpringBoot应用程序的初学者

波姆

spring-boot-starter-thymeleaf

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

波姆

spring-boot-starter-validation

JavaBean验证与Hibernate验证器的启动

波姆

spring-boot-starter-web

使用SpringMVC构建Web应用程序,包括RESTful应用程序。使用Tomcat作为默认的嵌入式容器。

波姆

spring-boot-starter-web-services

启动使用SpringWeb服务

波姆

spring-boot-starter-webflux

使用Spring框架的反应性Web支持构建WebFlux应用程序的初学者

波姆

spring-boot-starter-websocket

使用Spring框架的WebSocket支持构建WebSocket应用程序的初学者

波姆

 

除了应用程序启动程序之外,还可以使用以下启动程序添加生产准备特征:

表13.2.弹簧启动生产启动器

名字,姓名描述波姆

spring-boot-starter-actuator

使用SpringBootActuator的初学者,它提供生产准备功能,帮助您监视和管理应用程序

波姆

 

最后,SpringBoot还包括以下启动程序,如果要排除或交换特定的技术方面,可以使用这些启动程序:

表13.3.弹簧启动技术启动器

名字,姓名描述波姆

spring-boot-starter-jetty

开始使用Jetty作为嵌入式servlet容器。替代物spring-boot-starter-tomcat

波姆

spring-boot-starter-log4j2

开始使用Log4j2进行日志记录。替代物spring-boot-starter-logging

波姆

spring-boot-starter-logging

使用Logback开始日志记录。默认日志起动器

波姆

spring-boot-starter-reactor-netty

开始使用反应堆Netty作为嵌入式反应HTTP服务器。

波姆

spring-boot-starter-tomcat

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

波姆

spring-boot-starter-undertow

作为嵌入式servlet容器的启动程序。替代物spring-boot-starter-tomcat

波姆

 

[Tip]

有关其他社区贡献者的列表,请参见自述文件在.。spring-boot-startersGitHub上的模块。

14.构造代码

SpringBoot不需要任何特定的代码布局才能工作。然而,有一些最佳实践是有帮助的。

14.1使用“默认”包

类不包括package声明,它被认为是在“默认包”中。通常不鼓励使用“默认包”,应该避免使用。它可能会给SpringBoot应用程序带来特殊问题,这些应用程序使用@ComponentScan@EntityScan,或@SpringBootApplication注释,因为每个JAR中的每个类都会被读取。

[Tip]

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

14.2定位主应用程序类

我们通常建议您将主应用程序类定位在根包中,而不是其他类。这,这个,那,那个@SpringBootApplication注记通常放在主类中,并且它隐式地定义了特定项的基本“搜索包”。例如,如果您正在编写JPA应用程序,则@SpringBootApplication带注释的类用于搜索@Entity物品。使用根包还允许组件扫描只应用于项目。

[Tip]

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

下面的清单显示了一个典型的布局:

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

这,这个,那,那个Application.java文件将声明main方法,以及@SpringBootApplication,如下:

package com.example.myapplication;

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

@SpringBootApplication
public class Application {

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

}

15.配置类

Spring Boot支持基于Java的配置。虽然可以使用SpringApplication对于xml源,我们通常建议您的主源是一个@Configuration班级,等级通常定义main方法是一种很好的候选方法。@Configuration.

[Tip]

许多使用XML配置的Spring配置示例已经在Internet上发布。如果可能,请始终尝试使用等效的基于Java的配置。寻觅Enable*注释可以是一个很好的起点。

15.1导入其他配置类

你不需要把你所有的@Configuration变成一个班级。这,这个,那,那个@Import注释可用于导入其他配置类。或者,您可以使用@ComponentScan自动获取所有Spring组件,包括@Configuration上课。

15.2导入XML配置

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

16.自动配置

SpringBoot自动配置尝试根据您添加的JAR依赖关系自动配置Spring应用程序。例如,如果HSQLDB在类路径上,并且没有手动配置任何数据库连接bean,那么SpringBoot自动配置内存中的数据库。

您需要通过添加@EnableAutoConfiguration@SpringBootApplication中的一个注释@Configuration上课。

[Tip]

你只应该加一个@SpringBootApplication@EnableAutoConfiguration注释我们通常建议您将一个或另一个添加到主@Configuration只上课。

16.1逐步取代自动配置

自动配置是非侵入性的。在任何时候,您都可以开始定义自己的配置来替换自动配置的特定部分。例如,如果添加自己的DataSourcebean,默认的嵌入式数据库支持将不再支持。

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

16.2禁用特定的自动配置类

如果发现正在应用不希望应用的特定自动配置类,则可以使用@EnableAutoConfiguration若要禁用它们,请参见以下示例:

import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
import org.springframework.context.annotation.*;

@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}

如果类不在类路径上,则可以使用excludeName属性,并指定完全限定的名称。最后,还可以通过使用spring.autoconfigure.exclude财产。

[Tip]

您可以在注释级别和通过使用属性定义排除。

17.Springbean和依赖注入

您可以使用任何标准的SpringFramework技术来定义bean及其注入的依赖项。为了简单起见,我们经常发现@ComponentScan(找到您的bean)并使用@Autowired(进行构造函数注入)工作得很好。

如果按照上面的建议构造代码(将应用程序类定位在根包中),则可以添加@ComponentScan没有任何争论。所有应用程序组件(@Component@Service@Repository@Controller自动注册为Springbean。

下面的示例显示@Servicebean,它使用构造函数注入来获得所需的RiskAssessor豆子:

package com.example.service;

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

@Service
public class DatabaseAccountService implements AccountService {

	private final RiskAssessor riskAssessor;

	@Autowired
	public DatabaseAccountService(RiskAssessor riskAssessor) {
		this.riskAssessor = riskAssessor;
	}

	// ...

}

如果bean有一个构造函数,则可以省略@Autowired,如以下示例所示:

@Service
public class DatabaseAccountService implements AccountService {

	private final RiskAssessor riskAssessor;

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

	// ...

}
[Tip]

注意如何使用构造函数注入使riskAssessor字段标记为final,指示不能随后更改它。

18.使用@SpringBootApplication注释

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

  • @EnableAutoConfiguration*启用弹簧启动自动配置机构
  • @ComponentScan*启用@Component扫描应用程序所在的包(请参阅最佳做法)
  • @Configuration允许在上下文中注册额外的bean或导入其他配置类

这,这个,那,那个@SpringBootApplication注释相当于使用@Configuration@EnableAutoConfiguration,和@ComponentScan使用它们的默认属性,如下面的示例所示:

package com.example.myapplication;

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

@SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan
public class Application {

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

}
[Note]

@SpringBootApplication还提供别名来自定义@EnableAutoConfiguration@ComponentScan.

[Note]

这些特性中没有一个是强制性的,您可以选择用它所启用的任何特性来替换这个单个注释。例如,您可能不希望在应用程序中使用组件扫描:

package com.example.myapplication;

import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@EnableAutoConfiguration
@Import({ MyConfig.class, MyAnotherConfig.class })
public class Application {

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

}

在这个例子中,Application就像其他SpringBoot应用程序一样,除了@Component-未自动检测到带注释的类,也不会显式导入用户定义的bean(请参阅@Import).

19.运行您的应用程序

将应用程序打包为JAR并使用嵌入式HTTP服务器的最大优点之一是可以像运行其他应用程序一样运行应用程序。调试SpringBoot应用程序也很容易。您不需要任何特殊的IDE插件或扩展。

[Note]

本节仅涉及基于JAR的包装。如果选择将应用程序打包为WAR文件,则应参考服务器和IDE文档。

19.1从IDE运行

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

如果不能直接将项目导入IDE,则可以使用构建插件生成IDE元数据。Maven包括用于月食理念。Gradle为各种IDE.

[Tip]

如果您意外地运行了两个web应用程序,您会看到一个“端口已经在使用”错误。STS用户可以使用Relaunch按钮而不是Run按钮,以确保任何现有实例都已关闭。

19.2作为打包应用程序运行

如果使用SpringBootMaven或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

19.3使用Maven插件

SpringBootMaven插件包括一个run可用于快速编译和运行应用程序的目标。应用程序以爆炸性的形式运行,就像它们在您的IDE中所做的那样。下面的示例显示了运行SpringBoot应用程序的典型Maven命令:

$ mvn spring-boot:run

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

$ export MAVEN_OPTS=-Xmx1024m

19.4使用Gradle插件

SpringBootGradle插件还包括bootRun可用于以爆炸性形式运行应用程序的任务。这,这个,那,那个bootRun当您应用org.springframework.bootjava插件,如以下示例所示:

$ gradle bootRun

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

$ export JAVA_OPTS=-Xmx1024m

19.5热交换

由于SpringBoot应用程序只是普通的Java应用程序,因此JVM热交换应该是现成的。JVM热交换在一定程度上受到了它可以替换的字节码的限制。为了更完整的解决方案,贾贝尔可以使用。

这,这个,那,那个spring-boot-devtools模块还包括对快速应用程序重新启动的支持。见第20章,开发工具本章后面的一节以及热腾腾的“如何-到”关于细节。

20.开发工具

SpringBoot包括一组额外的工具,这些工具可以使应用程序开发体验更加愉快。这,这个,那,那个spring-boot-devtools模块可以包含在任何项目中,以提供额外的开发时特性。要包含DevTools支持,请将模块依赖项添加到您的构建中,如Maven和Gradle的以下清单所示:

梅文。

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-devtools</artifactId>
		<optional>true</optional>
	</dependency>
</dependencies>

 

格拉德尔。

dependencies {
	compile("org.springframework.boot:spring-boot-devtools")
}

 

[Note]

在运行完整打包的应用程序时,将自动禁用开发工具。如果您的应用程序是从java -jar或者,如果它是从一个特殊的类加载程序启动的,那么它就被认为是一个“生产应用程序”。在Maven中将依赖项标记为可选,或使用compileOnly在Gradle中,防止DevTools被临时应用到使用您的项目的其他模块是一种最佳实践。

[Tip]

默认情况下,重新打包的档案不包含DevTools。如果您想使用某些远程DevTools功能,则需要禁用excludeDevtools生成包含它的属性。Maven和Gradle插件都支持该属性。

20.1财产违约

SpringBoot支持的几个库使用缓存来提高性能。例如模板引擎缓存已编译模板,以避免重复解析模板文件。此外,SpringMVC可以在提供静态资源时向响应添加HTTP缓存头。

虽然缓存在生产中非常有益,但它在开发过程中可能会适得其反,从而阻止您看到您刚才在应用程序中所做的更改。因此,Springboot-DevTools默认禁用缓存选项。

缓存选项通常由application.properties档案。例如,Thymeleaf提供spring.thymeleaf.cache财产。不需要手动设置这些属性,spring-boot-devtools模块自动应用合理的开发时间配置。

因为您在开发SpringMVC和SpringWebFlux应用程序时需要更多关于Web请求的信息,所以开发人员工具将启用DEBUG的日志记录。web伐木组。这将为您提供有关传入请求、正在处理它的处理程序、响应结果等方面的信息。如果希望记录所有请求详细信息(包括潜在敏感信息),可以打开spring.http.log-request-details配置属性。

[Note]

如果不希望应用属性默认值,则可以设置spring.devtools.add-propertiesfalse在你的application.properties.

[Tip]

有关DevTools应用的属性的完整列表,请参见DevToolsPropertyDefaultsPostProcessor.

20.2自动重启

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

触发重新启动

在DevTools监视类路径资源时,触发重新启动的唯一方法是更新类路径。导致类路径更新的方式取决于您正在使用的IDE。在Eclipse中,保存修改后的文件将导致类路径被更新并触发重新启动。在IntelliJ IDEA中,构建项目(Build -> Build Project)具有相同的效果。

[Note]

只要启用了分叉,您也可以使用支持的构建插件(Maven和Gradle)启动应用程序,因为DevTools需要一个独立的应用程序类加载程序才能正常运行。默认情况下,Gradle和Maven在类路径上检测DevTools时会这样做。

[Tip]

当与LiveReload一起使用时,自动重新启动工作非常好。参见LiveReload部分关于细节。如果使用JRebel,则禁用自动重新启动以支持动态类重新加载。其他DevTools特性(如LiveReload和PropertyOverrids)仍然可以使用。

[Note]

DevTools依赖于应用程序上下文的关机钩子来关闭它。如果禁用了关机挂钩(SpringApplication.setRegisterShutdownHook(false)).

[Note]

在决定类路径上的条目是否应该在更改时触发重新启动时,DevTools会自动忽略名为spring-bootspring-boot-devtoolsspring-boot-autoconfigurespring-boot-actuator,和spring-boot-starter.

[Note]

DevTools需要自定义ResourceLoaderApplicationContext。如果您的应用程序已经提供了一个,那么它将被包装。直接覆盖getResource方法的ApplicationContext不支持。

重新启动VS Reload

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

如果发现重新启动对应用程序来说不够快,或者遇到类加载问题,则可以考虑重新加载技术,例如贾贝尔来自ZeroTurn的。这些工作是通过在加载类时重写类来完成的,以使它们更易于重新加载。

20.2.1状态评估中的测井变化

默认情况下,每次应用程序重新启动时,都会记录一个显示条件评估增量的报告。报告显示了在进行更改时对应用程序的自动配置所做的更改,例如添加或删除bean以及设置配置属性。

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

spring.devtools.restart.log-condition-evaluation-delta=false

20.2.2不包括资源

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

spring.devtools.restart.exclude=static/**,public/**
[Tip]

如果你想保留这些默认值其他排除,请使用spring.devtools.restart.additional-exclude而是财产。

20.2.3观察其他路径

您可能希望在对不位于类路径上的文件进行更改时重新启动或重新加载应用程序。若要这样做,请使用spring.devtools.restart.additional-paths属性配置其他路径以监视更改。您可以使用spring.devtools.restart.exclude财产前文描述若要控制附加路径下的更改是否触发完全重新启动或活重装.

20.2.4禁用重新启动

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

如果你需要完全地禁用重新启动支持(例如,因为它不适用于特定的库),您需要设置spring.devtools.restart.enabled System财产false在打电话之前SpringApplication.run(…​),如以下示例所示:

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

20.2.5使用触发器文件

如果您使用持续编译更改文件的IDE,则可能希望只在特定时间触发重新启动。为此,您可以使用“触发器文件”,这是一个特殊的文件,当您想要实际触发重新启动检查时,必须修改该文件。更改文件只会触发检查,只有在DevTools检测到必须做什么时才会重新启动。触发器文件可以手动更新,也可以使用IDE插件更新。

若要使用触发器文件,请将spring.devtools.restart.trigger-file属性设置为触发器文件的路径。

[Tip]

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

20.2.6自定义重新启动类加载程序

如前面所述,重新启动VS Reload节中,重新启动功能是通过使用两个类加载器实现的。对于大多数应用程序来说,这种方法工作得很好。但是,它有时会导致类加载问题。

默认情况下,IDE中的任何打开项目都带有“重新启动”类加载器和任何常规的类加载器。.jar使用“基本”类加载器加载文件。如果您在一个多模块项目上工作,而且不是每个模块都导入到您的IDE中,那么您可能需要定制一些东西。为此,您可以创建一个META-INF/spring-devtools.properties档案。

这,这个,那,那个spring-devtools.properties文件可以包含以restart.excluderestart.include。这,这个,那,那个include元素是应该拖放到“重新启动”类加载器中的项,并且exclude元素是应该向下推到“基本”类加载器中的项。属性的值是应用于类路径的regex模式,如下面的示例所示:

restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
[Note]

所有属性键必须是唯一的。只要财产开始于restart.include.restart.exclude.它被认为是。

[Tip]

META-INF/spring-devtools.properties从类路径被装载。您可以将文件打包到项目中或项目使用的库中。

20.2.7已知限制

重新启动功能不能很好地处理使用标准反序列化的对象。ObjectInputStream。如果需要反序列化数据,则可能需要使用Spring的ConfigurableObjectInputStream结合在一起Thread.currentThread().getContextClassLoader().

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

20.3 LiveReload

这,这个,那,那个spring-boot-devtools模块包括嵌入式LiveReload服务器,该服务器可用于在资源更改时触发浏览器刷新。LiveReload浏览器扩展可以免费提供给Chrome、Firefox和Safarilivereload.com.

如果不希望在应用程序运行时启动LiveReload服务器,则可以将spring.devtools.livereload.enabled财产false.

[Note]

一次只能运行一个LiveReload服务器。在启动应用程序之前,请确保没有其他LiveReload服务器正在运行。如果您从IDE启动多个应用程序,那么只有第一个应用程序具有LiveReload支持。

20.4全球设置

可以通过添加名为.spring-boot-devtools.properties敬你的$HOME文件夹(请注意文件名以“.”开头)。添加到此文件的任何属性都应用于使用DevTools的机器上的SpringBoot应用程序。例如,要将重新启动配置为始终使用触发文件,您将添加以下属性:

~/.Spring-boot-devtools.properties。

spring.devtools.reload.trigger-file=.reloadtrigger

 

20.5远程应用程序

SpringBootDeveloper工具并不局限于本地开发。在远程运行应用程序时,还可以使用几个特性。远程支持是可选的。要启用它,您需要确保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属性,如以下示例所示:

spring.devtools.remote.secret=mysecret
[Warning]

使能spring-boot-devtools在远程应用程序上存在安全风险。您永远不应该启用对生产部署的支持。

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

20.5.1运行远程客户端应用程序

远程客户端应用程序设计为在IDE中运行。你得跑org.springframework.boot.devtools.RemoteSpringApplication具有与所连接的远程项目相同的类路径。应用程序唯一需要的参数是它所连接的远程URL。

例如,如果您正在使用Eclipse或STS,并且您有一个名为my-app您已经部署到CloudFoundry,您将执行以下操作:

  • 选择Run Configurations…​Run菜单。
  • 创建一个新的Java Application“发射配置”。
  • 浏览my-app项目。
  • 使用org.springframework.boot.devtools.RemoteSpringApplication作为主修班。
  • https://myapp.cfapps.ioProgram arguments(或者不管您的远程URL是什么)。

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

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

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-devtools/target/classes started by pwebb in /Users/pwebb/projects/spring-boot/code/spring-boot-samples/spring-boot-sample-devtools)
2015-06-10 18:25:06.671  INFO 14938 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@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)
[Note]

由于远程客户端使用的类路径与实际应用程序相同,因此可以直接读取应用程序属性。这就是为什么spring.devtools.remote.secret属性被读取并传递给服务器以进行身份验证。

[Tip]

使用总是明智的。https://作为连接协议,使通信被加密,密码不能被截获。

[Tip]

如果需要使用代理访问远程应用程序,请配置spring.devtools.remote.proxy.hostspring.devtools.remote.proxy.port财产。

20.5.2远程更新

远程客户端监视应用程序类路径的更改,方式与局部重启。任何更新的资源都被推送到远程应用程序中,并且(如有需要)触发重新启动。如果您在使用本地没有的云服务的特性上进行迭代,这可能会很有帮助。通常,远程更新和重新启动要比完整的重建和部署周期快得多。

[Note]

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

21.包装生产申请

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

要获得额外的“生产准备”功能,如健康、审核和度量REST或jmx端点,请考虑添加spring-boot-actuator。看见第五部分,“SpringBoot执行器:可生产的特性”关于细节。

22.接下来要读什么?

现在您应该了解如何使用SpringBoot和应该遵循的一些最佳实践。现在您可以继续了解弹簧启动功能或者你可以跳过前面读到“生产准备“春靴的各个方面。

第四部分。弹簧启动功能

本节讨论SpringBoot的细节。在这里,您可以了解您可能希望使用和自定义的关键特性。如果您还没有这样做,您可能需要阅读“第二部分,“开始”“和”第三部分,“使用Spring Boot”“章节,让你有一个良好的基础。

23.Spring应用

这,这个,那,那个SpringApplication类提供了一种方便的方法来引导从main()方法。在许多情况下,您可以委托给静态SpringApplication.run方法,如以下示例所示:

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

当应用程序启动时,您应该会看到类似于以下输出的内容:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::   v2.1.0.BUILD-SNAPSHOT

2013-07-31 00:08:16.117  INFO 56603 --- [           main] o.s.b.s.app.SampleApplication            : Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb)
2013-07-31 00:08:16.166  INFO 56603 --- [           main] ationConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6e5a8246: startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy
2014-03-04 13:09:54.912  INFO 41370 --- [           main] .t.TomcatServletWebServerFactory : Server initialized with port: 8080
2014-03-04 13:09:56.501  INFO 41370 --- [           main] o.s.b.s.app.SampleApplication            : Started SampleApplication in 2.992 seconds (JVM running for 3.658)

默认情况下,INFO将显示日志消息,包括一些相关的启动细节,例如启动应用程序的用户。如果您需要日志级别而不是INFO,您可以设置它,如第26.4节,“日志水平”,

23.1启动失败

如果您的应用程序无法启动,请注册FailureAnalyzers有机会提供一条专门的错误消息和解决问题的具体操作。例如,如果您在端口上启动web应用程序8080而且该端口已经在使用中,您应该会看到类似于以下消息的内容:

***************************
APPLICATION FAILED TO START
***************************

Description:

Embedded servlet container failed to start. Port 8080 was already in use.

Action:

Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
[Note]

Spring Boot提供了许多FailureAnalyzer实现,您可以添加你自己的.

如果没有故障分析器能够处理异常,则仍然可以显示完整的条件报告,以更好地了解错误所在。要做到这一点,你需要启用debug财产使能DEBUG测井org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener.

例如,如果您正在运行您的应用程序,则使用java -jar,您可以启用debug财产如下:

$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug

23.2定制横幅

在启动时打印的横幅可以通过添加banner.txt文件到类路径中,或者通过设置spring.banner.location属性设置为这样一个文件的位置。如果文件具有utf-8以外的编码,则可以设置spring.banner.charset。除了文本文件之外,还可以添加banner.gifbanner.jpg,或banner.png图像文件到类路径或设置spring.banner.image.location财产。图像被转换成ASCII艺术表示法,并打印在任何文字横幅之上。

在你的banner.txt文件中,可以使用下列任何占位符:

表23.1.横幅变量

变量描述

${application.version}

应用程序的版本号,如MANIFEST.MF。例如Implementation-Version: 1.0打印为1.0.

${application.formatted-version}

应用程序的版本号,如MANIFEST.MF格式以供显示(括号包围,前缀为v)例如(v1.0).

${spring-boot.version}

您正在使用的SpringBoot版本。例如2.1.0.BUILD-SNAPSHOT.

${spring-boot.formatted-version}

您所使用的SpringBoot版本,格式化为显示(用括号包围,前缀为v)例如(v2.1.0.BUILD-SNAPSHOT).

${Ansi.NAME}(或${AnsiColor.NAME}${AnsiBackground.NAME}${AnsiStyle.NAME})

哪里NAMEANSI转义代码的名称。看见AnsiPropertySource关于细节。

${application.title}

您的应用程序的标题,如MANIFEST.MF。例如Implementation-Title: MyApp打印为MyApp.

 

[Tip]

这,这个,那,那个SpringApplication.setBanner(…​)方法,如果希望以编程方式生成横幅,则可以使用该方法。使用org.springframework.boot.Banner接口并实现自己的printBanner()方法。

您还可以使用spring.main.banner-mode属性以确定是否必须在其上打印横幅。System.out (console),发送到配置的记录器(log),或根本不生产(off).

打印的横幅以下列名称注册为单例bean:springBootBanner.

[Note]

YAML地图offfalse,因此,如果要禁用应用程序中的横幅,请确保添加引号,如下面的示例所示:

spring:
	main:
		banner-mode: "off"

23.3定制Spring应用程序

如果SpringApplication默认值并不适合您的口味,您可以创建一个本地实例并对其进行自定义。例如,要关闭横幅,可以编写:

public static void main(String[] args) {
	SpringApplication app = new SpringApplication(MySpringConfiguration.class);
	app.setBannerMode(Banner.Mode.OFF);
	app.run(args);
}
[Note]

传递给SpringApplication是Springbean的配置源。在大多数情况下,这些都是引用@Configuration类,但它们也可以引用XML配置或应该扫描的包。

还可以配置SpringApplication通过使用application.properties档案。看见第24章,外化配置关于细节。

有关配置选项的完整列表,请参见SpringApplicationJavadoc.

23.4 FLUENT BuilderAPI

如果您需要构建一个ApplicationContext层次结构(具有父/子关系的多个上下文),或者如果您更喜欢使用“流利”构建器API,则可以使用SpringApplicationBuilder.

这,这个,那,那个SpringApplicationBuilder让您将多个方法调用链接在一起,并包括parentchild允许您创建层次结构的方法,如以下示例所示:

new SpringApplicationBuilder()
		.sources(Parent.class)
		.child(Application.class)
		.bannerMode(Banner.Mode.OFF)
		.run(args);
[Note]

创建ApplicationContext等级制度。例如,Web组件包含在子上下文中,并且相同Environment用于父上下文和子上下文。见SpringApplicationBuilderJavadoc详细情况。

23.5应用程序事件和侦听器

除了常见的Spring框架事件之外,例如ContextRefreshedEvent..SpringApplication发送其他应用程序事件。

[Note]

某些事件实际上是在ApplicationContext创建,因此不能将侦听器注册为@Bean。您可以将它们注册到SpringApplication.addListeners(…​)方法或SpringApplicationBuilder.listeners(…​)方法。

如果希望这些侦听器自动注册,而不管应用程序的创建方式如何,则可以添加META-INF/spring.factories文件到项目中,并使用org.springframework.context.ApplicationListener键,如以下示例所示:

org.springframework.context.ApplicationListener=com.example.project.MyListener

在应用程序运行时,应用程序事件按以下顺序发送:

  1. ApplicationStartingEvent在运行开始时发送,但在任何处理之前发送,但侦听器和初始化器的注册除外。
  2. ApplicationEnvironmentPreparedEventEnvironment在上下文中使用是已知的,但在创建上下文之前。
  3. ApplicationPreparedEvent在启动刷新之前发送,但在加载bean定义之后发送。
  4. ApplicationStartedEvent在刷新上下文之后,但在调用任何应用程序和命令行运行程序之前发送。
  5. ApplicationReadyEvent在调用任何应用程序和命令行运行程序之后发送。它表示应用程序已准备好为请求提供服务。
  6. ApplicationFailedEvent如果启动时出现异常,则发送。
[Tip]

您通常不需要使用应用程序事件,但是知道它们的存在是很方便的。在内部,SpringBoot使用事件来处理各种任务。

应用程序事件是通过使用SpringFramework的事件发布机制发送的。此机制的一部分确保在子上下文中发布给侦听器的事件也会在任何祖先上下文中发布给侦听器。因此,如果应用程序使用的层次结构为SpringApplication实例,侦听器可能接收同一类型应用程序事件的多个实例。

若要允许侦听器区分针对其上下文的事件和针对后代上下文的事件,则应请求注入其应用程序上下文,然后将注入的上下文与事件的上下文进行比较。可以通过实现ApplicationContextAware或者,如果侦听器是bean,则使用@Autowired.

23.6网络环境

SpringApplication尝试创建正确类型的ApplicationContext代表你。用于确定WebApplicationType相当简单:

  • 如果SpringMVC存在,则AnnotationConfigServletWebServerApplicationContext使用
  • 如果SpringMVC不存在且SpringWebFlux存在,则AnnotationConfigReactiveWebServerApplicationContext使用
  • 否则,AnnotationConfigApplicationContext使用

这意味着如果您使用SpringMVC和新的WebClient从同一个应用程序中的SpringWebFlux开始,默认情况下将使用SpringMVC。您可以通过调用setWebApplicationType(WebApplicationType).

也可以完全控制ApplicationContext类型,该类型通过调用setApplicationContextClass(…​).

[Tip]

打电话给setWebApplicationType(WebApplicationType.NONE)使用时SpringApplication在JUnit测试中。

23.7访问应用程序参数

如果需要访问传递给SpringApplication.run(…​),你可以注射org.springframework.boot.ApplicationArguments豆子这,这个,那,那个ApplicationArguments接口提供对两个原始数据的访问。String[]论点和分析optionnon-option参数,如以下示例所示:

import org.springframework.boot.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.stereotype.*;

@Component
public class MyBean {

	@Autowired
	public MyBean(ApplicationArguments args) {
		boolean debug = args.containsOption("debug");
		List<String> files = args.getNonOptionArgs();
		// if run with "--debug logfile.txt" debug=true, files=["logfile.txt"]
	}

}
[Tip]

Spring Boot还注册了一个CommandLinePropertySource与春天Environment。这还允许您通过使用@Value注释

23.8使用ApplicationRunner或CommandLineRunner

如果您需要在SpringApplication已经启动,您可以实现ApplicationRunnerCommandLineRunner接口。两个接口都以相同的方式工作,并提供了一个run方法,该方法在前面被调用。SpringApplication.run(…​)完成。

这,这个,那,那个CommandLineRunner接口以简单字符串数组的形式提供对应用程序参数的访问,而ApplicationRunner使用ApplicationArguments接口。下面的示例显示CommandLineRunner带着run方法:

import org.springframework.boot.*;
import org.springframework.stereotype.*;

@Component
public class MyBean implements CommandLineRunner {

	public void run(String... args) {
		// Do something...
	}

}

如果几个CommandLineRunnerApplicationRunnerbean被定义为必须按特定顺序调用,您可以另外实现org.springframework.core.Ordered接口或使用org.springframework.core.annotation.Order注释

23.9申请出口

SpringApplication向JVM注册一个关闭挂钩,以确保ApplicationContext在出口处优雅地关闭。所有标准的Spring生命周期回调(如DisposableBean接口或@PreDestroy(注释)可以使用。

此外,bean还可以实现org.springframework.boot.ExitCodeGenerator接口时,如果希望返回特定的退出代码,则为SpringApplication.exit()叫做。然后,可以将此退出代码传递给System.exit()若要将其作为状态代码返回,请参见以下示例:

@SpringBootApplication
public class ExitCodeApplication {

	@Bean
	public ExitCodeGenerator exitCodeGenerator() {
		return () -> 42;
	}

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

}

此外,ExitCodeGenerator接口可以通过异常实现。当遇到这样的异常时,SpringBoot返回实现的退出代码getExitCode()方法。

23.10行政特点

通过指定spring.application.admin.enabled财产。这暴露了SpringApplicationAdminMXBean在站台上MBeanServer。您可以使用此特性远程管理SpringBoot应用程序。此特性对于任何服务包装器实现也可能有用。

[Tip]

如果您想知道应用程序在哪个HTTP端口上运行,请使用local.server.port.

[Caution]谨慎

启用此特性时要小心,因为MBean公开了关闭应用程序的方法。

24.外化配置

SpringBoot允许您将配置外部化,以便在不同的环境中使用相同的应用程序代码。您可以使用属性文件、YAML文件、环境变量和命令行参数来外部化配置.属性可以将属性值直接注入bean中。@Value注释,通过Spring的Environment抽象,或被绑定到结构化对象贯通@ConfigurationProperties.

Spring Boot使用了一个非常特殊的PropertySource旨在允许合理地凌驾于价值观之上的秩序。属性按以下顺序考虑:

  1. DevTools全局设置属性在你的主目录上(~/.spring-boot-devtools.properties当DevTools处于活动状态时)。
  2. @TestPropertySource测试的注释。
  3. properties属性在您的测试中。可在@SpringBootTest用于测试应用程序的特定部分的测试注释.
  4. 命令行参数。
  5. 属性SPRING_APPLICATION_JSON(嵌入到环境变量或系统属性中的内联JSON)。
  6. ServletConfiginit参数
  7. ServletContextinit参数
  8. 的JNDI属性java:comp/env.
  9. Java系统属性(System.getProperties()).
  10. 操作系统环境变量。
  11. RandomValuePropertySource中只具有属性的random.*.
  12. 特定于配置文件的应用程序属性在你包装的罐子外面(application-{profile}.properties和YAML变体)。
  13. 特定于配置文件的应用程序属性包装在你的罐子里(application-{profile}.properties和YAML变体)。
  14. 打包JAR之外的应用程序属性(application.properties和YAML变体)。
  15. 打包在JAR中的应用程序属性(application.properties和YAML变体)。
  16. @PropertySource的注释@Configuration上课。
  17. 默认属性(由设置指定)SpringApplication.setDefaultProperties).

为了提供一个具体的示例,假设您开发了一个@Component使用name属性,如以下示例所示:

import org.springframework.stereotype.*;
import org.springframework.beans.factory.annotation.*;

@Component
public class MyBean {

    @Value("${name}")
    private String name;

    // ...

}

在应用程序类路径(例如,在JAR中)上,可以使用application.properties文件,该文件提供了name。在新环境中运行时,application.properties文件可以在您的JAR之外提供,该JAR覆盖name。对于一次性测试,可以使用特定的命令行开关启动(例如,java -jar app.jar --name="Spring").

[Tip]

这,这个,那,那个SPRING_APPLICATION_JSON属性可以在命令行中使用环境变量提供。例如,您可以在UN*X shell中使用以下行:

$ SPRING_APPLICATION_JSON='{"acme":{"name":"test"}}' java -jar myapp.jar

在前面的示例中,您的结果是acme.name=test春天Environment。您还可以将JSON提供给spring.application.json在系统属性中,如以下示例所示:

$ java -Dspring.application.json='{"name":"test"}' -jar myapp.jar

还可以使用命令行参数提供JSON,如下例所示:

$ java -jar myapp.jar --spring.application.json='{"name":"test"}'

您还可以将JSON作为JNDI变量提供,如下所示:java:comp/env/spring.application.json.

24.1配置随机值

这,这个,那,那个RandomValuePropertySource对于注入随机值(例如,向秘密或测试用例)很有用。它可以生成整数、长、uid或字符串,如以下示例所示:

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

这,这个,那,那个random.int*语法是OPEN value (,max) CLOSE在那里OPEN,CLOSE任何角色value,max是整数。如果max则提供value是最小值,并且max最大值(独占)。

24.2访问命令行属性

默认情况下,SpringApplication转换任何命令行选项参数(即以--,如--server.port=9000)property并将它们添加到春天Environment。如前所述,命令行属性总是优先于其他属性源。

如果不希望将命令行属性添加到Environment,您可以通过以下方式禁用它们SpringApplication.setAddCommandLineProperties(false).

24.3应用程序属性文件

SpringApplicationapplication.properties文件位于以下位置,并将它们添加到Spring中Environment:

  1. /config当前目录的子目录
  2. 当前目录
  3. 类路径/config包装
  4. 类生根

列表按优先级排序(在列表中较高的位置中定义的属性覆盖在较低位置中定义的属性)。

[Note]

你也可以使用YAML(‘.yml’)文件作为“.properties”的替代物。

如果你不喜欢application.properties作为配置文件名,可以通过指定spring.config.name环境属性属性还可以引用显式位置。spring.config.location环境属性(它是以逗号分隔的目录位置或文件路径列表)。下面的示例演示如何指定不同的文件名:

$ java -jar myproject.jar --spring.config.name=myproject

下面的示例演示如何指定两个位置:

$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
[Warning]

spring.config.namespring.config.location用于确定必须加载哪些文件,因此必须将它们定义为环境属性(通常是OS环境变量、系统属性或命令行参数)。

如果spring.config.location包含目录(相对于文件),它们应该以/(并在运行时,附加从spring.config.name在加载之前,包括特定于配置文件的文件名)。中指定的文件spring.config.location作为-is使用,不支持特定于配置文件的变体,并且被任何特定于配置文件的属性覆盖.

配置位置按反向顺序搜索。默认情况下,配置的位置为classpath:/,classpath:/config/,file:./,file:./config/。得到的搜索顺序如下:

  1. file:./config/
  2. file:./
  3. classpath:/config/
  4. classpath:/

当通过以下方式配置自定义配置位置时spring.config.location,它们替换默认位置。例如,如果spring.config.location配置为classpath:/custom-config/,file:./custom-config/,搜索顺序如下:

  1. file:./custom-config/
  2. classpath:custom-config/

或者,当通过以下方法配置自定义配置位置时spring.config.additional-location,除默认位置外,还将使用它们。在默认位置之前搜索其他位置。例如,如果classpath:/custom-config/,file:./custom-config/配置后,搜索顺序如下:

  1. file:./custom-config/
  2. classpath:custom-config/
  3. file:./config/
  4. file:./
  5. classpath:/config/
  6. classpath:/

此搜索顺序允许您在一个配置文件中指定默认值,然后在另一个配置文件中选择性地覆盖这些值。中为应用程序提供默认值。application.properties(或您选择的其他任何基本名称)spring.config.name)在默认位置之一。然后,可以在运行时使用位于其中一个自定义位置的不同文件重写这些默认值。

[Note]

如果使用环境变量而不是系统属性,大多数操作系统都不允许以周期分隔的键名,但可以使用下划线(例如,SPRING_CONFIG_NAME而不是spring.config.name).

[Note]

如果应用程序在容器中运行,则JNDI属性(在java:comp/env)或者可以使用servlet上下文初始化参数来代替环境变量或系统属性,也可以使用环境变量或系统属性。

24.4剖面特性

除了……之外application.properties还可以使用下列命名约定定义特定于配置文件的属性:application-{profile}.properties。这,这个,那,那个Environment具有一组默认配置文件(默认情况下,[default]),如果未设置活动配置文件,则使用。换句话说,如果没有显式激活配置文件,则application-default.properties都装好了。

特定于配置文件的属性是从与标准位置相同的位置加载的。application.properties,使用特定于配置文件的文件总是覆盖非特定的文件,无论配置文件特定的文件是否位于打包的JAR内部或外部。

如果指定了多个配置文件,则应用最后一次获胜策略。例如,由spring.profiles.active属性的配置后添加SpringApplicationAPI,因此优先。

[Note]

如果您在spring.config.location,不考虑这些文件的特定配置文件变体。使用目录spring.config.location如果您也想使用特定于配置文件的属性。

24.5属性中的占位符

中的值application.properties通过现有的Environment当它们被使用时,您可以引用以前定义的值(例如,从系统属性)。

app.name=MyApp
app.description=${app.name} is a Spring Boot application
[Tip]

您还可以使用此技术创建现有SpringBoot属性的“短”变体。见第76.4节,“使用‘短’命令行参数”如何了解细节。

24.6使用YAML代替属性

YAML是JSON的超集,因此是指定分层配置数据的方便格式。这,这个,那,那个SpringApplication类自动支持YAML作为属性的替代方法,只要您有蛇YAML你的类路径上的图书馆。

[Note]

如果使用“starters”,SnakeYAML将自动由spring-boot-starter.

24.6.1装载YAML

SpringFramework提供了两个方便的类,可用于加载YAML文档。这,这个,那,那个YamlPropertiesFactoryBean负载YAML ASPropertiesYamlMapFactoryBean将YAML加载为Map.

例如,考虑以下YAML文档:

environments:
	dev:
		url: http://dev.example.com
		name: Developer Setup
	prod:
		url: http://another.example.com
		name: My Cool App

前面的示例将转换为以下属性:

environments.dev.url=http://dev.example.com
environments.dev.name=Developer Setup
environments.prod.url=http://another.example.com
environments.prod.name=My Cool App

YAML列表表示为[index]脱扣器。例如,考虑以下YAML:

my:
servers:
	- dev.example.com
	- another.example.com

前面的示例将转换为以下属性:

my.servers[0]=dev.example.com
my.servers[1]=another.example.com

通过使用SpringBoot的Binder实用程序(这是@ConfigurationProperties,则需要在类型为java.util.List(或Set),或者需要提供一个setter,或者用一个可变值初始化它。例如,下面的示例绑定到前面显示的属性:

@ConfigurationProperties(prefix="my")
public class Config {

	private List<String> servers = new ArrayList<String>();

	public List<String> getServers() {
		return this.servers;
	}
}

24.6.2在Spring环境中将YAML公开为属性

这,这个,那,那个YamlPropertySourceLoader类可用于将YAML公开为PropertySource春天Environment。这样做可以让您使用@Value带有占位符语法的注释以访问YAML属性。

24.6.3多概况YAML文件

可以在单个文件中指定多个特定于配置文件的YAML文档。spring.profiles键指示何时应用文档,如以下示例所示:

server:
	address: 192.168.1.100
---
spring:
	profiles: development
server:
	address: 127.0.0.1
---
spring:
	profiles: production & eu-central
server:
	address: 192.168.1.120

在前面的示例中,如果development配置文件处于活动状态,则server.address财产127.0.0.1。类似地,如果production  eu-central配置文件处于活动状态,server.address财产192.168.1.120。如果developmentproductioneu-central配置文件是启用,则属性的值为192.168.1.100.

[Note]

spring.profiles因此,可以包含一个简单的配置文件名称(例如production)或配置文件表达式。配置文件表达式允许表示更复杂的配置文件逻辑,例如production & (eu-central | eu-west)。检查参考指南更多细节。

如果在应用程序上下文启动时没有显式活动,默认配置文件将被激活。因此,在下面的YAML中,我们为spring.security.user.password那是可得的在“默认”配置文件中:

server:
  port: 8000
---
spring:
  profiles: default
  security:
    user:
      password: weak

然而,在下面的示例中,密码总是被设置,因为它没有附加到任何配置文件,并且在所有其他配置文件中都必须在必要时显式地重置它:

server:
  port: 8000
spring:
  security:
    user:
      password: weak

使用spring.profiles元素可以通过使用!性格。如果为单个文档指定了否定的和非否定的配置文件,则至少必须有一个非否定的配置文件匹配,并且任何否定的配置文件都不能匹配。

24.6.4 YAML缺陷

属性无法加载YAML文件。@PropertySource注释因此,在需要以这种方式加载值的情况下,需要使用属性文件。

24.7类型安全配置属性

使用@Value("${property}")注入配置属性的注释有时会很麻烦,特别是如果您正在处理多个属性,或者您的数据本质上是分层的。SpringBoot提供了一种使用属性的替代方法,该方法允许强类型bean控制和验证应用程序的配置,如下面的示例所示:

package com.example;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("acme")
public class AcmeProperties {

	private boolean enabled;

	private InetAddress remoteAddress;

	private final Security security = new Security();

	public boolean isEnabled() { ... }

	public void setEnabled(boolean enabled) { ... }

	public InetAddress getRemoteAddress() { ... }

	public void setRemoteAddress(InetAddress remoteAddress) { ... }

	public Security getSecurity() { ... }

	public static class Security {

		private String username;

		private String password;

		private List<String> roles = new ArrayList<>(Collections.singleton("USER"));

		public String getUsername() { ... }

		public void setUsername(String username) { ... }

		public String getPassword() { ... }

		public void setPassword(String password) { ... }

		public List<String> getRoles() { ... }

		public void setRoles(List<String> roles) { ... }

	}
}

前面的POJO定义了以下属性:

  • acme.enabled,值为false默认情况下。
  • acme.remote-address,具有可以被胁迫的类型。String.
  • acme.security.username具有嵌套的“Security”对象,该对象的名称由属性的名称决定。特别是,返回类型根本不被使用,而且可能是SecurityProperties.
  • acme.security.password.
  • acme.security.roles的集合String.
[Note]

getter和setter通常是强制性的,因为绑定是通过标准的JavaBeans属性描述符进行的,就像SpringMVC中的那样。在下列情况下,可省略一位策划人:

  • 映射,只要它们被初始化,就需要一个getter,但不一定是setter,因为它们可以由绑定器进行变异。
  • 可以通过索引(通常使用YAML)或使用单个逗号分隔的值(属性)访问集合和数组。在后一种情况下,策划人是强制性的。我们建议总是为这类型添加一个setter。如果初始化一个集合,请确保它不是不可变的(如前面的示例所示)。
  • 如果初始化了嵌套的POJO属性(如Security字段),则不需要设置器。如果希望活页夹使用默认构造函数动态创建实例,则需要一个setter。

有些人使用ProjectLombok自动添加getter和setter。确保Lombok不会为这种类型生成任何特定的构造函数,因为容器会自动使用它来实例化对象。

最后,只考虑标准JavaBean属性,不支持在静态属性上绑定。

[Tip]

另见之间的差异@Value@ConfigurationProperties.

您还需要列出要在@EnableConfigurationProperties注释,如以下示例所示:

@Configuration
@EnableConfigurationProperties(AcmeProperties.class)
public class MyConfiguration {
}
[Note]

@ConfigurationPropertiesbean是以这种方式注册的,bean有一个常规名称:<prefix>-<fqn>,在哪里<prefix>中指定的环境键前缀。@ConfigurationProperties注释和<fqn>bean的完全限定名。如果注释没有提供任何前缀,则只使用bean的完全限定名。

上面示例中的bean名称是acme-com.example.AcmeProperties.

即使前面的配置为AcmeProperties,我们建议@ConfigurationProperties只处理环境,特别是不从上下文注入其他bean。话虽如此,@EnableConfigurationProperties注释是自动应用于您的项目,以便任何现有带注释的bean@ConfigurationProperties配置为Environment。你可以走捷径MyConfiguration确保AcmeProperties已经是一个bean,如下面的示例所示:

@Component
@ConfigurationProperties(prefix="acme")
public class AcmeProperties {

	// ... see the preceding example

}

这种类型的配置特别适用于SpringApplication外部YAML配置,如以下示例所示:

# application.yml

acme:
	remote-address: 192.168.1.1
	security:
		username: admin
		roles:
		  - USER
		  - ADMIN

# additional configuration as required

与之合作@ConfigurationPropertiesbean,您可以与任何其他bean相同的方式注入它们,如下面的示例所示:

@Service
public class MyService {

	private final AcmeProperties properties;

	@Autowired
	public MyService(AcmeProperties properties) {
	    this.properties = properties;
	}

 	//...

	@PostConstruct
	public void openConnection() {
		Server server = new Server(this.properties.getRemoteAddress());
		// ...
	}

}
[Tip]

使用@ConfigurationProperties此外,您还可以生成元数据文件,这些元数据文件可以被IDE用来为您自己的键提供自动完成。见附录B,配置元数据详见附录。

24.7.1第三方配置

以及使用@ConfigurationProperties若要对类进行注释,还可以将其用于公共类。@Bean方法。当您想要将属性绑定到超出您控制范围的第三方组件时,这样做特别有用。

配置bean的步骤。Environment属性,添加@ConfigurationProperties到它的bean注册,如下面的示例所示:

@ConfigurationProperties(prefix = "another")
@Bean
public AnotherComponent anotherComponent() {
	...
}

属性定义的任何属性。another前缀映射到AnotherComponentbean的方式类似于前面的AcmeProperties举个例子。

24.7.2放宽约束力

SpringBoot使用一些宽松的规则进行绑定Environment属性@ConfigurationProperties类之间不需要完全匹配。Environment属性名称和bean属性名称。有用的常见示例包括破折号分隔的环境属性(例如,context-path绑定到contextPath)和大写环境属性(例如,PORT绑定到port).

例如,请考虑以下几点@ConfigurationProperties班级:

@ConfigurationProperties(prefix="acme.my-project.person")
public class OwnerProperties {

	private String firstName;

	public String getFirstName() {
		return this.firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

}

在前面的示例中,可以使用以下属性名称:

表24.1.松弛结合

财产

acme.my-project.person.first-name

烤肉串箱,推荐用于.properties.yml档案。

acme.myProject.person.firstName

标准骆驼案例语法。

acme.my_project.person.first_name

中使用的另一种格式:下划线表示法。.properties.yml档案。

ACME_MYPROJECT_PERSON_FIRSTNAME

大写格式,在使用系统环境变量时推荐。

 

[Note]

这,这个,那,那个prefix注释的值。以烤肉串(小写)隔开-,如acme.my-project.person).

表24.2.每个属性源放松绑定规则

财产来源简约列单

属性文件

骆驼箱,烤肉串箱,或下划线表示法

标准列表语法[ ]或逗号分隔的值。

YAML档案

骆驼箱,烤肉串箱,或下划线表示法

标准YAML列表语法或逗号分隔的值

环境变量

大写格式,下划线作为分隔符。_不应在属性名称中使用。

由下划线包围的数值,如MY_ACME_1_OTHER = my.acme[1].other

系统性质

骆驼箱,烤肉串箱,或下划线表示法

标准列表语法[ ]或逗号分隔的值。

 

[Tip]

我们建议,在可能的情况下,属性以小写的kebab格式存储,例如my.property-name=acme.

当绑定到Map属性,如果key包含除小写字母-数字字符或-,您需要使用括号表示法,以便保留原始值。如果密钥未被[],任何不是alpha-数字或-都被移走了。例如,考虑将下列属性绑定到Map:

acme:
  map:
    "[/key1]": value1
    "[/key2]": value2
    /key3: value3

上面的属性将绑定到Map带着/key1/key2key3就像地图上的钥匙。

24.7.3合并复杂类型

当在多个地方配置列表时,可以通过替换整个列表来重写。

例如,假设MyPojo对象namedescription属性null默认情况下。下面的示例公开MyPojo对象AcmeProperties:

@ConfigurationProperties("acme")
public class AcmeProperties {

	private final List<MyPojo> list = new ArrayList<>();

	public List<MyPojo> getList() {
		return this.list;
	}

}

考虑以下配置:

acme:
  list:
    - name: my name
      description: my description
---
spring:
  profiles: dev
acme:
  list:
    - name: my another name

如果dev侧写不活跃,AcmeProperties.list包含一个MyPojo条目,如先前定义的。如果dev但是,已启用配置文件。list 仍然只包含一个条目(名称为my another name以及对.的描述null)这种配置加一秒钟MyPojo实例添加到列表中,并且它不合并项。

List在多个配置文件中指定,则使用优先级最高的配置文件(仅使用该配置文件)。考虑以下示例:

acme:
  list:
    - name: my name
      description: my description
    - name: another name
      description: another description
---
spring:
  profiles: dev
acme:
  list:
    - name: my another name

在前面的示例中,如果dev侧写很活跃,AcmeProperties.list MyPojo条目(名称为my another name以及对.的描述null)对于YAML,逗号分隔的列表和YAML列表都可以用于完全覆盖列表的内容。

Map属性,则可以绑定从多个源提取的属性值。但是,对于多个源中的相同属性,则使用具有最高优先级的属性。下面的示例公开Map<String, MyPojo>从…AcmeProperties:

@ConfigurationProperties("acme")
public class AcmeProperties {

	private final Map<String, MyPojo> map = new HashMap<>();

	public Map<String, MyPojo> getMap() {
		return this.map;
	}

}

考虑以下配置:

acme:
  map:
    key1:
      name: my name 1
      description: my description 1
---
spring:
  profiles: dev
acme:
  map:
    key1:
      name: dev name 1
    key2:
      name: dev name 2
      description: dev description 2

如果dev侧写不活跃,AcmeProperties.map包含一个带键的条目key1(名称为my name 1以及对.的描述my description 1)如果dev但是,已启用配置文件,map包含两个带键的条目。key1(名称为dev name 1以及对.的描述my description 1)和key2(名称为dev name 2以及对.的描述dev description 2).

[Note]

前面的合并规则适用于来自所有属性源的属性,而不仅仅是YAML文件。

24.7.4属性转换

当外部应用程序属性绑定到@ConfigurationProperties豆子如果需要自定义类型转换,则可以提供ConversionServicebean(有一个名为conversionService)或自定义属性编辑器(通过CustomEditorConfigurer(豆子)或习惯Converters(将bean定义注释为@ConfigurationPropertiesBinding).

[Note]

由于此bean是在应用程序生命周期早期被请求的,请确保限制您ConversionService正在使用。通常,在创建时可能不会完全初始化所需的任何依赖项。您可能要重命名您的自定义。ConversionService如果它不是配置键强制所必需的,并且仅依赖于符合以下条件的自定义转换器@ConfigurationPropertiesBinding.

转换持续时间

SpringBoot为表示持续时间提供了专门的支持。如果您暴露了java.time.Duration属性时,应用程序属性中的下列格式可用:

  • 常客long表示(使用毫秒作为默认单位,除非@DurationUnit已指定)
  • 标准ISO-8601格式java.util.Duration
  • 一种更易读的格式,其中值和单元耦合在一起(例如,10s表示10秒)

考虑以下示例:

@ConfigurationProperties("app.system")
public class AppSystemProperties {

	@DurationUnit(ChronoUnit.SECONDS)
	private Duration sessionTimeout = Duration.ofSeconds(30);

	private Duration readTimeout = Duration.ofMillis(1000);

	public Duration getSessionTimeout() {
		return this.sessionTimeout;
	}

	public void setSessionTimeout(Duration sessionTimeout) {
		this.sessionTimeout = sessionTimeout;
	}

	public Duration getReadTimeout() {
		return this.readTimeout;
	}

	public void setReadTimeout(Duration readTimeout) {
		this.readTimeout = readTimeout;
	}

}

若要指定30秒的会话超时,30PT30S30s都是等价物。可以下列任何形式指定500 ms的读取超时:500PT0.5S500ms.

您还可以使用任何受支持的单元。它们是:

  • ns纳秒
  • us微秒
  • ms毫秒
  • s几秒钟
  • m几分钟
  • h几个小时
  • d好几天

默认单位为毫秒,可以使用@DurationUnit如上面的示例所示。

[Tip]

如果您正在从简单地使用Long若要表示持续时间,请确保定义单元(使用@DurationUnit)如果切换到Duration。这样做提供了透明的升级路径,同时支持更丰富的格式。

转换数据大小

Spring Framework有一个DataSize值类型,允许以字节表示大小。如果您暴露了DataSize属性时,应用程序属性中的下列格式可用:

  • 常客long表示(使用字节作为默认单位,除非@DataSizeUnit已指定)
  • 一种更易读的格式,其中值和单元耦合在一起(例如,10MB表示10兆字节)

考虑以下示例:

@ConfigurationProperties("app.io")
public class AppIoProperties {

	@DataSizeUnit(DataUnit.MEGABYTES)
	private DataSize bufferSize = DataSize.ofMegabytes(2);

	private DataSize sizeThreshold = DataSize.ofBytes(512);

	public DataSize getBufferSize() {
		return this.bufferSize;
	}

	public void setBufferSize(DataSize bufferSize) {
		this.bufferSize = bufferSize;
	}

	public DataSize getSizeThreshold() {
		return this.sizeThreshold;
	}

	public void setSizeThreshold(DataSize sizeThreshold) {
		this.sizeThreshold = sizeThreshold;
	}

}

若要指定10兆字节的缓冲区大小,1010MB都是等价物。大小阈值为256字节,可指定为256256B.

您还可以使用任何受支持的单元。它们是:

  • B表示字节
  • KB千字节
  • MB兆字节
  • GB千兆字节
  • TB为兆字节

默认单位是字节,可以使用@DataSizeUnit如上面的示例所示。

[Tip]

如果您正在从简单地使用Long若要表示大小,请确保定义单元(使用@DataSizeUnit)如果它不是与开关旁边的字节,则为DataSize。这样做提供了透明的升级路径,同时支持更丰富的格式。

24.7.5@ConfigurationProperties验证

Spring Boot试图验证@ConfigurationProperties类,只要它们被Spring注释@Validated注释您可以使用jsr-303。javax.validation直接对配置类进行约束注释。为此,请确保类路径上有符合JSR-303的实现,然后将约束注释添加到字段中,如下面的示例所示:

@ConfigurationProperties(prefix="acme")
@Validated
public class AcmeProperties {

	@NotNull
	private InetAddress remoteAddress;

	// ... getters and setters

}
[Tip]

还可以通过注释@Bean方法创建配置属性的@Validated.

虽然嵌套属性在绑定时也将得到验证,但最好的做法是将关联字段注释为@Valid。这确保即使没有找到嵌套属性也会触发验证。下面的示例构建在前面的AcmeProperties例子:

@ConfigurationProperties(prefix="acme")
@Validated
public class AcmeProperties {

	@NotNull
	private InetAddress remoteAddress;

	@Valid
	private final Security security = new Security();

	// ... getters and setters

	public static class Security {

		@NotEmpty
		public String username;

		// ... getters and setters

	}

}

还可以添加自定义SpringValidator通过创建一个名为configurationPropertiesValidator。这,这个,那,那个@Bean方法应声明static。配置属性验证器是在应用程序生命周期的早期创建的,并声明@Bean方法可以创建bean,而不必实例化@Configuration班级,等级这样做可以避免任何可能因早期实例化而引起的问题。有一个属性验证样本这说明了如何设置。

[Tip]

这,这个,那,那个spring-boot-actuator模块包括一个公开所有@ConfigurationProperties豆子将web浏览器指向/actuator/configprops或者使用等效的JMX端点。见“生产准备功能“详细情况。

24.7.6@ConfigurationProperties与@Value

这,这个,那,那个@Value注释是一个核心容器特性,它不提供与类型安全配置属性相同的特性。下表总结了@ConfigurationProperties@Value:

特征@ConfigurationProperties@Value

松弛结合

元数据支持

SpEL评价

如果您为您自己的组件定义了一组配置键,我们建议您将它们分组到带注释的POJO中。@ConfigurationProperties。你也应该知道,因为@Value不支持轻松绑定,如果需要使用环境变量提供值,则不是很好的选择。

最后,当您可以编写一个SpEL表达在@Value,这些表达式不是从应用程序属性文件.

25.剖面图

SpringProfiles提供了一种隔离应用程序配置部分并使其仅在特定环境中可用的方法。任何@Component@Configuration可以用@Profile若要限制加载时间,请参见以下示例:

@Configuration
@Profile("production")
public class ProductionConfiguration {

	// ...

}

您可以使用spring.profiles.active Environment属性指定哪些配置文件是活动的。您可以使用本章前面描述的任何方式指定该属性。例如,您可以将它包含在您的application.properties,如以下示例所示:

spring.profiles.active=dev,hsqldb

还可以使用以下开关在命令行中指定它:--spring.profiles.active=dev,hsqldb.

25.1添加活动概要文件

这,这个,那,那个spring.profiles.active属性遵循与其他属性相同的排序规则:PropertySource赢了。这意味着您可以在application.properties然后取代通过使用命令行开关。

有时,具有特定于配置文件的属性是有用的而不是替换它们。这,这个,那,那个spring.profiles.include属性可用于无条件地添加活动配置文件。这,这个,那,那个SpringApplication入口点还具有一个JavaAPI,用于设置其他配置文件(即,在由spring.profiles.active财产)。见setAdditionalProfiles()方法Spring应用.

例如,当使用开关运行具有下列属性的应用程序时,--spring.profiles.active=prodproddbprodmq还启动了配置文件:

---
my.property: fromyamlfile
---
spring.profiles: prod
spring.profiles.include:
  - proddb
  - prodmq
[Note]

记住spring.profiles属性可以在YAML文档中定义,以确定何时将此特定文档包括在配置中。看见第76.7节,“根据环境改变配置”更多细节。

25.2以编程方式设置概要文件

可以通过以下方式以编程方式设置活动配置文件:SpringApplication.setAdditionalProfiles(…​)在应用程序运行之前。还可以使用Spring的ConfigurableEnvironment接口。

25.3配置文件-特定配置文件

特定于配置文件的两种变体application.properties(或application.yml)和通过@ConfigurationProperties被视为文件并加载。见“第24.4节,“配置文件特有的属性”“详细情况。

26.测井

弹簧启动共用测井对于所有内部日志记录,但保持基础日志实现处于打开状态。提供了默认配置。Java Util测井Log4J2,和Logback。在每种情况下,记录器都预先配置为使用控制台输出和可选文件输出。

默认情况下,如果使用“starters”,则使用Logback进行日志记录。还包括适当的Logback路由,以确保使用JavaUtil日志记录、CommonLogging、Log4J或SLF4J的依赖库都正确工作。

[Tip]

Java有很多日志记录框架可用。如果上面的列表看起来很混乱,不要担心。通常,您不需要更改日志记录依赖项,SpringBoot默认设置也很好。

26.1日志格式

SpringBoot的默认日志输出类似于以下示例:

2014-03-05 10:57:51.112  INFO 45469 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.52
2014-03-05 10:57:51.253  INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2014-03-05 10:57:51.253  INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1358 ms
2014-03-05 10:57:51.698  INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2014-03-05 10:57:51.702  INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]

输出的项目如下:

  • 日期和时间:毫秒精度,易于排序。
  • 日志级别:ERRORWARNINFODEBUG,或TRACE.
  • 进程ID
  • ---分隔符以区分实际日志消息的开始。
  • 线程名称:括在方括号中(可以截断控制台输出)。
  • 记录器名称:这通常是源类名(通常缩写)。
  • 日志信息。
[Note]

Logback没有FATAL水平。它被映射到ERROR.

26.2控制台输出

默认日志配置在写入消息时将消息回显到控制台。默认情况下,ERROR-水平,WARN-级别,和INFO-记录级别消息。还可以启用“调试”模式,方法是将应用程序启动为--debug旗子。

$ java -jar myapp.jar --debug
[Note]

您还可以指定debug=true在你的application.properties.

启用调试模式后,将选择核心记录器(嵌入式容器、Hibernate和SpringBoot)以输出更多信息。启用调试模式将应用程序配置为将所有消息记录为DEBUG水平。

或者,您可以启用“跟踪”模式,方法是将应用程序启动为--trace旗(或)trace=true在你的application.properties)这样做可以为选择的核心记录器(嵌入式容器、Hibernate模式生成和整个Spring组合)启用跟踪日志记录。

26.2.1彩色编码输出

如果您的终端支持ANSI,则使用颜色输出来提高可读性。你可以spring.output.ansi.enabled转到支撑值以覆盖自动检测。

颜色编码是通过使用%clr转换词。最简单的形式是,转换器根据日志级别对输出进行着色,如下面的示例所示:

%clr(%5p)

下表描述日志级别到颜色的映射:

水平颜色

FATAL

红色

ERROR

红色

WARN

黄色

INFO

绿色

DEBUG

绿色

TRACE

绿色

或者,您可以通过提供颜色或样式作为转换的选项来指定应该使用的颜色或样式。例如,要使文本变黄,请使用以下设置:

%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow}

支持下列颜色和样式:

  • blue
  • cyan
  • faint
  • green
  • magenta
  • red
  • yellow

26.3文件输出

默认情况下,SpringBoot只记录到控制台,不写入日志文件。如果要在控制台输出之外写入日志文件,则需要设置logging.filelogging.path属性(例如,在application.properties).

下表显示了logging.*属性可以一起使用:

表26.1.测井特性

logging.filelogging.path描述

(无)

(无)

 

控制台只记录。

特定文件

(无)

my.log

写入指定的日志文件。名称可以是确切的位置,也可以是相对于当前目录的位置。

(无)

特定目录

/var/log

写字spring.log到指定的目录。名称可以是确切的位置,也可以是相对于当前目录的位置。

 

日志文件在达到10 MB时旋转,与控制台输出一样,ERROR-水平,WARN-级别,和INFO-默认情况下记录级别消息。大小限制可以使用logging.file.max-size财产。以前旋转的文件被无限期存档,除非logging.file.max-history属性已设置。

[Note]

日志系统是在应用程序生命周期的早期初始化的。因此,在通过@PropertySource注释。

[Tip]

日志属性独立于实际的日志基础结构。因此,特定的配置键(如logback.configurationFile)不是由SpringBoot管理的。

26.4原木水平

所有受支持的日志系统都可以在Spring中设置记录器级别Environment(例如,在application.properties)通过使用logging.level.<logger-name>=<level>哪里level是跟踪、调试、信息、警告、错误、致命或关闭之一。这,这个,那,那个root可以通过以下方式配置记录器:logging.level.root.

下面的示例显示了application.properties:

logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR

26.5原木组

能够将相关的记录器组合在一起,以便能够同时配置它们,这通常是有用的。例如,您可能通常会更改日志记录级别。Tomcat相关的记录器,但您不能轻松地记住顶级软件包。

为此,SpringBoot允许您在Spring中定义日志组Environment。例如,通过将“tomcat”组添加到application.properties:

logging.group.tomcat=org.apache.catalina, org.apache.coyote, org.apache.tomcat

定义完后,可以用一行更改组中所有记录器的级别:

logging.level.tomcat=TRACE

SpringBoot包括下列预定义的日志组,可以开箱即用:

名字,姓名伐木工

万维网

org.springframework.core.codecorg.springframework.httporg.springframework.web

SQL

org.springframework.jdbc.coreorg.hibernate.SQL

26.6自定义日志配置

可以通过在类路径中包含适当的库来激活各种日志系统,并可以通过在类路径根目录中或在下面的Spring指定的位置提供适当的配置文件来进一步定制这些日志系统。Environment财产:logging.config.

可以强制SpringBoot使用特定的日志系统,方法是使用org.springframework.boot.logging.LoggingSystem系统属性值应该是LoggingSystem执行。您还可以完全禁用SpringBoot的日志配置,方法是使用none.

[Note]

因为日志记录是初始化的以前这,这个,那,那个ApplicationContext,则无法从@PropertySources春天@Configuration档案。更改日志记录系统或完全禁用它的唯一方法是通过系统属性。

根据日志记录系统的不同,将加载以下文件:

测井系统定制化

Logback

logback-spring.xmllogback-spring.groovylogback.xml,或logback.groovy

Log4j2

log4j2-spring.xmllog4j2.xml

JDK(Java Util日志记录)

logging.properties

[Note]

如果可能,我们建议您使用-spring日志配置的变体(例如,logback-spring.xml而不是logback.xml)如果使用标准配置位置,Spring无法完全控制日志初始化。

[Warning]

JavaUtil日志记录中存在已知的类加载问题,在从“可执行JAR”运行时会导致问题。如果可能的话,我们建议您在从“可执行的JAR”运行时避免使用它。

为了帮助定制,其他一些属性将从Spring中传输Environment到系统属性,如下表所述:

春季环境系统性质评论意见

logging.exception-conversion-word

LOG_EXCEPTION_CONVERSION_WORD

记录异常时使用的转换字。

logging.file

LOG_FILE

如果已定义,则在默认日志配置中使用。

logging.file.max-size

LOG_FILE_MAX_SIZE

最大日志文件大小(如果启用LOG_FILE)。(仅支持默认的Logback设置。)

logging.file.max-history

LOG_FILE_MAX_HISTORY

要保留的存档日志文件的最大数量(如果启用log_file)。(仅支持默认的Logback设置。)

logging.path

LOG_PATH

如果已定义,则在默认日志配置中使用。

logging.pattern.console

CONSOLE_LOG_PATTERN

要在控制台上使用的日志模式(Stdout)。(仅支持默认的Logback设置。)

logging.pattern.dateformat

LOG_DATEFORMAT_PATTERN

日志日期格式的附录模式。(仅支持默认的Logback设置。)

logging.pattern.file

FILE_LOG_PATTERN

要在文件中使用的日志模式(如果LOG_FILE已启用)。(仅支持默认的Logback设置。)

logging.pattern.level

LOG_LEVEL_PATTERN

在呈现日志级别时使用的格式(默认值)%5p)(仅支持默认的Logback设置。)

PID

PID

当前进程ID(如果可能的话会被发现,如果还没有定义为OS环境变量的话)。

所有受支持的日志记录系统在解析其配置文件时都可以参考系统属性。中的默认配置spring-boot.jar例如:

[Tip]

如果要在日志记录属性中使用占位符,则应使用Spring Boot语法而不是底层框架的语法。特别要注意的是,如果您使用Logback,您应该使用:作为属性名称与其默认值之间的分隔符,而不使用:-.

[Tip]

您可以将mdc和其他临时内容添加到日志行中,只需重写LOG_LEVEL_PATTERN(或logging.pattern.level和Logback一起)。例如,如果您使用logging.pattern.level=user:%X{user} %5p,则默认日志格式包含“user”(如果存在)的MDC条目,如下面的示例所示。

2015-09-30 12:30:04.031 user:someone INFO 22174 --- [  nio-8080-exec-0] demo.Controller
Handling authenticated request

26.7 Logback扩展

SpringBoot包括一些可以帮助高级配置的Logback扩展。您可以在logback-spring.xml配置文件

[Note]

因为标准logback.xml配置文件加载得太早,您不能在其中使用扩展名。你要么用logback-spring.xml或定义logging.config财产。

[Warning]

这些扩展不能与Logback的组态扫描。如果尝试这样做,对配置文件进行更改将导致一个类似于正在记录的以下内容之一的错误:

ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]]

26.7.1配置文件-特定配置

这,这个,那,那个<springProfile>标记允许您根据活动的Spring配置文件选择性地包含或排除配置部分。配置文件中的任何位置都支持配置文件节。<configuration>元素。使用name属性指定哪个配置文件接受配置。这,这个,那,那个<springProfile>标记可以包含一个简单的配置文件名称(例如staging)或配置文件表达式。配置文件表达式允许表示更复杂的配置文件逻辑,例如production & (eu-central | eu-west)。检查参考指南更多细节。下面的清单显示了三个示例配置文件:

<springProfile name="staging">
	<!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>

<springProfile name="dev | staging">
	<!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>

<springProfile name="!production">
	<!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>

26.7.2环境特性

这,这个,那,那个<springProperty>标记允许您公开Spring中的属性Environment在Logback中使用。如果您想从application.properties在您的Logback配置中的文件。标记的工作方式类似于Logback的标准<property>标签。但是,与其指定直接value,您可以指定source(从Environment)如果您需要将该财产存储在local范围内,可以使用scope属性。如果需要回退值(如果属性未在Environment),您可以使用defaultValue属性。下面的示例演示如何公开在Logback中使用的属性:

<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"
		defaultValue="localhost"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
	<remoteHost>${fluentHost}</remoteHost>
	...
</appender>
[Note]

这,这个,那,那个source必须在烤肉串箱中指定(如my.property-name)但是,可以将属性添加到Environment通过使用宽松的规则。

27.开发Web应用程序

SpringBoot非常适合Web应用程序的开发。您可以通过使用嵌入式Tomcat、Jetty、Under拖车或Netty创建一个自包含的HTTP服务器。大多数web应用程序使用spring-boot-starter-web模块快速启动和运行。还可以选择使用spring-boot-starter-webflux模块。

如果你还没有开发一个SpringBootWeb应用程序,你可以按照“HelloWorld!”实例中的开始部分。

27.1“SpringWebMVC框架”

这,这个,那,那个SpringWebMVC框架(通常简称为“SpringMVC”)是一个丰富的“模型视图控制器”Web框架。Springmvc允许您创建特殊的@Controller@RestController用来处理传入的HTTP请求的bean。方法将控制器中的方法映射到HTTP。@RequestMapping注释。

下面的代码显示了一个典型的@RestController它提供JSON数据:

@RestController
@RequestMapping(value="/users")
public class MyRestController {

	@RequestMapping(value="/{user}", method=RequestMethod.GET)
	public User getUser(@PathVariable Long user) {
		// ...
	}

	@RequestMapping(value="/{user}/customers", method=RequestMethod.GET)
	List<Customer> getUserCustomers(@PathVariable Long user) {
		// ...
	}

	@RequestMapping(value="/{user}", method=RequestMethod.DELETE)
	public User deleteUser(@PathVariable Long user) {
		// ...
	}

}

SpringMVC是核心Spring框架的一部分,详细信息可在参考文献。还有几个指南介绍了SpringMVCspring.io/guides.

27.1.1 SpringMVC自动配置

SpringBoot为SpringMVC提供了自动配置,它适用于大多数应用程序。

自动配置在Spring的默认值之上添加了以下特性:

如果您想保持SpringBootMVC特性,并且希望添加额外的MVC配置(拦截器、格式化程序、视图控制器和其他特性),您可以添加自己的@Configuration类型类WebMvcConfigurer @EnableWebMvc。如果您希望提供RequestMappingHandlerMappingRequestMappingHandlerAdapter,或ExceptionHandlerExceptionResolver,您可以声明WebMvcRegistrationsAdapter实例来提供这些组件。

如果您想完全控制SpringMVC,可以添加您自己的@Configuration带注释@EnableWebMvc.

27.1.2 HttpMessage转换器

SpringMVC使用HttpMessageConverter接口来转换HTTP请求和响应。明智之举也包括在内。例如,对象可以自动转换为JSON(通过使用Jackson库)或XML(如果可用的话使用Jackson XML扩展,或者在Jackson XML扩展不可用时使用JAXB)。默认情况下,字符串编码为UTF-8.

如果需要添加或自定义转换器,可以使用SpringBoot的HttpMessageConverters类,如以下清单所示:

import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.context.annotation.*;
import org.springframework.http.converter.*;

@Configuration
public class MyConfiguration {

	@Bean
	public HttpMessageConverters customConverters() {
		HttpMessageConverter<?> additional = ...
		HttpMessageConverter<?> another = ...
		return new HttpMessageConverters(additional, another);
	}

}

任何HttpMessageConverter上下文中存在的bean被添加到转换器列表中。您也可以同样的方式覆盖默认转换器。

27.1.3自定义JSON序列化程序和反序列化器

如果使用Jackson序列化和反序列化JSON数据,则可能需要编写自己的JsonSerializerJsonDeserializer上课。自定义序列化程序通常是通过模块向Jackson注册,但是SpringBoot提供了另一种选择@JsonComponent注释,使直接注册Springbean更加容易。

您可以使用@JsonComponent直接注释JsonSerializerJsonDeserializer实现。还可以在包含序列化器/反序列化器的类中作为内部类使用它,如下面的示例所示:

import java.io.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import org.springframework.boot.jackson.*;

@JsonComponent
public class Example {

	public static class Serializer extends JsonSerializer<SomeObject> {
		// ...
	}

	public static class Deserializer extends JsonDeserializer<SomeObject> {
		// ...
	}

}

@JsonComponent豆类ApplicationContext都会自动注册到杰克逊那里。因为@JsonComponent元注释@Component,适用通常的组件扫描规则。

Spring Boot还提供JsonObjectSerializerJsonObjectDeserializer基类,这些基类在序列化对象时为标准Jackson版本提供了有用的替代方案。看见JsonObjectSerializerJsonObjectDeserializer在Javadoc中获得详细信息。

27.1.4消息代码解析器

SpringMVC有一种用于生成错误代码的策略,用于从绑定错误中呈现错误消息:MessageCodesResolver。如果您设置spring.mvc.message-codes-resolver.format财产PREFIX_ERROR_CODEPOSTFIX_ERROR_CODE,Spring Boot为您创建一个DefaultMessageCodesResolver.Format).

27.1.5静态含量

默认情况下,SpringBoot从一个名为/static(或/public/resources/META-INF/resources)在类路径中或从ServletContext。它使用ResourceHttpRequestHandler,这样您就可以通过添加自己的WebMvcConfigurer和凌驾于addResourceHandlers方法。

在独立的web应用程序中,容器中的默认servlet也被启用,并充当后盾,从ServletContext如果春天决定不处理它。大多数情况下,这种情况不会发生(除非修改默认的MVC配置),因为Spring总是可以通过DispatcherServlet.

默认情况下,资源被映射到/**,但是您可以通过spring.mvc.static-path-pattern财产。例如,将所有资源重新定位到/resources/**可实现以下目标:

spring.mvc.static-path-pattern=/resources/**

还可以使用spring.resources.static-locations属性(将默认值替换为目录位置列表)。根servlet上下文路径,"/"自动添加为一个位置。

除了前面提到的“标准”静态资源位置之外,还为WebJars内容。中具有路径的任何资源。/webjars/**如果JAR文件以Webjars格式打包,则从JAR文件中提供服务。

[Tip]

不要使用src/main/webapp目录,如果应用程序打包为JAR。虽然这个目录是一个通用的标准,但它可以工作。使用WAR打包,如果您生成一个JAR,大多数构建工具都会忽略它。

SpringBoot还支持SpringMVC提供的高级资源处理特性,允许用例,例如破坏缓存的静态资源或Webjars的版本无关URL。

若要将版本无关的URL用于Webjars,请添加webjars-locator-core依赖。然后声明你的Webjar。以jQuery为例,添加"/webjars/jquery/jquery.min.js"结果"/webjars/jquery/x.y.z/jquery.min.js"。哪里x.y.z是Webjar版本。

[Note]

如果使用JBoss,则需要声明webjars-locator-jboss-vfs依赖项,而不是依赖项。webjars-locator-core。否则,所有Webjars将解析为404.

要使用缓存破坏,以下配置为所有静态资源配置缓存破坏解决方案,有效地添加内容散列,如<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>,以URL表示:

spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
[Note]

到资源的链接在运行时用模板重写,这要感谢ResourceUrlEncodingFilter这是为Thymeleaf和FreeMarker自动配置的。使用JSP时,应手动声明此筛选器。其他模板引擎目前不被自动支持,但可以使用自定义模板宏/帮助程序和使用ResourceUrlProvider.

例如,当用JavaScript模块加载器动态加载资源时,重命名文件不是一个选项。这就是为什么其他战略也得到支持并可以结合在一起的原因。“固定”策略在不更改文件名的情况下在URL中添加静态版本字符串,如下面的示例所示:

spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
spring.resources.chain.strategy.fixed.enabled=true
spring.resources.chain.strategy.fixed.paths=/js/lib/
spring.resources.chain.strategy.fixed.version=v12

使用此配置,JavaScript模块位于"/js/lib/"使用固定版本控制策略("/v12/js/lib/mymodule.js"),而其他资源仍然使用内容1(<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>).

看见ResourceProperties获得更多支持的选项。

[Tip]

这个特性已经在一个专用的博客帖子在Spring框架中参考文献.

27.1.6欢迎页

SpringBoot支持静态和模板欢迎页面。它首先寻找一个index.html文件在配置的静态内容位置中。如果找不到一个,它就会查找一个index模板。如果找到其中之一,则自动将其用作应用程序的欢迎页。

27.1.7海关偏袒

春靴favicon.ico在配置的静态内容位置和类路径的根中(按该顺序)。如果存在这样的文件,则自动将其用作应用程序的首选项。

27.1.8路径匹配和内容协商

SpringMVC可以通过查看请求路径并将其匹配到应用程序中定义的映射来将传入的HTTP请求映射到处理程序(例如,@GetMapping控制器方法的注释)。

SpringBoot默认选择禁用后缀模式匹配,这意味着请求类似"GET /projects/spring-boot.json"将无法与@GetMapping("/projects/spring-boot")映射。这被认为是SpringMVC应用程序的最佳实践。这个特性过去主要用于HTTP客户机,它没有发送正确的“接受”请求头;我们需要确保向客户端发送正确的ContentType。如今,内容协商变得更加可靠。

还有其他处理HTTP客户端的方法,这些方法不一致地发送适当的“接受”请求标头。不使用后缀匹配,我们可以使用查询参数来确保请求类似"GET /projects/spring-boot?format=json"将被映射到@GetMapping("/projects/spring-boot"):

spring.mvc.contentnegotiation.favor-parameter=true

# We can change the parameter name, which is "format" by default:
# spring.mvc.contentnegotiation.parameter-name=myparam

# We can also register additional file extensions/media types with:
spring.mvc.contentnegotiation.media-types.markdown=text/markdown

如果您理解这些警告,并且仍然希望您的应用程序使用后缀模式匹配,则需要进行以下配置:

spring.mvc.contentnegotiation.favor-path-extension=true

# You can also restrict that feature to known extensions only
# spring.mvc.pathmatch.use-registered-suffix-pattern=true

# We can also register additional file extensions/media types with:
# spring.mvc.contentnegotiation.media-types.adoc=text/asciidoc

27.1.9 ConfigurableWebBindingInitiators

SpringMVC使用WebBindingInitializer若要初始化WebDataBinder特别的请求。如果你自己创造ConfigurableWebBindingInitializer @Bean,SpringBoot自动配置SpringMVC来使用它。

27.1.10模板引擎

除了RESTWeb服务之外,您还可以使用SpringMVC来提供动态HTML内容。SpringMVC支持多种模板技术,包括Thymeleaf、FreeMarker和JSP。此外,许多其他模板引擎包括自己的SpringMVC集成。

SpringBoot包括对下列模板引擎的自动配置支持:

[Tip]

如果可能,应该避免JSP。有几个已知限制当将它们与嵌入式servlet容器一起使用时。

当您使用默认配置的模板引擎之一时,您的模板将自动从src/main/resources/templates.

[Tip]

根据运行应用程序的方式,IntelliJIDEA对类路径的排序不同。通过IDE的主方法在IDE中运行应用程序,与使用Maven或Gradle或从打包JAR运行应用程序时相比,会产生不同的顺序。这可能导致SpringBoot无法找到类路径上的模板。如果有此问题,可以重新排序IDE中的类路径,以便首先放置模块的类和资源。或者,您可以将模板前缀配置为搜索templates类路径上的目录,如下所示:classpath*:/templates/.

27.1.11错误处理

默认情况下,SpringBoot提供一个/error映射,以合理的方式处理所有错误,并将其注册为servlet容器中的“全局”错误页。对于机器客户端,它生成一个JSON响应,其中包含错误、HTTP状态和异常消息的详细信息。对于浏览器客户端,有一个“Whitelabel”错误视图,它以HTML格式呈现相同的数据(要自定义它,添加一个View决心error)若要完全替换默认行为,可以实现ErrorController并注册该类型的bean定义或添加类型的bean。ErrorAttributes使用现有机制但替换内容。

[Tip]

这,这个,那,那个BasicErrorController可用作自定义的基类。ErrorController。如果要为新的内容类型添加处理程序(默认值是要处理的),这尤其有用。text/html具体而言,并为其他一切提供一个退路)。为此,请扩展BasicErrorController,使用@RequestMapping有一个produces属性,并创建新类型的bean。

还可以定义带注释的类。@ControllerAdvice自定义JSON文档以返回特定控制器和/或异常类型,如下面的示例所示:

@ControllerAdvice(basePackageClasses = AcmeController.class)
public class AcmeControllerAdvice extends ResponseEntityExceptionHandler {

	@ExceptionHandler(YourException.class)
	@ResponseBody
	ResponseEntity<?> handleControllerException(HttpServletRequest request, Throwable ex) {
		HttpStatus status = getStatus(request);
		return new ResponseEntity<>(new CustomErrorType(status.value(), ex.getMessage()), status);
	}

	private HttpStatus getStatus(HttpServletRequest request) {
		Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
		if (statusCode == null) {
			return HttpStatus.INTERNAL_SERVER_ERROR;
		}
		return HttpStatus.valueOf(statusCode);
	}

}

在前面的示例中,如果YourException中定义的控制器引发AcmeController的JSON表示形式。CustomErrorType使用POJO代替ErrorAttributes代表。

自定义错误页

如果要显示给定状态代码的自定义HTML错误页,可以将文件添加到/error文件夹。错误页可以是静态HTML(即在任何静态资源文件夹下添加),也可以使用模板构建。文件的名称应该是确切的状态代码或序列掩码。

例如,要映射404对于静态HTML文件,文件夹结构如下:

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <other public assets>

映射所有5xx使用FreeMarker模板出错,文件夹结构如下所示:

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- templates/
             +- error/
             |   +- 5xx.ftl
             +- <other templates>

对于更复杂的映射,还可以添加实现ErrorViewResolver接口,如以下示例所示:

public class MyErrorViewResolver implements ErrorViewResolver {

	@Override
	public ModelAndView resolveErrorView(HttpServletRequest request,
			HttpStatus status, Map<String, Object> model) {
		// Use the request or status to optionally return a ModelAndView
		return ...
	}

}

您还可以使用常规的SpringMVC功能,如@ExceptionHandler方法@ControllerAdvice。这,这个,那,那个ErrorController然后提取任何未处理的异常。

在SpringMVC之外映射错误页面

对于不使用SpringMVC的应用程序,可以使用ErrorPageRegistrar接口直接注册ErrorPages。此抽象直接用于底层嵌入式servlet容器,即使您没有SpringMVC,也可以工作。DispatcherServlet.

@Bean
public ErrorPageRegistrar errorPageRegistrar(){
	return new MyErrorPageRegistrar();
}

// ...

private static class MyErrorPageRegistrar implements ErrorPageRegistrar {

	@Override
	public void registerErrorPages(ErrorPageRegistry registry) {
		registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
	}

}
[Note]

如果您注册了ErrorPage的路径,该路径将由Filter(与某些非Spring web框架一样,比如泽西岛和Wicket),Filter必须显式注册为ERRORDispatcher,如以下示例所示:

@Bean
public FilterRegistrationBean myFilter() {
	FilterRegistrationBean registration = new FilterRegistrationBean();
	registration.setFilter(new MyFilter());
	...
	registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
	return registration;
}

注意,默认的FilterRegistrationBean不包括ERROR调度员类型。

警告:当部署到servlet容器时,SpringBoot使用其错误页面筛选器将具有错误状态的请求转发到相应的错误页。只有在尚未提交响应的情况下,才能将请求转发到正确的错误页。默认情况下,WebSphereApplicationServer8.0及更高版本在成功完成servlet的服务方法后提交响应。应该通过设置com.ibm.ws.webcontainer.invokeFlushAfterServicefalse.

27.1.12弹簧

如果您开发了一个使用超媒体的RESTfulAPI,SpringBoot为SpringHATEOA提供了自动配置,它可以很好地应用于大多数应用程序。自动配置取代了使用@EnableHypermediaSupport并注册多个bean以方便构建基于超媒体的应用程序,包括LinkDiscoverers(用于客户端支持)和ObjectMapper配置为正确地将响应编组到所需的表示形式。这,这个,那,那个ObjectMapper是通过设置spring.jackson.*属性,或者,如果存在,则由Jackson2ObjectMapperBuilder豆子

您可以通过使用@EnableHypermediaSupport。注意,这样做将禁用ObjectMapper前面描述的自定义。

27.1.13 CORS支持

跨源资源共享(CORS)是W3C规范大多数浏览器这允许您以灵活的方式指定哪些类型的跨域请求是被授权的,而不是使用一些不太安全和功能较弱的方法,例如iframe或JSONP。

截至4.2版,SpringMVC支持CORS。使用控制器方法CORS配置带着@CrossOriginSpringBoot应用程序中的注释不需要任何特定的配置。全局CORS配置可以通过注册WebMvcConfigurer带有自定义的beanaddCorsMappings(CorsRegistry)方法,如以下示例所示:

@Configuration
public class MyConfiguration {

	@Bean
	public WebMvcConfigurer corsConfigurer() {
		return new WebMvcConfigurer() {
			@Override
			public void addCorsMappings(CorsRegistry registry) {
				registry.addMapping("/api/**");
			}
		};
	}
}

27.2“SpringWebFlux框架”

SpringWebFlux是SpringFramework5.0中引入的新的反应性Web框架。与SpringMVC不同,它不需要ServletAPI,完全异步和非阻塞,并实现了反应流规格通过反应堆工程.

SpringWebFlux有两种风格:基于功能的和基于注释的。基于注释的注释非常接近SpringMVC模型,如下面的示例所示:

@RestController
@RequestMapping("/users")
public class MyRestController {

	@GetMapping("/{user}")
	public Mono<User> getUser(@PathVariable Long user) {
		// ...
	}

	@GetMapping("/{user}/customers")
	public Flux<Customer> getUserCustomers(@PathVariable Long user) {
		// ...
	}

	@DeleteMapping("/{user}")
	public Mono<User> deleteUser(@PathVariable Long user) {
		// ...
	}

}

函数变体“WebFlim.fn”将路由配置与请求的实际处理分离开来,如下面的示例所示:

@Configuration
public class RoutingConfiguration {

	@Bean
	public RouterFunction<ServerResponse> monoRouterFunction(UserHandler userHandler) {
		return route(GET("/{user}").and(accept(APPLICATION_JSON)), userHandler::getUser)
				.andRoute(GET("/{user}/customers").and(accept(APPLICATION_JSON)), userHandler::getUserCustomers)
				.andRoute(DELETE("/{user}").and(accept(APPLICATION_JSON)), userHandler::deleteUser);
	}

}

@Component
public class UserHandler {

	public Mono<ServerResponse> getUser(ServerRequest request) {
		// ...
	}

	public Mono<ServerResponse> getUserCustomers(ServerRequest request) {
		// ...
	}

	public Mono<ServerResponse> deleteUser(ServerRequest request) {
		// ...
	}
}

WebFlux是Spring框架的一部分,详细信息可在其参考文献.

[Tip]

你可以定义RouterFunctionbean,因为您喜欢模块化路由器的定义。如果需要应用优先级,可以订购bean。

要开始,添加spring-boot-starter-webflux模块到您的应用程序。

[Note]

加法spring-boot-starter-webspring-boot-starter-webflux应用程序中的模块导致SpringBoot自动配置SpringMVC,而不是WebFlux。之所以选择此行为,是因为许多Spring开发人员添加spring-boot-starter-webflux到他们的SpringMVC应用程序来使用反应性WebClient。仍然可以通过将选定的应用程序类型设置为SpringApplication.setWebApplicationType(WebApplicationType.REACTIVE).

27.2.1 SpringWebFlux自动配置

SpringBoot为SpringWebFlux提供了自动配置,它适用于大多数应用程序。

自动配置在Spring的默认值之上添加了以下特性:

如果您想保持SpringBootWebFlux特性,并且希望添加其他功能WebFlux配置,您可以添加自己的@Configuration类型类WebFluxConfigurer @EnableWebFlux.

如果您想完全控制SpringWebFlux,可以添加您自己的@Configuration带注释@EnableWebFlux.

27.2.2带有HttpMessageReader和HttpMessageWriters的HTTP编解码器

SpringWebFlux使用HttpMessageReaderHttpMessageWriter接口来转换HTTP请求和响应。它们被配置为CodecConfigurer通过查看类路径中可用的库来实现合理的默认值。

Spring Boot使用CodecCustomizer实例。例如spring.jackson.*配置密钥应用于Jackson编解码器。

如果需要添加或自定义编解码器,则可以创建自定义CodecCustomizer组件,如以下示例所示:

import org.springframework.boot.web.codec.CodecCustomizer;

@Configuration
public class MyConfiguration {

	@Bean
	public CodecCustomizer myCodecCustomizer() {
		return codecConfigurer -> {
			// ...
		}
	}

}

你也可以利用引导的自定义JSON序列化程序和反序列化器.

27.2.3静态含量

默认情况下,SpringBoot从一个名为/static(或/public/resources/META-INF/resources)在类路径中。它使用ResourceWebHandler从SpringWebFlux开始,这样您就可以通过添加自己的WebFlux来修改这种行为了。WebFluxConfigurer和凌驾于addResourceHandlers方法。

默认情况下,资源被映射到/**,但是您可以通过设置spring.webflux.static-path-pattern财产。例如,将所有资源重新定位到/resources/**可实现以下目标:

spring.webflux.static-path-pattern=/resources/**

还可以通过以下方法自定义静态资源位置:spring.resources.static-locations。这样做将用目录位置列表替换默认值。如果这样做,默认欢迎页检测切换到自定义位置。所以,如果有一个index.html在启动时的任何位置,它都是应用程序的主页。

除了前面列出的“标准”静态资源位置之外,还为WebJars内容。中具有路径的任何资源。/webjars/**如果JAR文件以Webjars格式打包,则从JAR文件中提供服务。

[Tip]

SpringWebFlux应用程序并不严格依赖ServletAPI,因此它们不能作为WAR文件部署,也不使用src/main/webapp目录。

27.2.4模板引擎

除了RESTWeb服务之外,还可以使用SpringWebFlux提供动态HTML内容。SpringWebFlux支持多种模板技术,包括Thymeleaf、FreeMarker和胡子。

SpringBoot包括对下列模板引擎的自动配置支持:

当您使用默认配置的模板引擎之一时,您的模板将自动从src/main/resources/templates.

27.2.5错误处理

Spring Boot提供了一个WebExceptionHandler以合理的方式处理所有错误。它在处理顺序中的位置就在WebFlux提供的处理程序之前,后者被认为是最后一个。对于机器客户端,它生成一个JSON响应,其中包含错误、HTTP状态和异常消息的详细信息。对于浏览器客户端,有一个“Whitelabel”错误处理程序,它以HTML格式呈现相同的数据。您还可以提供自己的HTML模板来显示错误(请参阅下一节).

自定义此特性的第一步通常涉及使用现有机制,但替换或增强错误内容。为此,可以添加类型为ErrorAttributes.

若要更改错误处理行为,可以实现ErrorWebExceptionHandler并注册该类型的bean定义。因为WebExceptionHandler是相当低级的,SpringBoot也提供了方便。AbstractErrorWebExceptionHandler为了让您以WebFlux函数的方式处理错误,如下面的示例所示:

public class CustomErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {

	// Define constructor here

	@Override
	protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {

		return RouterFunctions
				.route(aPredicate, aHandler)
				.andRoute(anotherPredicate, anotherHandler);
	}

}

要获得更完整的图片,还可以使用子类。DefaultErrorWebExceptionHandler直接覆盖特定方法。

自定义错误页

如果要显示给定状态代码的自定义HTML错误页,可以将文件添加到/error文件夹。错误页可以是静态HTML(即在任何静态资源文件夹下添加),也可以是用模板构建的。文件的名称应该是确切的状态代码或序列掩码。

例如,要映射404对于静态HTML文件,文件夹结构如下:

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <other public assets>

映射所有5xx使用胡子模板出错,文件夹结构如下所示:

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- templates/
             +- error/
             |   +- 5xx.mustache
             +- <other templates>

27.2.6 Web过滤器

SpringWebFlux提供了一个WebFilter接口,可用于过滤HTTP请求-响应交换。WebFilter应用程序上下文中的bean将自动用于筛选每个交换。

在筛选器的顺序很重要的地方,它们可以实现。Ordered或用@Order。SpringBoot自动配置可以为您配置Web过滤器。这样做时,将使用下表中显示的命令:

Web过滤器命令

MetricsWebFilter

Ordered.HIGHEST_PRECEDENCE + 1

WebFilterChainProxy(春季保安)

-100

HttpTraceWebFilter

Ordered.LOWEST_PRECEDENCE - 10

27.3日航-斯普斯卡共和国和泽西岛

如果您更喜欢用于REST端点的JAX-RS编程模型,则可以使用可用的实现之一,而不是SpringMVC。泽西ApacheCXF工作得很好。CXF要求您注册它的ServletFilter作为@Bean在您的应用程序上下文中。泽西有一些原生的Spring支持,所以我们还在SpringBoot中为它提供了自动配置支持,同时还提供了一个启动器。

要开始使用泽西,包括spring-boot-starter-jersey作为一种依赖,那么你就需要一种依赖。@Bean类型ResourceConfig在其中注册所有端点,如以下示例所示:

@Component
public class JerseyConfig extends ResourceConfig {

	public JerseyConfig() {
		register(Endpoint.class);
	}

}
[Warning]

泽西对扫描可执行档案的支持相当有限。例如,它无法扫描在WEB-INF/classes在运行可执行的WAR文件时。若要避免此限制,请将packages方法,并且端点应通过使用register方法,如前面的示例所示。

对于更高级的自定义,还可以注册任意数量的实现ResourceConfigCustomizer.

所有注册的端点应该是@Components使用HTTP资源注释(@GET),如以下示例所示:

@Component
@Path("/hello")
public class Endpoint {

	@GET
	public String message() {
		return "Hello";
	}

}

因为Endpoint是春天@Component,它的生命周期由Spring管理,您可以使用@Autowired注释注入依赖项并使用@Value注解注入外部配置。默认情况下,Jerseyservlet被注册并映射到/*。可以通过添加@ApplicationPath敬你的ResourceConfig.

默认情况下,泽西岛被设置为@Bean类型ServletRegistrationBean命名jerseyServletRegistration。默认情况下,servlet是延迟初始化的,但是可以通过设置spring.jersey.servlet.load-on-startup。您可以使用相同的名称创建自己的bean,从而禁用或重写该bean。还可以通过设置spring.jersey.type=filter(在这种情况下,@Bean替换或覆盖是jerseyFilterRegistration)过滤器有一个@Order,您可以将其设置为spring.jersey.filter.order。servlet和过滤器注册都可以通过以下方式给出init参数:spring.jersey.init.*若要指定属性映射,请执行以下操作。

有一个泽西样本这样你就能看到如何安排好一切。

27.4嵌入式Servlet容器支持

SpringBoot包括对嵌入式系统的支持猫猫码头,和下引服务器。大多数开发人员使用适当的“初学者”来获得完全配置的实例。默认情况下,嵌入式服务器侦听端口上的HTTP请求8080.

[Warning]

如果您选择使用Tomcat onCentOS,请注意,默认情况下,临时目录用于存储已编译的JSP、文件上载等。此目录可由tmpwatch当应用程序运行时,会导致失败。为了避免这种行为,您可能需要自定义tmpwatch这样的配置tomcat.*目录未被删除或配置server.tomcat.basedir这样,嵌入式Tomcat就会使用不同的位置。

27.4.1 servlet、过滤器和侦听器

当使用嵌入式servlet容器时,可以注册servlet、过滤器和所有侦听器(如HttpSessionListener),通过使用Springbean或扫描servlet组件。

将servlet、过滤器和侦听器注册为Springbean

任何ServletFilter,或Servlet*Listener实例,即Springbean在嵌入式容器中注册。如果要引用application.properties在配置过程中。

默认情况下,如果上下文仅包含单个servlet,则将其映射到/。对于多个Servlet bean,bean名称用作路径前缀。过滤器映射到/*.

如果基于约定的映射不够灵活,则可以使用ServletRegistrationBeanFilterRegistrationBean,和ServletListenerRegistrationBean类用于完全控制。

SpringBoot提供了许多自动配置,可以定义过滤器bean。下面是几个过滤器的示例及其各自的顺序(低阶值意味着更高的优先级):

Servlet过滤器命令

OrderedCharacterEncodingFilter

Ordered.HIGHEST_PRECEDENCE

WebMvcMetricsFilter

Ordered.HIGHEST_PRECEDENCE + 1

ErrorPageFilter

Ordered.HIGHEST_PRECEDENCE + 1

HttpTraceFilter

Ordered.LOWEST_PRECEDENCE - 10

通常是安全的,让过滤豆子无序。

如果需要特定的订单,则应避免配置一个筛选器,该筛选器将在Ordered.HIGHEST_PRECEDENCE,因为它可能与应用程序的字符编码配置背道而驰。如果servlet筛选器包装了请求,则应该将其配置为小于或等于FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER.

27.4.2 servlet上下文初始化

嵌入式servlet容器不直接执行Servlet3.0+javax.servlet.ServletContainerInitializer界面或弹簧org.springframework.web.WebApplicationInitializer接口。这是一个有意的设计决策,旨在降低第三方库在WAR中运行可能破坏SpringBoot应用程序的风险。

如果需要在SpringBoot应用程序中执行servlet上下文初始化,则应该注册一个实现org.springframework.boot.web.servlet.ServletContextInitializer接口。单曲onStartup方法提供对ServletContext并且,如果有必要,可以很容易地用作现有的适配器。WebApplicationInitializer.

扫描servlet、过滤器和侦听器

使用嵌入式容器时,自动注册带注释的类@WebServlet@WebFilter,和@WebListener可以通过以下方式启用@ServletComponentScan.

[Tip]

@ServletComponentScan在独立容器中没有任何影响,在这种情况下,容器的内置发现机制被使用。

27.4.3 ServletWebServerApplicationContext

在引擎盖下,SpringBoot使用了一种不同类型的ApplicationContext支持嵌入式servlet容器。这,这个,那,那个ServletWebServerApplicationContext是一种特殊的WebApplicationContext通过搜索单个ServletWebServerFactory豆子通常是TomcatServletWebServerFactoryJettyServletWebServerFactory,或UndertowServletWebServerFactory已经自动配置好了。

[Note]

您通常不需要知道这些实现类。大多数应用程序都是自动配置的,并且ApplicationContextServletWebServerFactory都是代表你创造的。

27.4.4定制嵌入式servlet容器

可以使用Spring配置常见的servlet容器设置Environment财产。通常,您将在application.properties档案。

常见的服务器设置包括:

  • 网络设置:监听传入HTTP请求的端口(server.port),要绑定到的接口地址。server.address等等。
  • 会话设置:会话是否持久(server.servlet.session.persistence),会话超时(server.servlet.session.timeout),会话数据的位置(server.servlet.session.store-dir),以及会话-cookie配置(server.servlet.session.cookie.*).
  • 错误管理:错误页面的位置(server.error.path等等。
  • SSL
  • http压缩

SpringBoot尽可能多地尝试公开公共设置,但这并不总是可能的。对于这些情况,专用名称空间提供特定于服务器的自定义(请参阅server.tomcatserver.undertow)例如访问日志可以使用嵌入式servlet容器的特定功能进行配置。

[Tip]

ServerProperties类获取完整列表。

程序定制

如果需要以编程方式配置嵌入的servlet容器,则可以注册实现WebServerFactoryCustomizer接口。WebServerFactoryCustomizer提供对ConfigurableServletWebServerFactory,其中包括许多定制的setter方法。下面的示例显示了以编程方式设置端口:

import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.stereotype.Component;

@Component
public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {

	@Override
	public void customize(ConfigurableServletWebServerFactory server) {
		server.setPort(9000);
	}

}
[Note]

TomcatServletWebServerFactoryJettyServletWebServerFactoryUndertowServletWebServerFactory的专用变体ConfigurableServletWebServerFactory它们分别为Tomcat、Jetty和Undertext提供了额外的自定义setter方法。

直接定制ConfigurableServletWebServerFactory

如果前面的自定义技术太有限,则可以注册TomcatServletWebServerFactoryJettyServletWebServerFactory,或UndertowServletWebServerFactory你自己吃吧。

@Bean
public ConfigurableServletWebServerFactory webServerFactory() {
	TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
	factory.setPort(9000);
	factory.setSessionTimeout(10, TimeUnit.MINUTES);
	factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notfound.html"));
	return factory;
}

为许多配置选项提供了setter。如果您需要做一些更有异国情调的事情,还提供了几个受保护的方法“钩子”。见源代码文档关于细节。

27.4.5 JSP限制

当运行使用嵌入式servlet容器(并打包为可执行存档)的SpringBoot应用程序时,JSP支持有一些限制。

  • 对于Jetty和Tomcat,如果您使用WAR打包,它应该可以工作。可执行的WAR将在与java -jar,也可以部署到任何标准容器中。在使用可执行JAR时,不支持JPS。
  • 欠付不支持JSP。
  • 创建自定义error.jsp页不覆盖默认视图。错误处理自定义错误页应该用它代替。

有一个JSP样本这样你就能看到如何安排好一切。

28.保安

如果弹簧安全在类路径上,则Web应用程序在默认情况下是安全的。Spring Boot依赖SpringSecurity的内容协商策略来决定是否使用httpBasicformLogin。若要向web应用程序添加方法级安全性,还可以添加@EnableGlobalMethodSecurity有你想要的设置。更多信息可在弹簧安全参考指南.

默认UserDetailsService只有一个用户。用户名是user,密码是随机的,在应用程序启动时在信息级别打印,如下面的示例所示:

Using generated security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35
[Note]

如果您微调日志记录配置,请确保org.springframework.boot.autoconfigure.security类别设置为日志。INFO-级别信息。否则,将不打印默认密码。

您可以通过提供spring.security.user.namespring.security.user.password.

默认情况下,Web应用程序中获得的基本功能如下:

  • UserDetailsService(或ReactiveUserDetailsService在WebFlux应用程序的情况下,bean具有内存存储和生成密码的单个用户(请参见SecurityProperties.User对于用户的属性)。
  • 整个应用程序的基于表单的登录或HTTP基本安全性(取决于内容类型)(如果执行器位于类路径上,则包括执行器端点)。
  • DefaultAuthenticationEventPublisher用于发布身份验证事件。

你可以提供不同的AuthenticationEventPublisher为它添加一个豆子。

28.1 MVC安全性

默认安全配置是在SecurityAutoConfigurationUserDetailsServiceAutoConfigurationSecurityAutoConfiguration进口品SpringBootWebSecurityConfiguration对于网络安全和UserDetailsServiceAutoConfiguration配置身份验证,这也与非web应用程序相关。若要完全关闭默认web应用程序安全配置,可以添加类型为WebSecurityConfigurerAdapter(这样做不会禁用UserDetailsService配置或执行器的安全性)。

也可以关闭UserDetailsService配置时,可以添加类型为UserDetailsServiceAuthenticationProvider,或AuthenticationManager。中有几个安全应用程序。弹簧启动样本让您从通用例开始。

可以通过添加自定义来重写访问规则。WebSecurityConfigurerAdapter。SpringBoot提供了方便的方法,可以用来覆盖执行器端点和静态资源的访问规则。EndpointRequest可以用来创建RequestMatcher,这是基于management.endpoints.web.base-path财产。PathRequest可以用来创建RequestMatcher用于常用地点的资源。

28.2 WebFlux安全

类似于SpringMVC应用程序,可以通过添加spring-boot-starter-security依赖。默认安全配置是在ReactiveSecurityAutoConfigurationUserDetailsServiceAutoConfigurationReactiveSecurityAutoConfiguration进口品WebFluxSecurityConfiguration对于网络安全和UserDetailsServiceAutoConfiguration配置身份验证,这也与非web应用程序相关。若要完全关闭默认web应用程序安全配置,可以添加类型为WebFilterChainProxy(这样做不会禁用UserDetailsService配置或执行器的安全性)。

也可以关闭UserDetailsService配置时,可以添加类型为ReactiveUserDetailsServiceReactiveAuthenticationManager.

可以通过添加自定义来配置访问规则。SecurityWebFilterChain。SpringBoot提供了方便的方法,可以用来覆盖执行器端点和静态资源的访问规则。EndpointRequest可以用来创建ServerWebExchangeMatcher,这是基于management.endpoints.web.base-path财产。

PathRequest可以用来创建ServerWebExchangeMatcher用于常用地点的资源。

例如,您可以通过添加以下内容来自定义您的安全配置:

@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	return http
		.authorizeExchange()
			.matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
			.pathMatchers("/foo", "/bar")
				.authenticated().and()
			.formLogin().and()
		.build();
}

28.3 OAuth2

OAuth2是Spring支持的广泛使用的授权框架。

28.3.1客户

如果你有spring-security-oauth2-client在类路径上,您可以利用一些自动配置来轻松地设置OAuth2/OpenIDConnect客户端。此配置使用OAuth2ClientProperties.

对象下注册多个OAuth2/OpenID连接提供程序。spring.security.oauth2.client.provider前缀,如以下示例所示:

spring.security.oauth2.client.provider.my-oauth-provider.authorization-uri=http://my-auth-server/oauth/authorize
spring.security.oauth2.client.provider.my-oauth-provider.token-uri=http://my-auth-server/oauth/token
spring.security.oauth2.client.provider.my-oauth-provider.user-info-uri=http://my-auth-server/userinfo
spring.security.oauth2.client.provider.my-oauth-provider.user-info-authentication-method=header
spring.security.oauth2.client.provider.my-oauth-provider.jwk-set-uri=http://my-auth-server/token_keys
spring.security.oauth2.client.provider.my-oauth-provider.user-name-attribute=name

对于支持OpenID连接提供程序的OpenID连接发现,可以进一步简化配置。提供程序需要配置issuer-uri它断言的URI是它的颁发者标识符。例如,如果issuer-uri提供的是“https:/example.com”,然后是OpenID Provider Configuration Request将被制作成“https://example.com/.well-known/openid-configuration”.预期结果将是OpenID Provider Configuration Response。下面的示例演示如何使用issuer-uri:

spring.security.oauth2.client.provider.oidc-provider.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/

OpenID连接登录客户端注册

对象下注册多个开放ID连接客户端。spring.security.oauth2.client.registration.login前缀,如以下示例所示:

spring.security.oauth2.client.registration.login.my-client-1.client-id=abcd
spring.security.oauth2.client.registration.login.my-client-1.client-secret=password
spring.security.oauth2.client.registration.login.my-client-1.client-name=Client for user scope
spring.security.oauth2.client.registration.login.my-client-1.provider=my-oauth-provider
spring.security.oauth2.client.registration.login.my-client-1.scope=user
spring.security.oauth2.client.registration.login.my-client-1.redirect-uri=http://localhost:8080/login/oauth2/code/my-client-1
spring.security.oauth2.client.registration.login.my-client-1.client-authentication-method=basic
spring.security.oauth2.client.registration.login.my-client-1.authorization-grant-type=authorization_code

spring.security.oauth2.client.registration.login.my-client-2.client-id=abcd
spring.security.oauth2.client.registration.login.my-client-2.client-secret=password
spring.security.oauth2.client.registration.login.my-client-2.client-name=Client for email scope
spring.security.oauth2.client.registration.login.my-client-2.provider=my-oauth-provider
spring.security.oauth2.client.registration.login.my-client-2.scope=email
spring.security.oauth2.client.registration.login.my-client-2.redirect-uri=http://localhost:8080/login/oauth2/code/my-client-2
spring.security.oauth2.client.registration.login.my-client-2.client-authentication-method=basic
spring.security.oauth2.client.registration.login.my-client-2.authorization-grant-type=authorization_code

默认情况下,Spring的OAuth2LoginAuthenticationFilter只处理URL匹配/login/oauth2/code/*。如果要自定义redirect-uri要使用不同的模式,您需要提供配置来处理该自定义模式。例如,对于servlet应用程序,可以添加自己的WebSecurityConfigurerAdapter这类似于以下几点:

public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http
			.authorizeRequests()
				.anyRequest().authenticated()
				.and()
			.oauth2Login()
				.redirectionEndpoint()
					.baseUri("/custom-callback");
	}
}

同样的属性也适用于servlet和反应性应用程序。

OAuth2授权代码客户端注册

您可以注册多个OAuth2authorization_code客户在spring.security.oauth2.client.registration.authorization-code前缀,如以下示例所示:

spring.security.oauth2.client.registration.authorization-code.my-client-1.client-id=abcd
spring.security.oauth2.client.registration.authorization-code.my-client-1.client-secret=password
spring.security.oauth2.client.registration.authorization-code.my-client-1.client-name=Client for user scope
spring.security.oauth2.client.registration.authorization-code.my-client-1.provider=my-oauth-provider
spring.security.oauth2.client.registration.authorization-code.my-client-1.scope=user
spring.security.oauth2.client.registration.authorization-code.my-client-1.redirect-uri=http://my-redirect-uri.com
spring.security.oauth2.client.registration.authorization-code.my-client-1.client-authentication-method=basic
spring.security.oauth2.client.registration.authorization-code.my-client-1.authorization-grant-type=authorization_code

spring.security.oauth2.client.registration.authorization-code.my-client-2.client-id=abcd
spring.security.oauth2.client.registration.authorization-code.my-client-2.client-secret=password
spring.security.oauth2.client.registration.authorization-code.my-client-2.client-name=Client for email scope
spring.security.oauth2.client.registration.authorization-code.my-client-2.provider=my-oauth-provider
spring.security.oauth2.client.registration.authorization-code.my-client-2.scope=email
spring.security.oauth2.client.registration.authorization-code.my-client-2.redirect-uri=http://my-redirect-uri.com
spring.security.oauth2.client.registration.authorization-code.my-client-2.client-authentication-method=basic
spring.security.oauth2.client.registration.authorization-code.my-client-2.authorization-grant-type=authorization_code

OAuth2通用提供者的客户端注册

对于常见的OAuth2和OpenID提供商,包括Google、Gizub、Facebook和Okta,我们提供了一组提供者默认值(googlegithubfacebook,和okta分别)。

如果不需要自定义这些提供程序,则可以将provider属性为需要推断默认值的属性。此外,如果客户端的ID与默认支持的提供程序匹配,SpringBoot也会推断这一点。

换句话说,以下示例中的两个配置使用Google Provider:

spring.security.oauth2.client.registration.login.my-client.client-id=abcd
spring.security.oauth2.client.registration.login.my-client.client-secret=password
spring.security.oauth2.client.registration.login.my-client.provider=google

spring.security.oauth2.client.registration.login.google.client-id=abcd
spring.security.oauth2.client.registration.login.google.client-secret=password

28.3.2资源服务器

如果你有spring-security-oauth2-resource-server在类路径上,只要指定了JWK集URI或OIDC Issuer URI,Spring Boot就可以设置OAuth2资源服务器,如以下示例所示:

spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://example.com/oauth2/default/v1/keys
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/

同样的属性也适用于servlet和反应性应用程序。

或者,您可以定义自己的JwtDecoder用于servlet应用程序的bean或ReactiveJwtDecoder用于反应性应用。

28.3.3授权服务器

目前,SpringSecurity不支持实现OAuth2.0授权服务器。但是,此功能可从弹簧安全OAuth项目,它最终将被SpringSecurity完全取代。在此之前,您可以使用spring-security-oauth2-autoconfigure模块以轻松设置OAuth2.0授权服务器;请参见其文献资料为了得到指示。

28.4执行器安全

为安全起见,除/health/info默认情况下禁用。这,这个,那,那个management.endpoints.web.exposure.include属性可用于启用执行机构。

如果Spring安全性位于类路径上,并且没有其他WebSecurityConfigurerAdapter,则除/health/info由SpringBoot自动配置保护。如果您定义了一个自定义WebSecurityConfigurerAdapter,SpringBoot自动配置将退出,您将完全控制执行器访问规则。

[Note]

在设置management.endpoints.web.exposure.include,确保公开的执行机构不包含敏感信息和/或通过将它们放置在防火墙后面或类似Spring Security的地方进行保护。

28.4.1跨站点请求伪造保护

由于SpringBoot依赖SpringSecurity的默认设置,默认情况下CSRF保护是打开的。这意味着执行器端点需要POST(关机和记录器端点),PUTDELETE在使用默认安全配置时,将得到一个403禁止的错误。

[Note]

只有在创建非浏览器客户端使用的服务时,我们才建议完全禁用CSRF保护。

有关csrf保护的其他信息,请参阅弹簧安全参考指南.

29.使用SQL数据库

这,这个,那,那个弹簧框架提供对使用sql数据库的广泛支持,可直接使用jdbc访问JdbcTemplate来完成诸如Hibernate之类的“对象关系映射”技术。弹簧数据提供额外的功能级别:创建Repository直接从接口实现,并使用约定从您的方法名称生成查询。

29.1配置数据源

爪哇javax.sql.DataSource接口提供了处理数据库连接的标准方法。传统上,“DataSource”使用URL以及建立数据库连接的一些凭据。

[Tip]

看见“如何到”一节对于更高级的示例,通常要完全控制DataSource的配置。

29.1.1嵌入式数据库支持

使用内存内嵌入式数据库开发应用程序通常很方便.显然,内存中的数据库不提供持久存储.您需要在应用程序启动时填充数据库,并准备好在应用程序结束时丢弃数据。

[Tip]

“如何到”部分包括一节,介绍如何初始化数据库。.

弹簧引导可以自动配置嵌入式。HSQL,和德比数据库。您不需要提供任何连接URL。只需将构建依赖项包含到要使用的嵌入式数据库。

[Note]

如果您在测试中使用此功能,您可能会注意到,无论您使用多少应用程序上下文,整个测试套件都重用相同的数据库。如果要确保每个上下文都有单独的嵌入式数据库,则应设置spring.datasource.generate-unique-nametrue.

例如,典型的POM依赖关系如下:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
	<groupId>org.hsqldb</groupId>
	<artifactId>hsqldb</artifactId>
	<scope>runtime</scope>
</dependency>
[Note]

你需要依赖spring-jdbc对于要自动配置的嵌入式数据库。在这个例子中,它是通过spring-boot-starter-data-jpa.

[Tip]

如果出于任何原因,您确实为嵌入式数据库配置了连接URL,请注意确保禁用了数据库的自动关闭。如果你使用h2,你应该使用DB_CLOSE_ON_EXIT=FALSE这样做。如果使用HSQLDB,则应确保shutdown=true不被使用。禁用数据库的自动关闭使SpringBoot可以在数据库关闭时进行控制,从而确保一旦不再需要对数据库的访问,就会发生这种情况。

29.1.2连接到生产数据库

还可以使用池自动配置生产数据库连接。DataSource。Spring Boot使用以下算法来选择特定的实现:

  1. 我们更喜欢HikariCP因为它的性能和并发性。如果HikariCP可用,我们总是选择它。
  2. 否则,如果Tomcat池DataSource是可用的,我们用它。
  3. 如果没有HikariCP或Tomcat池数据源,并且共用DBCP 2是可用的,我们用它。

如果您使用spring-boot-starter-jdbcspring-boot-starter-data-jpa“Starters”,您将自动获得一个依赖项HikariCP.

[Note]

可以完全绕过该算法,并通过设置spring.datasource.type财产。如果您在Tomcat容器中运行应用程序,这一点尤其重要,如tomcat-jdbc默认情况下提供。

[Tip]

其他连接池始终可以手动配置。如果你定义了你自己的DataSourcebean,不发生自动配置.

中的外部配置属性控制数据源配置。spring.datasource.*。例如,您可以在application.properties:

spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
[Note]

您至少应该通过设置spring.datasource.url财产。否则,SpringBoot尝试自动配置嵌入式数据库.

[Tip]

您通常不需要指定driver-class-name,因为SpringBoot可以从url.

[Note]

为了汇集DataSource要创建,我们需要能够验证Driver类是可用的,所以我们在做任何事情之前都要检查它。换句话说,如果你spring.datasource.driver-class-name=com.mysql.jdbc.Driver,那么这个类必须是可加载的。

看见DataSourceProperties有关更多受支持的选项。无论实际实现如何,这些都是有效的标准选项。还可以使用它们各自的前缀对特定于实现的设置进行微调(spring.datasource.hikari.*spring.datasource.tomcat.*,和spring.datasource.dbcp2.*)有关详细信息,请参阅您正在使用的连接池实现的文档。

例如,如果您使用Tomcat连接池,您可以自定义许多其他设置,如以下示例所示:

# Number of ms to wait before throwing an exception if no connection is available.
spring.datasource.tomcat.max-wait=10000

# Maximum number of active connections that can be allocated from this pool at the same time.
spring.datasource.tomcat.max-active=50

# Validate the connection before borrowing it from the pool.
spring.datasource.tomcat.test-on-borrow=true

29.1.3连接到JNDI数据源

如果将SpringBoot应用程序部署到ApplicationServer,则可能需要使用ApplicationServer的内置特性配置和管理DataSource,并使用JNDI访问它。

这,这个,那,那个spring.datasource.jndi-name属性可用作spring.datasource.urlspring.datasource.username,和spring.datasource.password属性访问DataSource从特定的JNDI位置。例如,application.properties演示如何按定义访问JBossDataSource:

spring.datasource.jndi-name=java:jboss/datasources/customers

29.2使用JdbcTemplate

春天的JdbcTemplateNamedParameterJdbcTemplate类是自动配置的,您可以@Autowire它们直接进入您自己的bean中,如下面的示例所示:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

	private final JdbcTemplate jdbcTemplate;

	@Autowired
	public MyBean(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	// ...

}

控件可以自定义模板的某些属性。spring.jdbc.template.*属性,如以下示例所示:

spring.jdbc.template.max-rows=500
[Note]

这,这个,那,那个NamedParameterJdbcTemplate重用相同JdbcTemplate幕后的例子。如果不止一个JdbcTemplate定义,并且不存在主候选,则NamedParameterJdbcTemplate不是自动配置的。

29.3 JPA和Spring Data JPA

JavaPersistenceAPI是一种标准技术,允许您将对象“映射”到关系数据库。这,这个,那,那个spring-boot-starter-data-jpaPOM提供了一种快速入门的方法。它提供了以下关键依赖项:

  • Hibernate:最流行的JPA实现之一。
  • SpringDataJPA:使基于JPA的存储库易于实现。
  • SpringOrms:Spring框架中的核心ORM支持。
[Tip]

我们不会详细讨论JPA或弹簧数据这里你可以跟着“使用JPA访问数据”spring.io并阅读春季数据JPA冬眠参考文件。

29.3.1实体类

传统上,JPA“实体”类是在persistence.xml档案。对于SpringBoot,这个文件是不必要的,取而代之的是“实体扫描”。默认情况下,主配置类下面的所有包(用@EnableAutoConfiguration@SpringBootApplication)被搜查。

带注释的任何类@Entity@Embeddable,或@MappedSuperclass都被考虑了。典型的实体类似于以下示例:

package com.example.myapp.domain;

import java.io.Serializable;
import javax.persistence.*;

@Entity
public class City implements Serializable {

	@Id
	@GeneratedValue
	private Long id;

	@Column(nullable = false)
	private String name;

	@Column(nullable = false)
	private String state;

	// ... additional members, often include @OneToMany mappings

	protected City() {
		// no-args constructor required by JPA spec
		// this one is protected since it shouldn't be used directly
	}

	public City(String name, String state) {
		this.name = name;
		this.state = state;
	}

	public String getName() {
		return this.name;
	}

	public String getState() {
		return this.state;
	}

	// ... etc

}
[Tip]

属性自定义实体扫描位置。@EntityScan注释见“第83.4节,“将@实体定义与Spring配置分开”“怎么.

29.3.2 Spring数据JPA存储库

春季数据JPA存储库是您可以定义的访问数据的接口。JPA查询是根据您的方法名称自动创建的。例如,CityRepository接口可能会声明findAllByState(String state)方法来查找处于给定状态的所有城市。

对于更复杂的查询,可以使用Spring数据的Query注释

Spring数据存储库通常从RepositoryCrudRepository接口。如果使用自动配置,则从包含主配置类的包(带注释的类)中搜索存储库。@EnableAutoConfiguration@SpringBootApplication)趴下。

下面的示例显示了典型的Spring数据存储库接口定义:

package com.example.myapp.domain;

import org.springframework.data.domain.*;
import org.springframework.data.repository.*;

public interface CityRepository extends Repository<City, Long> {

	Page<City> findAll(Pageable pageable);

	City findByNameAndStateAllIgnoringCase(String name, String state);

}

SpringDataJPA存储库支持三种不同的引导模式:默认模式、延迟模式和延迟模式。若要启用延迟或延迟引导,请将spring.data.jpa.repositories.bootstrap-modedeferredlazy分别。使用延迟或延迟引导时,自动配置EntityManagerFactoryBuilder将使用上下文的异步任务执行器(如果有的话)作为引导执行器。

[Tip]

我们几乎没有触及SpringDataJPA的表面。有关详细信息,请参阅Spring数据JPA参考文档.

29.3.3创建和删除JPA数据库

默认情况下,会自动创建jpa数据库。如果使用嵌入式数据库(H2、HSQL或Derby)。可以通过以下方法显式配置JPA设置:spring.jpa.*财产。例如,要创建和删除表,可以将以下行添加到application.properties:

spring.jpa.hibernate.ddl-auto=create-drop
[Note]

Hibernate自己的内部属性名(如果您更好地记住它)是hibernate.hbm2ddl.auto。可以与其他Hibernate本机属性一起设置它,方法是spring.jpa.properties.*(在将前缀添加到实体管理器之前先去掉前缀)。下一行展示了为Hibernate设置JPA属性的示例:

spring.jpa.properties.hibernate.globally_quoted_identifiers=true

前面示例中的行传递的值为truehibernate.globally_quoted_identifiers属性设置为Hibernate实体管理器。

默认情况下,DDL执行(或验证)将推迟到ApplicationContext已经开始了。还有一个spring.jpa.generate-ddl标志,但如果Hibernate自动配置处于活动状态,则不使用它,因为ddl-auto设置更细粒度.

29.3.4视图中的OpenEntityManager

如果正在运行web应用程序,默认情况下SpringBoot注册OpenEntityManagerInViewInterceptor应用“OpenEntityManager in View”模式,允许在web视图中延迟加载。如果不想要这种行为,则应设置spring.jpa.open-in-viewfalse在你的application.properties.

29.4 Spring数据JDBC

Spring数据包括对jdbc的存储库支持,并将自动为CrudRepository。对于更高级的查询,@Query提供了注释。

当类路径上有必要的依赖项时,SpringBoot将自动配置Spring数据的JDBC存储库。可以通过一个依赖项将它们添加到您的项目中。spring-boot-starter-data-jdbc。如果有必要,可以通过添加@EnableJdbcRepositories注释或JdbcConfiguration应用程序的子类。

[Tip]

有关SpringDataJDBC的详细信息,请参阅参考文献.

29.5使用H2的Web控制台

这,这个,那,那个H2数据库提供一个基于浏览器的控制台Spring Boot可以自动为您配置。当满足下列条件时,控制台将自动配置:

  • 您正在开发一个基于servlet的Web应用程序。
  • com.h2database:h2在类路径上。
  • 你在用Spring Boot开发工具.
[Tip]

如果您没有使用SpringBoot的开发工具,但仍然希望使用h2的控制台,则可以配置spring.h2.console.enabled属性的值为true.

[Note]

h2控制台仅供开发期间使用,因此您应注意确保spring.h2.console.enabled未设置为true在生产中。

29.5.1更改H2控制台的路径

默认情况下,控制台可在/h2-console。控件可以自定义控制台的路径。spring.h2.console.path财产。

29.6使用jOOQ

面向Java对象的查询(JOOQ)是一种流行的产品数据奇才它从数据库中生成Java代码,并允许您通过其FLUENT API构建类型安全的SQL查询。商业版本和开源版本都可以与SpringBoot一起使用。

29.6.1代码生成

为了使用jOOQ类型安全查询,需要从数据库模式生成Java类。您可以按照JOOQ用户手册。如果您使用jooq-codegen-maven插件,您也可以使用spring-boot-starter-parent“父POM”,您可以安全地省略插件的<version>标签。还可以使用SpringBoot定义的版本变量(如h2.version)声明插件的数据库依赖关系。下面的清单显示了一个示例:

<plugin>
	<groupId>org.jooq</groupId>
	<artifactId>jooq-codegen-maven</artifactId>
	<executions>
		...
	</executions>
	<dependencies>
		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<version>${h2.version}</version>
		</dependency>
	</dependencies>
	<configuration>
		<jdbc>
			<driver>org.h2.Driver</driver>
			<url>jdbc:h2:~/yourdatabase</url>
		</jdbc>
		<generator>
			...
		</generator>
	</configuration>
</plugin>

29.6.2使用DSLContext

jOOQ提供的Fluent API是通过org.jooq.DSLContext接口。Spring Boot自动配置DSLContext作为SpringBean并将其连接到应用程序DataSource。使用DSLContext,你可以@Autowire如以下示例所示:

@Component
public class JooqExample implements CommandLineRunner {

	private final DSLContext create;

	@Autowired
	public JooqExample(DSLContext dslContext) {
		this.create = dslContext;
	}

}
[Tip]

jOOQ手册倾向于使用一个名为create举行DSLContext.

然后,您可以使用DSLContext若要构造查询,请参见以下示例:

public List<GregorianCalendar> authorsBornAfter1980() {
	return this.create.selectFrom(AUTHOR)
		.where(AUTHOR.DATE_OF_BIRTH.greaterThan(new GregorianCalendar(1980, 0, 1)))
		.fetch(AUTHOR.DATE_OF_BIRTH);
}

29.6.3 jOOQ SQL方言

除非spring.jooq.sql-dialect属性,Spring Boot将确定要用于数据源的SQL方言。如果SpringBoot无法检测到方言,它将使用DEFAULT.

[Note]

SpringBoot只能自动配置jOOQ开源版本支持的方言。

29.6.4定制jOOQ

可以通过定义自己的自定义来实现更高级的自定义。@Bean定义,当jOOQ使用时使用Configuration是被创造出来的。可以为以下jOOQ类型定义bean:

  • ConnectionProvider
  • ExecutorProvider
  • TransactionProvider
  • RecordMapperProvider
  • RecordUnmapperProvider
  • RecordListenerProvider
  • ExecuteListenerProvider
  • VisitListenerProvider
  • TransactionListenerProvider

您也可以创建自己的org.jooq.Configuration @Bean如果您想完全控制jOOQ配置。

三十使用NoSQL技术

Spring数据提供了帮助您访问各种NoSQL技术的其他项目,包括:MongoDBNeo4J弹性搜索索尔雷迪斯双子火卡桑德拉CouchbaseLDAP。SpringBoot为Redis、MongoDB、Neo4j、Elasticsearch、Solr Cassandra、Couchbase和LDAP提供了自动配置。您可以使用其他项目,但您必须自己配置它们。请参阅适当的参考文件projects.spring.io/spring-data.

30.1 Redis

雷迪斯是一个缓存、消息代理和功能丰富的键值存储。Spring Boot为生菜吉迪斯客户端库及其之上的抽象春季数据红宝石.

有一个spring-boot-starter-data-redis用于以方便的方式收集依赖项的“初学者”。默认情况下,它使用生菜。该启动器同时处理传统应用程序和反应性应用程序。

[Tip]

我们还提供spring-boot-starter-data-redis-reactive“启动”与其他商店的一致性反应支持。

30.1.1连接到Redis

您可以注入一个自动配置的RedisConnectionFactoryStringRedisTemplate或香草RedisTemplate实例,就像其他SpringBean一样。默认情况下,实例试图连接到localhost:6379。下面的清单显示了这样一个bean的示例:

@Component
public class MyBean {

	private StringRedisTemplate template;

	@Autowired
	public MyBean(StringRedisTemplate template) {
		this.template = template;
	}

	// ...

}
[Tip]

您还可以注册任意数量的bean,这些bean实现了LettuceClientConfigurationBuilderCustomizer用于更高级的自定义。如果你用吉迪斯JedisClientConfigurationBuilderCustomizer也是可用的。

如果你加上你自己的@Bean在任何自动配置的类型中,它都将替换默认值(除非在RedisTemplate,当排除基于bean名称时,redisTemplate,而不是它的类型)。默认情况下,如果commons-pool2在类路径上,您将得到一个池连接工厂。

30.2 MongoDB

MongoDB是一个开源的NoSQL文档数据库,它使用类似JSON的模式,而不是传统的基于表的关系数据。SpringBoot为使用MongoDB提供了一些方便,包括spring-boot-starter-data-mongodbspring-boot-starter-data-mongodb-reactive“先开始”。

30.2.1连接到MongoDB数据库

要访问MONGO数据库,可以注入一个自动配置的org.springframework.data.mongodb.MongoDbFactory。默认情况下,实例尝试连接到mongodb://localhost/test下面的示例演示如何连接到MongoDB数据库:

import org.springframework.data.mongodb.MongoDbFactory;
import com.mongodb.DB;

@Component
public class MyBean {

	private final MongoDbFactory mongo;

	@Autowired
	public MyBean(MongoDbFactory mongo) {
		this.mongo = mongo;
	}

	// ...

	public void example() {
		DB db = mongo.getDb();
		// ...
	}

}

您可以设置spring.data.mongodb.uri属性更改URL并配置其他设置,如复制集,如以下示例所示:

spring.data.mongodb.uri=mongodb://user:secret@mongo1.example.com:12345,mongo2.example.com:23456/test

或者,只要使用mongo2.x,就可以指定host/port。例如,您可以在application.properties:

spring.data.mongodb.host=mongoserver
spring.data.mongodb.port=27017

如果你已经定义了你自己的MongoClient,它将用于自动配置合适的MongoDbFactory。双管齐下com.mongodb.MongoClientcom.mongodb.client.MongoClient是支持的。

[Note]

如果您使用MONGO3.0 Java驱动程序,spring.data.mongodb.hostspring.data.mongodb.port不支持。在这种情况下,spring.data.mongodb.uri应该用来提供所有的配置。

[Tip]

如果spring.data.mongodb.port未指定,则为27017被利用了。您可以从前面显示的示例中删除这一行。

[Tip]

如果不使用SpringDataMONGO,则可以插入com.mongodb.MongoClientbean而不是使用MongoDbFactory。如果要完全控制建立MongoDB连接,也可以声明自己的MongoDbFactoryMongoClient豆子

[Note]

如果您使用的是反应性驱动程序,则SSL需要Netty。如果Netty可用,并且尚未定制要使用的工厂,则自动配置将自动配置此工厂。

30.2.2蒙古板

春季数据MongoDB提供一个MongoTemplate类,它的设计与Spring的非常相似。JdbcTemplate。同.一样JdbcTemplate,SpringBoot自动配置bean以注入模板,如下所示:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

	private final MongoTemplate mongoTemplate;

	@Autowired
	public MyBean(MongoTemplate mongoTemplate) {
		this.mongoTemplate = mongoTemplate;
	}

	// ...

}

MongoOperationsJavadoc获得完整的细节。

30.2.3 Spring数据MongoDB存储库

Spring数据包括对MongoDB的存储库支持。与前面讨论的JPA存储库一样,基本原则是根据方法名称自动构造查询。

实际上,SpringDataJPA和SpringDataMongoDB共享相同的公共基础设施。您可以从前面的JPA示例开始,假设City现在是MONGO数据类,而不是JPA。@Entity,它以同样的方式工作,如下面的示例所示:

package com.example.myapp.domain;

import org.springframework.data.domain.*;
import org.springframework.data.repository.*;

public interface CityRepository extends Repository<City, Long> {

	Page<City> findAll(Pageable pageable);

	City findByNameAndStateAllIgnoringCase(String name, String state);

}
[Tip]

控件可以自定义文档扫描位置。@EntityScan注释

[Tip]

有关SpringDataMongoDB(包括其富对象映射技术)的详细信息,请参阅参考文献.

30.2.4嵌入式MONGO

Spring Boot为嵌入式蒙戈。若要在SpringBoot应用程序中使用它,请在de.flapdoodle.embed:de.flapdoodle.embed.mongo.

可以通过设置spring.data.mongodb.port财产。若要使用随机分配的空闲端口,请使用值0。这,这个,那,那个MongoClientMongoAutoConfiguration自动配置为使用随机分配的端口。

[Note]

如果不配置自定义端口,默认情况下,嵌入式支持将使用随机端口(而不是27017)。

如果类路径上有SLF4J,则MONGO产生的输出将自动路由到名为org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongo.

你可以宣布你自己的IMongodConfigIRuntimeConfigbean来控制MONGO实例的配置和日志路由。

30.3 Neo4j

Neo4j是一个开源的NoSQL图形数据库,它使用由一级关系连接的节点的丰富数据模型,比传统的RDBMS方法更适合连接大数据。SpringBoot为使用Neo4j提供了一些方便,包括spring-boot-starter-data-neo4j“初学者”。

30.3.1连接到Neo4j数据库

要访问neo4j服务器,可以注入一个自动配置的org.neo4j.ogm.session.Session。默认情况下,实例尝试连接到localhost:7687使用博尔特协议。下面的示例演示如何注入Neo4jSession:

@Component
public class MyBean {

	private final Session session;

	@Autowired
	public MyBean(Session session) {
		this.session = session;
	}

	// ...

}

可以通过设置spring.data.neo4j.*属性,如以下示例所示:

spring.data.neo4j.uri=bolt://my-server:7687
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=secret

可以通过添加org.neo4j.ogm.config.Configuration @Bean。同时,添加一个@Bean类型SessionFactory禁用自动配置,并给予您完全控制。

30.3.2使用嵌入式模式

如果你加上org.neo4j:neo4j-ogm-embedded-driver对于应用程序的依赖项,SpringBoot会自动配置一个在进程内嵌入的Neo4j实例,该实例在应用程序关闭时不会持久化任何数据。

[Note]

由于嵌入的Neo4jOGM驱动程序不提供Neo4j内核本身,所以必须声明org.neo4j:neo4j作为你自己的依赖性。请参阅Neo4j OGM文档有关兼容版本的列表。

当类路径上有多个驱动程序时,嵌入式驱动程序优先于其他驱动程序。通过设置,可以显式禁用嵌入模式。spring.data.neo4j.embedded.enabled=false.

数据Neo4j试验如果嵌入式驱动程序和Neo4j内核位于上述类路径上,则自动使用嵌入式Neo4j实例。

[Note]

您可以通过为配置中的数据库文件提供路径来启用嵌入式模式的持久性。spring.data.neo4j.uri=file://var/tmp/graph.db.

30.3.3 Neo4jSession

默认情况下,如果您正在运行Web应用程序,会话将绑定到请求的整个处理过程中的线程(也就是说,它使用“OpenSession in View”模式)。如果不想要这种行为,请将以下行添加到application.properties档案:

spring.data.neo4j.open-in-view=false

30.3.4 Spring数据Neo4j存储库

Spring数据包括对Neo4j的存储库支持。

与许多其他Spring数据模块一样,SpringDataNeo4j与SpringDataJPA共享公共基础设施。您可以从前面的JPA示例开始,并定义City作为Neo4j OGM@NodeEntity而不是JPA@Entity存储库抽象以同样的方式工作,如下面的示例所示:

package com.example.myapp.domain;

import java.util.Optional;

import org.springframework.data.neo4j.repository.*;

public interface CityRepository extends Neo4jRepository<City, Long> {

	Optional<City> findOneByNameAndState(String name, String state);

}

这,这个,那,那个spring-boot-starter-data-neo4j“初学者”启用了存储库支持和事务管理。可以自定义查找存储库和实体的位置,方法是@EnableNeo4jRepositories@EntityScan分别在@Configuration-豆子

[Tip]

有关SpringDataNeo4j(包括其对象映射技术)的详细信息,请参阅参考文献.

30.4双子火

弹簧数据Gemfire提供方便的Spring友好工具来访问枢轴双子火数据管理平台。有一个spring-boot-starter-data-gemfire用于以方便的方式收集依赖项的“初学者”。Gemfire目前不支持自动配置,但是可以使用单一注释:@EnableGemfireRepositories.

30.5 Solr

阿帕奇索尔是搜索引擎。Spring Boot为Solr 5客户端库提供了基本的自动配置,并且它之上的抽象由弹簧数据Solr。有一个spring-boot-starter-data-solr用于以方便的方式收集依赖项的“初学者”。

30.5.1连接到Solr

您可以注入一个自动配置的SolrClient实例,就像其他Springbean一样。默认情况下,实例尝试连接到localhost:8983/solr。下面的示例演示如何注入Solrbean:

@Component
public class MyBean {

	private SolrClient solr;

	@Autowired
	public MyBean(SolrClient solr) {
		this.solr = solr;
	}

	// ...

}

如果你加上你自己的@Bean类型SolrClient,它将替换默认值。

30.5.2 Spring数据Solr存储库

Spring数据包括对ApacheSolr的存储库支持。与前面讨论的JPA存储库一样,基本原则是根据方法名称自动为\You构造查询。

实际上,SpringDataJPA和SpringDataSolr共享相同的公共基础设施。您可以从前面的JPA示例开始,假设City现在是@SolrDocument类而不是JPA@Entity,以同样的方式工作。

[Tip]

有关SpringDataSolr的详细信息,请参阅参考文献.

30.6弹性搜索

弹性搜索是一个开源、分布式、RESTful的搜索和分析引擎。SpringBoot为弹力搜索提供了基本的自动配置。

SpringBoot支持几个HTTP客户端:

  • 正式的Java“低级”和“高级”REST客户端
  • 玩笑

传输客户端仍由弹簧数据弹性搜索,您可以开始使用spring-boot-starter-data-elasticsearch“初学者”。

30.6.1通过REST客户端连接到弹性搜索

ElasticSearch船两个不同的REST客户端您可以用来查询集群:“低级”客户端和“高级”客户端。

如果你有org.elasticsearch.client:elasticsearch-rest-client依赖于类路径,SpringBoot将自动配置和注册RestClientbean,在默认情况下是目标。localhost:9200。你可以进一步调整RestClient配置,如以下示例所示:

spring.elasticsearch.rest.uris=http://search.example.com:9200
spring.elasticsearch.rest.username=user
spring.elasticsearch.rest.password=secret

您还可以注册任意数量的bean,这些bean实现了RestClientBuilderCustomizer用于更高级的自定义。若要完全控制注册,请定义RestClient豆子

如果你有org.elasticsearch.client:elasticsearch-rest-high-level-client依赖于类路径,SpringBoot将自动配置RestHighLevelClient,它封装了任何现有的RestClientbean,重用它的HTTP配置。

30.6.2使用JEST连接到弹性搜索

如果你有Jest在类路径上,您可以注入一个自动配置的JestClient默认目标localhost:9200。您可以进一步优化客户端的配置方式,如以下示例所示:

spring.elasticsearch.jest.uris=http://search.example.com:9200
spring.elasticsearch.jest.read-timeout=10000
spring.elasticsearch.jest.username=user
spring.elasticsearch.jest.password=secret

您还可以注册任意数量的bean,这些bean实现了HttpClientConfigBuilderCustomizer用于更高级的自定义。下面的示例优化其他HTTP设置:

static class HttpSettingsCustomizer implements HttpClientConfigBuilderCustomizer {

	@Override
	public void customize(HttpClientConfig.Builder builder) {
		builder.maxTotalConnection(100).defaultMaxTotalConnectionPerRoute(5);
	}

}

若要完全控制注册,请定义JestClient豆子

30.6.3使用Spring数据连接弹性搜索

要连接到Elasticearch,必须提供一个或多个群集节点的地址。可以通过设置spring.data.elasticsearch.cluster-nodes属性以逗号分隔。host:port名单。配置就位后,ElasticsearchTemplateTransportClient可以像任何其他Springbean一样注入,如下面的示例所示:

spring.data.elasticsearch.cluster-nodes=localhost:9300
@Component
public class MyBean {

	private final ElasticsearchTemplate template;

	public MyBean(ElasticsearchTemplate template) {
		this.template = template;
	}

	// ...

}

如果你加上你自己的ElasticsearchTemplateTransportClient @Bean,它将替换默认值。

30.6.4 Spring数据弹性搜索库

Spring数据包括对Elasticearch的存储库支持。与前面讨论的JPA存储库一样,基本原则是根据方法名称自动为您构造查询。

实际上,SpringDataJPA和SpringDataElasticearch共享相同的公共基础设施。您可以从前面的JPA示例开始,假设City现在是一个弹性搜索@Document类而不是JPA@Entity,以同样的方式工作。

[Tip]

有关Spring数据弹性搜索的详细信息,请参阅参考文献.

30.7卡桑德拉

卡桑德拉是一个开放源码的分布式数据库管理系统,旨在处理跨越许多商品服务器的大量数据。Spring Boot为Cassandra提供了自动配置,并在此基础上提供了春季数据卡桑德拉。有一个spring-boot-starter-data-cassandra用于以方便的方式收集依赖项的“初学者”。

30.7.1连接卡桑德拉

您可以注入一个自动配置的CassandraTemplate或者卡桑德拉Session实例,就像对任何其他SpringBean一样。这,这个,那,那个spring.data.cassandra.*属性可用于自定义连接。一般来说,你提供keyspace-namecontact-points属性,如以下示例所示:

spring.data.cassandra.keyspace-name=mykeyspace
spring.data.cassandra.contact-points=cassandrahost1,cassandrahost2

下面的代码清单显示了如何注入Cassandrabean:

@Component
public class MyBean {

	private CassandraTemplate template;

	@Autowired
	public MyBean(CassandraTemplate template) {
		this.template = template;
	}

	// ...

}

如果你加上你自己的@Bean类型CassandraTemplate,它将替换默认值。

30.7.2 Spring数据库

Spring数据包括对Cassandra的基本存储库支持。目前,这比前面讨论的JPA存储库更有限,需要用@Query.

[Tip]

有关SpringDataCassandra的详细信息,请参阅参考文献.

30.8 Couchbase

Couchbase是一个开源的、分布式的、面向多模型的面向NoSQL文档的数据库,它是为交互式应用程序优化的.Spring Boot为Couchbase提供了自动配置,并且它之上的抽象由弹簧数据库。确实有。spring-boot-starter-data-couchbasespring-boot-starter-data-couchbase-reactive用于以方便的方式收集依赖项的“启动器”。

30.8.1连接到Couchbase

你可以得到一个BucketCluster通过添加Couchbase SDK和一些配置。这,这个,那,那个spring.couchbase.*属性可用于自定义连接。通常,您提供引导主机、桶名和密码,如下面的示例所示:

spring.couchbase.bootstrap-hosts=my-host-1,192.168.1.123
spring.couchbase.bucket.name=my-bucket
spring.couchbase.bucket.password=secret
[Tip]

你需要提供至少引导主机,在这种情况下,桶名是default密码是空字符串。或者,您可以定义自己的org.springframework.data.couchbase.config.CouchbaseConfigurer @Bean来控制整个配置。

还可以自定义一些CouchbaseEnvironment设置。例如,以下配置将超时更改为打开新的Bucket并启用SSL支持:

spring.couchbase.env.timeouts.connect=3000
spring.couchbase.env.ssl.key-store=/location/of/keystore.jks
spring.couchbase.env.ssl.key-store-password=secret

检查spring.couchbase.env.*属性获取更多详细信息。

30.8.2 Spring数据库

Spring数据包括对Couchbase的存储库支持。有关SpringDataCouchbase的详细信息,请参阅参考文献.

您可以注入一个自动配置的CouchbaseTemplate实例,与任何其他SpringBean一样,提供了一个违约 CouchbaseConfigurer是可用的(正如前面所解释的,启用Couchbase支持时会发生这种情况)。

下面的示例演示如何注入Couchbase bean:

@Component
public class MyBean {

	private final CouchbaseTemplate template;

	@Autowired
	public MyBean(CouchbaseTemplate template) {
		this.template = template;
	}

	// ...

}

您可以在自己的配置中定义几个bean来覆盖自动配置提供的bean:

  • CouchbaseTemplate @Bean名为couchbaseTemplate.
  • IndexManager @Bean名为couchbaseIndexManager.
  • CustomConversions @Bean名为couchbaseCustomConversions.

为了避免在您自己的配置中对这些名称进行硬编码,您可以重用这些名称。BeanNames由SpringDataCouchbase提供。例如,您可以自定义要使用的转换器,如下所示:

@Configuration
public class SomeConfiguration {

	@Bean(BeanNames.COUCHBASE_CUSTOM_CONVERSIONS)
	public CustomConversions myCustomConversions() {
		return new CustomConversions(...);
	}

	// ...

}
[Tip]

如果您希望完全绕过SpringDataCouchbase的自动配置,请提供您自己的实现org.springframework.data.couchbase.config.AbstractCouchbaseDataConfiguration.

30.9 LDAP

LDAP(轻量级目录访问协议)是一种开放的、与供应商无关的、行业标准的应用程序协议,用于通过IP网络访问和维护分布式目录信息服务。Spring Boot为任何兼容的ldap服务器提供自动配置,以及对内存中嵌入式ldap服务器的支持。无边.

LDAP抽象由春季数据LDAP。有一个spring-boot-starter-data-ldap用于以方便的方式收集依赖项的“初学者”。

30.9.1连接到LDAP服务器

若要连接到LDAP服务器,请确保在spring-boot-starter-data-ldap“起始”或spring-ldap-core然后在applicy.properties中声明服务器的URL,如下面的示例所示:

spring.ldap.urls=ldap://myserver:1235
spring.ldap.username=admin
spring.ldap.password=secret

如果需要自定义连接设置,可以使用spring.ldap.basespring.ldap.base-environment财产。

LdapContextSource是基于这些设置自动配置的。如果您需要自定义它,例如使用PooledContextSource,您仍然可以注入自动配置的LdapContextSource。确保标记您的定制ContextSource@Primary以便自动配置LdapTemplate用它。

30.9.2 Spring数据LDAP存储库

Spring数据包括对LDAP的存储库支持。有关SpringDataLDAP的详细信息,请参阅参考文献.

您还可以注入一个自动配置的LdapTemplate实例,与任何其他SpringBean一样,如下面的示例所示:

@Component
public class MyBean {

	private final LdapTemplate template;

	@Autowired
	public MyBean(LdapTemplate template) {
		this.template = template;
	}

	// ...

}

30.9.3嵌入式内存LDAP服务器

出于测试目的,SpringBoot支持自动配置内存中的ldap服务器。无边。若要配置服务器,请将依赖项添加到com.unboundid:unboundid-ldapsdk并声明base-dn财产如下:

spring.ldap.embedded.base-dn=dc=spring,dc=io
[Note]

可以定义多个基DN值,但是,由于可分辨名称通常包含逗号,因此必须使用正确的表示法来定义它们。

在YAML文件中,可以使用YAML列表符号:

spring.ldap.embedded.base-dn:
  - dc=spring,dc=io
  - dc=pivotal,dc=io

在属性文件中,必须将索引作为属性名称的一部分:

spring.ldap.embedded.base-dn[0]=dc=spring,dc=io
spring.ldap.embedded.base-dn[1]=dc=pivotal,dc=io

默认情况下,服务器在随机端口上启动并触发常规LDAP支持。不需要指定spring.ldap.urls财产。

如果有一个schema.ldif文件在您的类路径上,它用于初始化服务器。如果要从其他资源加载初始化脚本,也可以使用spring.ldap.embedded.ldif财产。

默认情况下,标准模式用于验证LDIF档案。通过设置spring.ldap.embedded.validation.enabled财产。如果您有自定义属性,则可以使用spring.ldap.embedded.validation.schema若要定义自定义属性类型或对象类,请执行以下操作。

30.10 InfluxDB

InfluxDB它是一个开放源码的时间序列数据库,用于快速、高可用性地存储和检索诸如操作监视、应用度量、物联网传感器数据和实时分析等领域的时间序列数据。

30.10.1连接到InfluxDB

Spring Boot自动配置InfluxDB实例,只要influxdb-java客户端位于类路径上,并且设置了数据库的URL,如下面的示例所示:

spring.influx.url=http://172.0.0.1:8086

如果连接到InFluxDB需要用户和密码,则可以将spring.influx.userspring.influx.password相应的属性。

InfluxDB依赖于OkHttp。如果您需要调优http客户端InfluxDB在幕后使用,您可以注册OkHttpClient.Builder豆子

31.缓存

SpringFramework支持透明地向应用程序添加缓存。在其核心,抽象将缓存应用于方法,从而减少了基于缓存中可用信息的执行次数。缓存逻辑是透明地应用的,对调用方没有任何干扰。Spring Boot自动配置缓存基础结构,只要通过@EnableCaching注释

[Note]

检查相关部分更多细节,请参考Spring框架。

简而言之,向服务的操作添加缓存就像将相关注释添加到其方法中一样简单,如下面的示例所示:

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

@Component
public class MathService {

	@Cacheable("piDecimals")
	public int computePiDecimal(int i) {
		// ...
	}

}

此示例演示如何在可能代价高昂的操作上使用缓存。在调用computePiDecimal,抽象将在piDecimals匹配i争论。如果找到一个条目,缓存中的内容将立即返回给调用方,并且不会调用该方法。否则,将调用该方法,并在返回值之前更新缓存。

[Caution]谨慎

您还可以使用标准的jsr-107(Jcache)注释(如@CacheResult)透明的。但是,我们强烈建议您不要混合和匹配SpringCache和JCache注释。

如果没有添加任何特定的缓存库,则SpringBoot自动配置简单提供者它使用内存中的并发映射。当需要缓存时(如piDecimals),此提供程序将为您创建该提供程序。简单的提供程序并不是真正推荐用于生产使用的,但是它对于开始使用和确保您理解这些特性是很好的。当您决定使用缓存提供程序时,请确保阅读其文档,以了解如何配置应用程序使用的缓存。几乎所有提供程序都要求您显式地配置在应用程序中使用的每个缓存。有些提供了一种自定义由spring.cache.cache-names财产。

[Tip]

透明也是可能的。更新驱逐缓存中的数据。

31.1支持缓存提供者

缓存抽象没有提供实际的存储,而是依赖于由org.springframework.cache.Cacheorg.springframework.cache.CacheManager接口。

如果尚未定义类型的beanCacheManager或者是CacheResolver命名cacheResolver(见CachingConfigurer),SpringBoot尝试检测以下提供程序(按指定的顺序):

  1. 属属
  2. JCache(JSR-107)(EhCache 3、Hazelcast、Infinisan等)
  3. EhCache 2.x
  4. 哈泽尔卡斯特
  5. 英菲尼斯潘
  6. Couchbase
  7. 雷迪斯
  8. 咖啡因
  9. 简约
[Tip]

也有可能设置spring.cache.type财产。如果需要使用此属性完全禁用缓存在某些环境中(如测试)。

[Tip]

使用spring-boot-starter-cache快速添加基本缓存依赖项的“初学者”。起动器来了spring-context-support。如果手动添加依赖项,则必须包括spring-context-support为了使用JCache、EhCache 2.x或Guava支持。

如果CacheManager是由SpringBoot自动配置的,您可以在它完全初始化之前进一步调优它的配置,方法是公开一个实现CacheManagerCustomizer接口。下面的示例设置一个标志,表示应该将空值传递给基础映射:

@Bean
public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() {
	return new CacheManagerCustomizer<ConcurrentMapCacheManager>() {
		@Override
		public void customize(ConcurrentMapCacheManager cacheManager) {
			cacheManager.setAllowNullValues(false);
		}
	};
}
[Note]

在前面的示例中,自动配置ConcurrentMapCacheManager都是意料之中的。如果情况并非如此(您提供了您自己的配置,或者一个不同的缓存提供程序是自动配置的),则根本不调用自定义程序。您可以拥有任意数量的自定义器,也可以通过使用@OrderOrdered.

31.1.1通用

如果上下文定义至少org.springframework.cache.Cache豆子一个CacheManager将创建该类型的所有bean。

31.1.2 JCache(JSR-107)

JCache通过存在的javax.cache.spi.CachingProvider在类路径(即,与JSR-107兼容的缓存库存在于类路径上)上,JCacheCacheManagerspring-boot-starter-cache“初学者”。有各种兼容的库,SpringBoot为Ehcache 3、Hazelcast和InfinisPAN提供了依赖关系管理。任何其他兼容的库也可以添加。

可能存在多个提供程序,在这种情况下,必须显式指定提供程序。即使JSR-107标准没有强制执行一种标准的方法来定义配置文件的位置,SpringBoot也会尽最大努力适应设置带有实现细节的缓存,如下面的示例所示:

   # Only necessary if more than one provider is present
spring.cache.jcache.provider=com.acme.MyCachingProvider
spring.cache.jcache.config=classpath:acme.xml
[Note]

当缓存库同时提供本机实现和JSR-107支持时,SpringBoot更喜欢JSR-107支持,因此如果切换到不同的JSR-107实现,也可以使用相同的特性。

[Tip]

春靴对Hazelcast的一般支持。如果一个人HazelcastInstance,则它将自动重用为CacheManager也是,除非spring.cache.jcache.config属性。

有两种方法可以自定义基础javax.cache.cacheManager:

  • 可以在启动时通过设置spring.cache.cache-names财产。如果一个习俗javax.cache.configuration.Configurationbean是定义的,它用于自定义它们。
  • org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer类的引用调用bean。CacheManager完全定制。
[Tip]

如果一个标准javax.cache.CacheManagerbean是定义的,它将自动包装在org.springframework.cache.CacheManager抽象所期望的实现。没有对其应用进一步的自定义。

31.1.3 EhCache 2.x

EhCache如果一个名为ehcache.xml可以在类路径的根部找到。如果找到EhCache 2.x,则EhCacheCacheManagerspring-boot-starter-cache“初学者”用于引导缓存管理器。还可以提供另一个配置文件,如以下示例所示:

spring.cache.ehcache.config=classpath:config/another-config.xml

31.1.4哈泽尔广播公司

春靴对Hazelcast的一般支持。如果HazelcastInstance已自动配置,它将自动包装在CacheManager.

31.1.5无限

英菲尼斯潘没有默认配置文件位置,因此必须显式指定。否则,将使用默认引导程序。

spring.cache.infinispan.config=infinispan.xml

可以在启动时通过设置spring.cache.cache-names财产。如果一个习俗ConfigurationBuilderbean是定义的,它用于自定义缓存。

[Note]

InfinisPAN在SpringBoot中的支持仅限于嵌入式模式,是相当基础的。如果您想要更多的选项,您应该使用正式的InfinispanSpringBootStart。看见英菲尼斯潘文件更多细节。

31.1.6 Couchbase

如果CouchbaseJava客户端和couchbase-spring-cache实现是可用的,Couchbase是配置..CouchbaseCacheManager是自动配置的。还可以在启动时通过设置spring.cache.cache-names财产。这些缓存在Bucket那是自动配置的。你可以的。在另一个上创建额外的缓存Bucket通过使用自定义程序。假设您需要两个缓存(cache1cache2)关于“主要”Bucket还有一个(cache3)具有自定义时间的缓存,在“另一个”上生存2秒。Bucket。您可以通过配置创建前两个缓存,如下所示:

spring.cache.cache-names=cache1,cache2

然后,您可以定义@Configuration类来配置额外的Bucketcache3缓存如下:

@Configuration
public class CouchbaseCacheConfiguration {

	private final Cluster cluster;

	public CouchbaseCacheConfiguration(Cluster cluster) {
		this.cluster = cluster;
	}

	@Bean
	public Bucket anotherBucket() {
		return this.cluster.openBucket("another", "secret");
	}

	@Bean
	public CacheManagerCustomizer<CouchbaseCacheManager> cacheManagerCustomizer() {
		return c -> {
			c.prepareCache("cache3", CacheBuilder.newInstance(anotherBucket())
					.withExpiration(2));
		};
	}

}

此示例配置重用Cluster这是通过自动配置创建的。

31.1.7 Redis

如果雷迪斯是否可用并配置,则RedisCacheManager是自动配置的。在启动时可以通过设置spring.cache.cache-names属性和缓存默认值可以通过使用spring.cache.redis.*财产。例如,下面的配置创建cache1cache2缓存活下去的时间10分钟:

spring.cache.cache-names=cache1,cache2
spring.cache.redis.time-to-live=600000
[Note]

默认情况下,会添加一个键前缀,这样,如果两个单独的缓存使用相同的键,Redis就不会有重叠的键,并且不能返回无效的值。如果您创建自己的设置,我们强烈建议将此设置保持为启用状态。RedisCacheManager.

[Tip]

可以通过添加RedisCacheConfiguration @Bean你自己的。如果您想要自定义序列化策略,这可能很有用。

31.1.8咖啡因

咖啡因Java 8重写了番石榴的缓存,取代了对番石榴的支持。如果咖啡因存在,CaffeineCacheManager(由spring-boot-starter-cache是自动配置的。可以在启动时通过设置spring.cache.cache-names属性,并且可以通过以下之一进行自定义(按指定的顺序):

  1. spring.cache.caffeine.spec
  2. com.github.benmanes.caffeine.cache.CaffeineSpecbean被定义为
  3. com.github.benmanes.caffeine.cache.Caffeinebean被定义为

例如,下面的配置创建cache1cache2缓存的最大大小为500,并且活下去的时间10分钟

spring.cache.cache-names=cache1,cache2
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s

如果com.github.benmanes.caffeine.cache.CacheLoaderbean被定义,它将自动关联到CaffeineCacheManager。因为CacheLoader将与缓存管理器管理的缓存,它必须定义为CacheLoader<Object, Object>。自动配置忽略任何其他泛型类型.

31.1.9简单

如果找不到其他提供程序,则使用ConcurrentHashMap在配置缓存存储时。如果应用程序中没有缓存库,这是默认的。默认情况下,缓存是根据需要创建的,但可以通过设置cache-names财产。例如,如果你只想cache1cache2缓存,设置cache-names财产如下:

spring.cache.cache-names=cache1,cache2

如果这样做,并且应用程序使用未列出的缓存,那么当需要缓存时,它会在运行时失败,而不是在启动时失败。如果使用未声明的缓存,这与“真实”缓存提供程序的行为方式类似。

31.1.10无

什么时候@EnableCaching在您的配置中,还需要一个合适的缓存配置。如果需要在某些环境中完全禁用缓存,请强制缓存类型为none若要使用NO-OP实现,请参见以下示例:

spring.cache.type=none

三十二信息传递

Spring框架为与消息传递系统集成提供了广泛的支持,简化了JMSAPI的使用JmsTemplate异步接收消息的完整基础结构。SpringAMQP为高级消息队列协议提供了类似的功能集。Spring Boot还提供了自动配置选项。RabbitTemplate还有拉比·MQ。SpringWebSocket内置了对STOMP消息传递的支持,SpringBoot通过启动器和少量的自动配置对此提供了支持。SpringBoot还支持ApacheKafka。

32.1 JMS

这,这个,那,那个javax.jms.ConnectionFactory接口提供了创建javax.jms.Connection用于与JMS代理交互。尽管春天需要一个ConnectionFactory要使用JMS,通常不需要自己直接使用它,而是可以依赖更高级别的消息抽象。(见相关部分)的详细信息。)SpringBoot还自动配置发送和接收消息所需的基础设施。

32.1.1 ActiveMQ支持

什么时候ActiveMQ在类路径上可用,SpringBoot也可以配置ConnectionFactory。如果存在代理,则会自动启动和配置嵌入式代理(前提是没有通过配置指定代理URL)。

[Note]

如果你用spring-boot-starter-activemq,提供了连接或嵌入ActiveMQ实例所需的依赖关系,与JMS集成的Spring基础结构也是如此。

中的外部配置属性控制ActiveMQ配置。spring.activemq.*。例如,您可以在application.properties:

spring.activemq.broker-url=tcp://192.168.1.210:9876
spring.activemq.user=admin
spring.activemq.password=secret

默认情况下,CachingConnectionFactory包裹本地人ConnectionFactory中的可由外部配置属性控制的合理设置。spring.jms.*:

spring.jms.cache.session-cache-size=5

如果您希望使用本机池,可以通过向org.messaginghub:pooled-jms和配置JmsPoolConnectionFactory因此,如以下示例所示:

spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=50
[Tip]

看见ActiveMQProperties有关更多受支持的选项。您还可以注册任意数量的bean,这些bean实现了ActiveMQConnectionFactoryCustomizer用于更高级的自定义。

默认情况下,如果还不存在ActiveMQ,则ActiveMQ将创建一个目的地,以便根据其提供的名称解析目的地。

32.1.2 Artemis支持

Spring Boot可以自动配置ConnectionFactory当它发现阿耳特米斯在类路径上可用。如果存在代理,则会自动启动和配置嵌入式代理(除非模式属性已显式设置)。支持的模式如下embedded(明确表示需要嵌入代理,如果类路径上无法使用代理,则应发生错误)native(使用netty运输协议)。配置后者时,SpringBoot将配置ConnectionFactory它连接到具有默认设置的本地计算机上运行的代理。

[Note]

如果你用spring-boot-starter-artemis,提供了连接到现有Artemis实例所需的依赖项,以及与JMS集成的Spring基础结构。加法org.apache.activemq:artemis-jms-server对您的应用程序允许您使用嵌入式模式。

中的外部配置属性控制artemis配置。spring.artemis.*。例如,您可以在application.properties:

spring.artemis.mode=native
spring.artemis.host=192.168.1.210
spring.artemis.port=9876
spring.artemis.user=admin
spring.artemis.password=secret

嵌入代理时,您可以选择是否要启用持久性,并列出应该可用的目的地。可以将它们指定为逗号分隔的列表,以便使用默认选项创建它们,或者可以定义类型的bean(S)。org.apache.activemq.artemis.jms.server.config.JMSQueueConfigurationorg.apache.activemq.artemis.jms.server.config.TopicConfiguration,分别用于高级队列和主题配置。

默认情况下,CachingConnectionFactory包裹本地人ConnectionFactory中的可由外部配置属性控制的合理设置。spring.jms.*:

spring.jms.cache.session-cache-size=5

如果您希望使用本机池,可以通过向org.messaginghub:pooled-jms和配置JmsPoolConnectionFactory因此,如以下示例所示:

spring.artemis.pool.enabled=true
spring.artemis.pool.max-connections=50

看见ArtemisProperties获得更多支持的选项。

不涉及JNDI查找,目的地将根据其名称进行解析,使用name属性在Artemis配置中或通过配置提供的名称中。

32.1.3使用JNDI连接工厂

如果在应用程序服务器中运行应用程序,SpringBoot尝试定位JMSConnectionFactory通过使用JNDI。默认情况下,java:/JmsXAjava:/XAConnectionFactory检查位置。您可以使用spring.jms.jndi-name如果需要指定替代位置,请创建以下示例:

spring.jms.jndi-name=java:/MyConnectionFactory

32.1.4发送消息

春天的JmsTemplate是自动配置的,您可以直接将它自动放入自己的bean中,如下面的示例所示:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

	private final JmsTemplate jmsTemplate;

	@Autowired
	public MyBean(JmsTemplate jmsTemplate) {
		this.jmsTemplate = jmsTemplate;
	}

	// ...

}
[Note]

JmsMessagingTemplate可以类似的方式注射。如果DestinationResolver或者是MessageConverterbean被定义,它将自动与自动配置的bean相关联。JmsTemplate.

32.1.5接收消息

当JMS基础设施存在时,任何bean都可以用@JmsListener若要创建侦听器端点,请执行以下操作。如果没有JmsListenerContainerFactory已定义了默认配置,则会自动配置默认配置。如果DestinationResolver或者是MessageConverterbean是定义的,它会自动与默认工厂相关联。

默认情况下,默认工厂是事务性的。如果您在一个基础设施中运行,其中JtaTransactionManager默认情况下,它与侦听器容器相关联。如果没有,则sessionTransacted已启用标志。在后一种情况下,可以通过添加以下方法将本地数据存储事务与传入消息的处理相关联@Transactional在侦听器方法(或其委托)上。这确保本地事务完成后确认传入消息。这还包括发送在同一JMS会话上执行的响应消息。

下面的组件在someQueue目的地:

@Component
public class MyBean {

	@JmsListener(destination = "someQueue")
	public void processMessage(String content) {
		// ...
	}

}
[Tip]

看见.的Javadoc@EnableJms更多细节。

如果您需要创建更多JmsListenerContainerFactory实例,或者如果要覆盖默认值,SpringBoot将提供一个DefaultJmsListenerContainerFactoryConfigurer可以用来初始化DefaultJmsListenerContainerFactory具有与自动配置的设置相同的设置。

例如,下面的示例公开另一个使用特定MessageConverter:

@Configuration
static class JmsConfiguration {

	@Bean
	public DefaultJmsListenerContainerFactory myFactory(
			DefaultJmsListenerContainerFactoryConfigurer configurer) {
		DefaultJmsListenerContainerFactory factory =
				new DefaultJmsListenerContainerFactory();
		configurer.configure(factory, connectionFactory());
		factory.setMessageConverter(myMessageConverter());
		return factory;
	}

}

那么你可以在任何地方使用这个工厂。@JmsListener-附加说明的方法如下:

@Component
public class MyBean {

	@JmsListener(destination = "someQueue", containerFactory="myFactory")
	public void processMessage(String content) {
		// ...
	}

}

32.2 AMQP

高级消息队列协议(AMQP)是一种面向消息中间件的平台中立、线级协议.SpringAMQP项目将核心Spring概念应用于基于AMQP的消息传递解决方案的开发。SpringBoot为通过RabbitMQ使用AMQP提供了一些方便,包括spring-boot-starter-amqp“初学者”。

32.2.1兔MQ支持

兔MQ是基于AMQP协议的轻量级、可靠、可伸缩和可移植的消息代理。弹簧使用RabbitMQ通过AMQP协议进行通信。

中的外部配置属性控制RabbitMQ配置。spring.rabbitmq.*。例如,您可以在application.properties:

spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=secret

如果ConnectionNameStrategybean存在于上下文中,它将自动用于命名由自动配置的连接。ConnectionFactory。看见RabbitProperties有关更多受支持的选项。

[Tip]

看见理解AMQP,RabbitMQ使用的协议更多细节。

32.2.2发送消息

春天的AmqpTemplateAmqpAdmin是自动配置的,您可以直接将它们自动放入自己的bean中,如下面的示例所示:

import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

	private final AmqpAdmin amqpAdmin;
	private final AmqpTemplate amqpTemplate;

	@Autowired
	public MyBean(AmqpAdmin amqpAdmin, AmqpTemplate amqpTemplate) {
		this.amqpAdmin = amqpAdmin;
		this.amqpTemplate = amqpTemplate;
	}

	// ...

}
[Note]

RabbitMessagingTemplate可以类似的方式注射。如果MessageConverterbean被定义,它将自动与自动配置的bean相关联。AmqpTemplate.

如有需要,任何org.springframework.amqp.core.Queue它被定义为bean自动用于在RabbitMQ实例上声明相应的队列。

若要重试操作,可以在AmqpTemplate(例如,在代理连接丢失时):

spring.rabbitmq.template.retry.enabled=true
spring.rabbitmq.template.retry.initial-interval=2s

默认情况下将禁用重试。您还可以自定义RetryTemplate以编程方式声明RabbitRetryTemplateCustomizer豆子

32.2.3接收消息

当存在兔子基础设施时,任何bean都可以用@RabbitListener若要创建侦听器端点,请执行以下操作。如果没有RabbitListenerContainerFactory已定义为默认值。SimpleRabbitListenerContainerFactory自动配置,您可以使用spring.rabbitmq.listener.type财产。如果MessageConverter或者是MessageRecovererbean是定义的,它会自动与默认工厂相关联。

下面的示例组件在someQueue排队:

@Component
public class MyBean {

	@RabbitListener(queues = "someQueue")
	public void processMessage(String content) {
		// ...
	}

}
[Tip]

看见.的Javadoc@EnableRabbit更多细节。

如果您需要创建更多RabbitListenerContainerFactory实例,或者如果要覆盖默认值,SpringBoot将提供一个SimpleRabbitListenerContainerFactoryConfigurer和一个DirectRabbitListenerContainerFactoryConfigurer可以用来初始化SimpleRabbitListenerContainerFactory和一个DirectRabbitListenerContainerFactory具有与自动配置使用的工厂相同的设置。

[Tip]

您所选择的容器类型并不重要。这两个bean由自动配置公开。

例如,下面的配置类公开了另一个使用特定MessageConverter:

@Configuration
static class RabbitConfiguration {

	@Bean
	public SimpleRabbitListenerContainerFactory myFactory(
			SimpleRabbitListenerContainerFactoryConfigurer configurer) {
		SimpleRabbitListenerContainerFactory factory =
				new SimpleRabbitListenerContainerFactory();
		configurer.configure(factory, connectionFactory);
		factory.setMessageConverter(myMessageConverter());
		return factory;
	}

}

那么你可以在任何地方使用这个工厂。@RabbitListener-附加说明的方法如下:

@Component
public class MyBean {

	@RabbitListener(queues = "someQueue", containerFactory="myFactory")
	public void processMessage(String content) {
		// ...
	}

}

您可以启用重试来处理侦听器抛出异常的情况。默认情况下,RejectAndDontRequeueRecoverer,但您可以定义MessageRecoverer你自己的。当重试用尽时,消息将被拒绝,如果代理被配置为删除或路由到死信交换。默认情况下,将禁用重试。您还可以自定义RetryTemplate以编程方式声明RabbitRetryTemplateCustomizer豆子

[Important]重要

默认情况下,如果禁用重试并引发异常,则将无限期地重新尝试传递。可以通过两种方式修改此行为:defaultRequeueRejected财产false,这样就可以尝试或抛出零次重发。AmqpRejectAndDontRequeueException若要发出信号,则应拒绝该消息。后者是在启用重试并达到最大传递尝试次数时使用的机制。

32.3 Apache Kafka支持

阿帕奇卡夫卡的自动配置支持spring-kafka项目。

中的外部配置属性控制Kafka配置。spring.kafka.*。例如,您可以在application.properties:

spring.kafka.bootstrap-servers=localhost:9092
spring.kafka.consumer.group-id=myGroup
[Tip]

若要在启动时创建主题,请添加类型为NewTopic。如果主题已经存在,则忽略bean。

看见KafkaProperties获得更多支持的选项。

32.3.1发送信息

春天的KafkaTemplate是自动配置的,您可以直接在自己的bean中自动配置它,如下面的示例所示:

@Component
public class MyBean {

	private final KafkaTemplate kafkaTemplate;

	@Autowired
	public MyBean(KafkaTemplate kafkaTemplate) {
		this.kafkaTemplate = kafkaTemplate;
	}

	// ...

}
[Note]

如果财产spring.kafka.producer.transaction-id-prefix定义,KafkaTransactionManager是自动配置的。另外,如果RecordMessageConverterbean被定义后,它将自动与自动配置的bean相关联。KafkaTemplate.

32.3.2接收消息

当apache Kafka基础设施存在时,任何bean都可以用@KafkaListener若要创建侦听器端点,请执行以下操作。如果没有KafkaListenerContainerFactory已经定义好了,默认的键将自动配置为spring.kafka.listener.*.

下面的组件在someTopic题目:

@Component
public class MyBean {

	@KafkaListener(topics = "someTopic")
	public void processMessage(String content) {
		// ...
	}

}

如果KafkaTransactionManagerbean是定义的,它自动与容器工厂相关联。类似地,如果RecordMessageConverterErrorHandlerAfterRollbackProcessorbean是定义的,它会自动与默认工厂相关联。

[Tip]

风俗ChainedKafkaTransactionManager必须标记@Primary因为它通常引用自动配置的KafkaTransactionManager豆子

32.3.3 Kafka流

SpringforApacheKafka提供了一个工厂bean来创建一个StreamsBuilder对象并管理其流的生命周期。Spring Boot自动配置所需的KafkaStreamsConfiguration豆子kafka-streams在类路径上,Kafka流通过@EnableKafkaStreams注释

启用Kafka流意味着必须设置应用程序id和引导服务器。前者可以使用spring.kafka.streams.application-id,拖欠spring.application.name如果没有设定。后者可以全局设置,也可以仅针对流进行特殊重写。

使用专用属性可以获得其他几个属性;其他任意的Kafka属性可以使用spring.kafka.streams.properties命名空间。另见第32.3.4节,“额外的Kafka属性”想了解更多信息。

要使用工厂bean,只需连接StreamsBuilder进入你的@Bean如以下示例所示:

@Configuration
@EnableKafkaStreams
static class KafkaStreamsExampleConfiguration {

	@Bean
	public KStream<Integer, String> kStream(StreamsBuilder streamsBuilder) {
		KStream<Integer, String> stream = streamsBuilder.stream("ks1In");
		stream.map((k, v) -> new KeyValue<>(k, v.toUpperCase())).to("ks1Out",
				Produced.with(Serdes.Integer(), new JsonSerde<>()));
		return stream;
	}

}

默认情况下,由StreamBuilder对象自动启动。您可以使用spring.kafka.streams.auto-startup财产。

32.3.4额外的Kafka属性

自动配置支持的属性显示在附录A,通用应用特性。注意,在大多数情况下,这些属性(连字符或CamelCase)直接映射到ApacheKafka虚线属性。有关详细信息,请参阅ApacheKafka文档。

前几个属性适用于所有组件(生产者、消费者、管理员和流),但如果您希望使用不同的值,则可以在组件级别指定。ApacheKafka指定的属性具有高、中或低的重要性。SpringBoot自动配置支持所有高重要性属性、一些选定的中、低属性以及没有默认值的任何属性。

只有一部分由Kafka支持的属性可以通过KafkaProperties班级,等级如果希望使用不直接支持的其他属性配置生产者或使用者,请使用以下属性:

spring.kafka.properties.prop.one=first
spring.kafka.admin.properties.prop.two=second
spring.kafka.consumer.properties.prop.three=third
spring.kafka.producer.properties.prop.four=fourth
spring.kafka.streams.properties.prop.five=fifth

这设置了公共prop.one卡夫卡first(适用于生产者、消费者和管理员)prop.two管理属性secondprop.three消费者财产thirdprop.four生产者财产fourthprop.five流属性fifth.

您还可以配置SpringKafkaJsonDeserializer详情如下:

spring.kafka.consumer.value-deserializer=org.springframework.kafka.support.serializer.JsonDeserializer
spring.kafka.consumer.properties.spring.json.value.default.type=com.example.Invoice
spring.kafka.consumer.properties.spring.json.trusted.packages=com.example,org.acme

类似地,您可以禁用JsonSerializer在标头中发送类型信息的默认行为:

spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer
spring.kafka.producer.properties.spring.json.add.type.headers=false
[Important]重要

以这种方式设置的属性覆盖SpringBoot显式支持的任何配置项。

33.调用REST服务RestTemplate

如果需要从应用程序调用远程REST服务,可以使用Spring框架的RestTemplate班级,等级自RestTemplate实例在使用之前通常需要进行自定义,SpringBoot不提供任何单独的自动配置。RestTemplate豆子但是,它会自动配置一个RestTemplateBuilder,可以用来创建RestTemplate需要时执行实例。自动配置RestTemplateBuilder确保明智HttpMessageConverters适用于RestTemplate实例。

下面的代码显示了一个典型的示例:

@Service
public class MyService {

	private final RestTemplate restTemplate;

	public MyService(RestTemplateBuilder restTemplateBuilder) {
		this.restTemplate = restTemplateBuilder.build();
	}

	public Details someRestCall(String name) {
		return this.restTemplate.getForObject("/{name}/details", Details.class, name);
	}

}
[Tip]

RestTemplateBuilder包含许多有用的方法,这些方法可用于快速配置RestTemplate。例如,要添加基本auth支持,可以使用builder.basicAuthorization("user", "password").build().

33.1餐厅模板定制

有三种主要的方法RestTemplate自定义,取决于您希望自定义应用的范围。

若要使任何自定义的范围尽可能窄,请插入自动配置的RestTemplateBuilder然后根据需要调用它的方法。每个方法调用返回一个新的RestTemplateBuilder实例,因此自定义只影响构建器的这种使用。

若要进行应用程序范围内的附加定制,请使用RestTemplateCustomizer豆子所有这些bean都会自动注册到自动配置的RestTemplateBuilder并应用于任何用它构建的模板。

下面的示例显示了一个自定义程序,该自定义程序配置除以下之外的所有主机的代理使用。192.168.0.5:

static class ProxyCustomizer implements RestTemplateCustomizer {

	@Override
	public void customize(RestTemplate restTemplate) {
		HttpHost proxy = new HttpHost("proxy.example.com");
		HttpClient httpClient = HttpClientBuilder.create()
				.setRoutePlanner(new DefaultProxyRoutePlanner(proxy) {

					@Override
					public HttpHost determineProxy(HttpHost target,
							HttpRequest request, HttpContext context)
							throws HttpException {
						if (target.getHostName().equals("192.168.0.5")) {
							return null;
						}
						return super.determineProxy(target, request, context);
					}

				}).build();
		restTemplate.setRequestFactory(
				new HttpComponentsClientHttpRequestFactory(httpClient));
	}

}

最后,最极端的(而且很少使用)选项是创建自己的RestTemplateBuilder豆子这样做可以关闭RestTemplateBuilder并阻止任何RestTemplateCustomizer被使用的豆子。

34.调用REST服务WebClient

如果类路径上有SpringWebFlux,也可以选择使用WebClient呼叫远程休息服务。相比较RestTemplate,这个客户有一种功能更强的感觉和完全的反应。您可以了解更多关于WebClient在奉献中Spring框架文档中的.

Spring Boot创建并预先配置WebClient.Builder对于您;强烈建议将其注入组件并使用它创建WebClient实例。SpringBoot将构建器配置为共享HTTP资源,以与服务器相同的方式反映编解码器的设置(请参见WebFlux HTTP编解码器自动配置),还有更多。

下面的代码显示了一个典型的示例:

@Service
public class MyService {

	private final WebClient webClient;

	public MyService(WebClient.Builder webClientBuilder) {
		this.webClient = webClientBuilder.baseUrl("http://example.org").build();
	}

	public Mono<Details> someRestCall(String name) {
		return this.webClient.get().uri("/{name}/details", name)
						.retrieve().bodyToMono(Details.class);
	}

}

34.1 WebClient运行时

Spring Boot将自动检测哪个ClientHttpConnector开车WebClient,取决于应用程序类路径上可用的库。

这,这个,那,那个spring-boot-starter-webflux取决于io.projectreactor.netty:reactor-netty默认情况下,这会同时带来服务器和客户端实现。如果选择使用Jetty作为反应性服务器,则应添加对JettyReactiveHTTP客户端库的依赖关系,org.eclipse.jetty:jetty-reactive-httpclient,因为它将自动与服务器共享HTTP资源。

开发人员可以通过定义自己的ClientHttpConnector在这种情况下,并且取决于您选择的HTTP客户机库,您还应该定义一个资源工厂bean来管理该客户端的HTTP资源。例如,ReactorResourceFactory用于反应堆Netty客户端。

您可以了解更多关于WebClientSpring框架参考文档中的配置选项.

34.2 Web客户端定制

有三种主要的方法WebClient自定义,取决于您希望自定义应用的范围。

若要使任何自定义的范围尽可能窄,请插入自动配置的WebClient.Builder然后根据需要调用它的方法。WebClient.Builder实例是有状态的:构建器上的任何更改都反映在随后使用它创建的所有客户端中。如果希望使用相同的构建器创建多个客户端,还可以考虑使用WebClient.Builder other = builder.clone();.

对所有用户进行应用程序范围的、附加的自定义。WebClient.Builder实例,您可以声明WebClientCustomizer和更改WebClient.Builder局部注射点。

最后,您可以回到原来的api并使用WebClient.create()。在这种情况下,没有自动配置或WebClientCustomizer被应用。

35.验证

只要JSR-303实现(例如Hibernate验证器)在类路径上,Bean Validation1.1支持的方法验证功能就会自动启用。这允许使用bean方法进行注释。javax.validation对其参数和/或其返回值的约束。具有此类注释方法的目标类需要用@Validated类型级别的注释,以便搜索它们的方法以查找内联约束注释。

例如,以下服务触发第一个参数的验证,确保其大小介于8到10之间:

@Service
@Validated
public class MyBean {

	public Archive findByCodeAndAuthor(@Size(min = 8, max = 10) String code,
			Author author) {
		...
	}

}

36.发送电子邮件

Spring框架为发送电子邮件提供了一个简单的抽象,使用JavaMailSender接口,SpringBoot提供了它的自动配置以及一个启动模块.

[Tip]

参考文献有关如何使用JavaMailSender.

如果spring.mail.host以及相关的图书馆(由spring-boot-starter-mail)是可用的,默认情况下JavaMailSender如果不存在,则创建。属性中的配置项可以进一步自定义发送方。spring.mail命名空间。看见MailProperties更多细节。

特别是,某些默认超时值是无限的,您可能希望更改此值,以避免线程被没有响应的邮件服务器阻塞,如下面的示例所示:

spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=3000
spring.mail.properties.mail.smtp.writetimeout=5000

还可以配置JavaMailSender现有的Session来自JNDI:

spring.mail.jndi-name=mail/Session

jndi-name设置后,它将优先于所有其他与会话相关的设置。

37.使用JTA的分布式事务

Spring Boot支持跨多个XA资源的分布式JTA事务,方法是使用Atomikos比特罗尼嵌入式事务管理器当部署到适当的JavaEE应用服务器时,也支持JTA事务。

当检测到JTA环境时,Spring的JtaTransactionManager用于管理事务。自动配置的JMS、DataSource和JPAbean被升级,以支持XA事务。您可以使用标准的Spring成语,例如@Transactional,以参与分布式事务。如果您位于JTA环境中,并且仍然希望使用本地事务,则可以将spring.jta.enabled财产false若要禁用JTA自动配置,请执行以下操作。

37.1使用Atomikos事务管理器

Atomikos是一个流行的开源事务管理器,可以嵌入到SpringBoot应用程序中。您可以使用spring-boot-starter-jta-atomikos启动引入适当的Atomikos库。SpringBoot自动配置Atomikos并确保depends-on将设置应用于Springbean以进行正确的启动和关闭排序。

默认情况下,Atomikos事务日志被写入transaction-logs应用程序主目录中的目录(应用程序JAR文件所在的目录)。您可以通过设置spring.jta.log-dir你的财产application.properties档案。属性以spring.jta.atomikos.properties也可用于自定义AtomikosUserTransactionServiceImp。见AtomikosPropertiesJavadoc获得完整的细节。

[Note]

为了确保多个事务管理器能够安全地协调相同的资源管理器,每个Atomikos实例必须配置一个唯一的ID。默认情况下,此ID是运行Atomikos的机器的IP地址。若要确保生产中的唯一性,应配置spring.jta.transaction-manager-id属性对应用程序的每个实例具有不同的值。

37.2使用Bitronix事务管理器

比特罗尼是一个流行的开源JTA事务管理器实现。您可以使用spring-boot-starter-jta-bitronix启动将适当的Bitronix依赖项添加到项目中。与Atomikos一样,SpringBoot会自动配置Bitronix并对bean进行后处理,以确保启动和关闭顺序是正确的。

默认情况下,Bitronix事务日志文件(part1.btmpart2.btm)写到transaction-logs应用程序主目录中的目录。属性来自定义此目录的位置。spring.jta.log-dir财产。属性以spring.jta.bitronix.properties也绑定到bitronix.tm.Configurationbean,允许完全自定义。见Bitronix文档关于细节。

[Note]

为了确保多个事务管理器能够安全地协调相同的资源管理器,每个Bitronix实例必须配置一个唯一的ID。默认情况下,此ID是运行Bitronix的机器的IP地址。若要确保生产中的唯一性,应配置spring.jta.transaction-manager-id属性对应用程序的每个实例具有不同的值。

37.3使用JavaEE托管事务管理器

如果将SpringBoot应用程序打包为warear文件并将其部署到JavaEE应用服务器上,您可以使用应用程序服务器的内置事务管理器。SpringBoot试图通过查看常见的JNDI位置来自动配置事务管理器(java:comp/UserTransactionjava:comp/TransactionManager等等)。如果使用应用服务器提供的事务服务,通常还希望确保所有资源都由服务器管理,并通过JNDI公开。Spring Boot试图通过查找ConnectionFactory在JNDI路径上(java:/JmsXAjava:/XAConnectionFactory),您可以使用spring.datasource.jndi-name财产若要配置您的DataSource.

37.4混合XA和非XA JMS连接

当使用JTA时,主JMSConnectionFactorybean是XA感知的,并参与分布式事务。在某些情况下,您可能希望使用非XA处理某些JMS消息。ConnectionFactory。例如,JMS处理逻辑可能比XA超时时间更长。

如果您想使用非XAConnectionFactory,您可以将nonXaJmsConnectionFactory而不是@Primary jmsConnectionFactory豆子为了保持一致性,jmsConnectionFactorybean还通过使用bean别名提供。xaJmsConnectionFactory.

下面的示例演示如何注入ConnectionFactory实例:

// Inject the primary (XA aware) ConnectionFactory
@Autowired
private ConnectionFactory defaultConnectionFactory;

// Inject the XA aware ConnectionFactory (uses the alias and injects the same as above)
@Autowired
@Qualifier("xaJmsConnectionFactory")
private ConnectionFactory xaConnectionFactory;

// Inject the non-XA aware ConnectionFactory
@Autowired
@Qualifier("nonXaJmsConnectionFactory")
private ConnectionFactory nonXaConnectionFactory;

37.5支持替代嵌入式事务管理器

这,这个,那,那个XAConnectionFactoryWrapperXADataSourceWrapper接口可用于支持其他嵌入式事务管理器。接口负责包装。XAConnectionFactoryXADataSource豆类,并将它们作为常规公开。ConnectionFactoryDataSourcebean,它透明地注册在分布式事务中。DataSource和JMS自动配置使用JTA变体,只要您有JtaTransactionManager中注册的bean和适当的XA包装bean。ApplicationContext.

这,这个,那,那个BitronixXAConnectionFactoryWrapperBitronixXADataSourceWrapper提供关于如何编写XA包装器的良好示例。

38.哈泽尔卡斯特

如果哈泽尔卡斯特在类路径上,并找到合适的配置,SpringBoot自动配置HazelcastInstance你可以在你的应用程序中注入。

如果定义com.hazelcast.config.ConfigBeanSpring Boot使用这个。如果您的配置定义了实例名,SpringBoot将尝试定位一个现有实例,而不是创建一个新实例。

您还可以指定hazelcast.xml要通过配置使用的配置文件,如以下示例所示:

spring.hazelcast.config=classpath:config/my-hazelcast.xml

否则,SpringBoot尝试从默认位置查找Hazelcast配置:hazelcast.xml在工作目录或类路径的根目录中。我们还检查hazelcast.config设置系统属性。见Hazelcast文件更多细节。

如果hazelcast-client在类路径中,SpringBoot第一次尝试通过检查以下配置选项来创建客户端:

  • A的存在com.hazelcast.client.config.ClientConfig豆子
  • 控件定义的配置文件。spring.hazelcast.config财产。
  • 的存在hazelcast.client.config系统属性
  • hazelcast-client.xml在工作目录或类路径的根目录中。
[Note]

春靴也有对Hazelcast的显式缓存支持。如果启用了缓存,则HazelcastInstance自动包装在CacheManager执行。

39.石英调度器

Spring Boot为使用石英调度器,包括spring-boot-starter-quartz“初学者”。如果石英可用,Scheduler是自动配置的(通过SchedulerFactoryBean抽象)

将自动获取下列类型的bean并将其与Scheduler:

  • JobDetail*定义特定职务。JobDetail实例可以使用JobBuilderAPI
  • Calendar.
  • Trigger*定义何时触发特定作业。

默认情况下,内存中的JobStore被利用了。但是,如果DataSourcebean在您的应用程序中可用,如果spring.quartz.job-store-type属性进行相应配置,如以下示例所示:

spring.quartz.job-store-type=jdbc

当使用JDBC存储时,模式可以在启动时初始化,如下面的示例所示:

spring.quartz.jdbc.initialize-schema=always
[Note]

默认情况下,使用Quartz库提供的标准脚本检测和初始化数据库。还可以通过设置spring.quartz.jdbc.schema财产。

默认情况下,配置创建的作业不会覆盖已从持久性作业存储区读取的已注册作业。若要启用覆盖现有作业定义,请将spring.quartz.overwrite-existing-jobs财产。

石英调度器配置可以使用spring.quartz属性和SchedulerFactoryBeanCustomizerbean,它允许编程。SchedulerFactoryBean定制。高级Quartz配置属性可以使用spring.quartz.properties.*.

[Note]

特别是,Executorbean与调度程序没有关联,因为Quartz提供了一种通过以下方式配置调度程序的方法:spring.quartz.properties。如果需要自定义任务执行器,请考虑实现SchedulerFactoryBeanCustomizer.

作业可以定义设置器来注入数据映射属性。也可以类似的方式注入常规bean,如下例所示:

public class SampleJob extends QuartzJobBean {

	private MyService myService;

	private String name;

	// Inject "MyService" bean
	public void setMyService(MyService myService) { ... }

	// Inject the "name" job data property
	public void setName(String name) { ... }

	@Override
	protected void executeInternal(JobExecutionContext context)
			throws JobExecutionException {
		...
	}

}

四十任务执行和调度

在没有TaskExecutorbean在上下文中,SpringBoot自动配置ThreadPoolTaskExecutor具有可自动关联到异步任务执行的合理默认值(@EnableAsync)和SpringMVC异步请求处理。

线程池使用8个核心线程,它们可以根据负载增长和收缩。这些默认设置可以使用spring.task.execution命名空间,如以下示例所示:

spring.task.execution.pool.max-threads=16
spring.task.execution.pool.queue-capacity=100
spring.task.execution.pool.keep-alive=10s

这将线程池更改为使用有界队列,以便当队列满(100个任务)时,线程池将增加到最多16个线程。当线程空闲10秒时(而不是默认的60秒),线程的收缩更具有侵略性。

ThreadPoolTaskScheduler如果需要与计划的任务执行相关联,也可以自动配置(@EnableScheduling)线程池默认使用一个线程,这些设置可以使用spring.task.scheduling命名空间。

双双TaskExecutorBuilder豆和aTaskSchedulerBuilder如果需要创建自定义执行器或调度程序,则可以在上下文中使用bean。

41.弹簧集成

SpringBoot为使用弹簧集成,包括spring-boot-starter-integration“初学者”。SpringIntegration通过消息传递和其他传输(如HTTP、TCP和其他传输)提供抽象。如果SpringIntegration在类路径上可用,则通过@EnableIntegration注释

SpringBoot还配置了一些特性,这些特性是由其他SpringIntegration模块的存在触发的。如果spring-integration-jmx也在类路径上,消息处理统计信息是通过JMX发布的。如果spring-integration-jdbc可用时,可以在启动时创建默认数据库架构,如下所示:

spring.integration.jdbc.initialize-schema=always

IntegrationAutoConfigurationIntegrationProperties有关更多细节的类。

默认情况下,如果千分尺meterRegistrybean是存在的,Spring集成度量将通过千分尺进行管理。如果希望使用遗留的SpringIntegration度量,请添加DefaultMetricsFactorybean到应用程序上下文。

42.春季会议

弹簧启动春季会议用于多种数据存储的自动配置。在构建Servlet Web应用程序时,可以自动配置以下存储:

  • JDBC
  • 雷迪斯
  • 哈泽尔卡斯特
  • MongoDB

在构建反应性Web应用程序时,可以自动配置以下存储:

  • 雷迪斯
  • MongoDB

如果类路径上存在单个Spring会话模块,SpringBoot将自动使用该存储实现。如果有多个实现,则必须选择StoreType来存储会话。例如,要使用JDBC作为后端存储,可以按照以下方式配置应用程序:

spring.session.store-type=jdbc
[Tip]

可以通过设置store-typenone.

每个商店都有特定的附加设置。例如,可以自定义JDBC存储的表名,如下面的示例所示:

spring.session.jdbc.table-name=SESSIONS

若要设置会话的超时,可以使用spring.session.timeout财产。如果未设置该属性,则自动配置将返回到server.servlet.session.timeout.

43.对JMX的监测和管理

Java管理扩展(JMX)提供了监视和管理应用程序的标准机制。默认情况下,SpringBoot创建一个MBeanServerID为mbeanServer并公开任何用SpringJMX注释的bean(@ManagedResource@ManagedAttribute,或@ManagedOperation).

JmxAutoConfiguration获取更多详细信息。

44.测试

SpringBoot在测试应用程序时提供了许多实用程序和注释来帮助您。测试支持由两个模块提供:spring-boot-test包含核心项,以及spring-boot-test-autoconfigure支持测试的自动配置。

大多数开发人员使用spring-boot-starter-test“初学者”,它导入SpringBoot测试模块以及JUnit、AssertJ、Hamcrest和许多其他有用的库。

44.1测试范围依赖项

这,这个,那,那个spring-boot-starter-test“初学者”(在test scope)包含下列提供的库:

我们通常认为这些公共库在编写测试时很有用。如果这些库不适合您的需要,则可以添加您自己的其他测试依赖项。

44.2测试Spring应用程序

依赖注入的主要优点之一是它应该使您的代码更容易进行单元测试。属性实例化对象。new操作员甚至不涉及Spring。您也可以使用模拟对象而不是真正的依赖关系。

通常,您需要超越单元测试,开始集成测试(使用Spring)ApplicationContext)能够在不需要部署应用程序或连接到其他基础结构的情况下执行集成测试是非常有用的。

Spring框架包括一个专门用于这种集成测试的测试模块。可以将依赖项直接声明为org.springframework:spring-test或使用spring-boot-starter-test“起动机”把它临时拉进来。

如果您没有使用spring-test模块之前,您应该从读取相关部分Spring框架参考文档。

44.3测试SpringBoot应用程序

Spring引导应用程序是SpringApplicationContext因此,除了通常使用普通Spring上下文所做的工作之外,没有什么特别的事情要做来测试它。

[Note]

外部属性、日志记录和SpringBoot的其他特性在默认情况下仅在以下情况下才会安装在上下文中SpringApplication去创造它。

Spring Boot提供了一个@SpringBootTest注释,可以作为标准的替代。spring-test @ContextConfiguration当您需要SpringBoot特性时进行注释。注释的作用是创建ApplicationContext在您的测试中使用SpringApplication。除了……之外@SpringBootTest还提供了一些其他注释。测试更具体的切片一份申请书。

[Tip]

如果您使用的是JUnit 4,请不要忘记添加@RunWith(SpringRunner.class)对于您的测试,否则注释将被忽略。如果您使用的是JUnit 5,则不需要添加等效的@ExtendWith(SpringExtension)@SpringBootTest另一个@…Test注释已经用它注释了。

默认情况下,@SpringBootTest不会启动服务器。您可以使用webEnvironment属性@SpringBootTest为了进一步完善测试的运行方式:

  • MOCK(默认):加载WebApplicationContext并提供一个模拟Web环境。使用此注释时不会启动嵌入式服务器。如果您的类路径上没有web环境,则此模式将透明地退回到创建常规的非web环境。ApplicationContext。它可以与@AutoConfigureMockMvc@AutoConfigureWebTestClient用于基于模拟的web应用程序测试。
  • RANDOM_PORT*装载WebServerApplicationContext并提供了一个真实的网络环境。嵌入式服务器将启动并在随机端口上侦听。
  • DEFINED_PORT*装载WebServerApplicationContext并提供了一个真实的网络环境。嵌入式服务器将在定义的端口上启动并侦听(从application.properties)或在默认端口8080.
  • NONE*加载ApplicationContextSpringApplication但没有提供任何Web环境(模拟或其他)。
[Note]

如果你的测试是@Transactional,默认情况下,它会在每个测试方法的末尾回滚事务。但是,当使用这种安排时,RANDOM_PORTDEFINED_PORT隐式地提供了一个真正的servlet环境,HTTP客户机和服务器在单独的线程中运行,因此在单独的事务中运行。在这种情况下,服务器上启动的任何事务都不会回滚。

[Note]

@SpringBootTest带着webEnvironment = WebEnvironment.RANDOM_PORT如果应用程序对管理服务器使用不同的端口,则还将在单独的随机端口上启动管理服务器。

44.3.1检测Web应用程序类型

如果SpringMVC可用,则配置一个基于MVC的常规应用程序上下文。如果您只有SpringWebFlux,我们将检测它并配置一个基于WebFlux的应用程序上下文。

如果两者都存在,则优先考虑SpringMVC。如果要在此方案中测试反应性web应用程序,则必须将spring.main.web-application-type财产:

@RunWith(SpringRunner.class)
@SpringBootTest(properties = "spring.main.web-application-type=reactive")
public class MyWebFluxTests { ... }

44.3.2检测测试配置

如果您熟悉Spring测试框架,您可能已经习惯于使用@ContextConfiguration(classes=…​)为了指定哪个Spring@Configuration装货。或者,您可能经常使用嵌套。@Configuration测试中的类。

在测试SpringBoot应用程序时,这通常不是必需的。弹簧靴@*Test当您没有显式定义主配置时,注释会自动搜索您的主配置。

搜索算法从包含测试的包开始工作,直到找到带注释的类。@SpringBootApplication@SpringBootConfiguration。只要你结构化代码以一种明智的方式,通常可以找到您的主要配置。

[Note]

如果您使用测试注释以测试应用程序中更特定的部分,则应避免添加特定于主要方法的应用类.

的基础组件扫描配置@SpringBootApplication定义用于确保切片按预期工作的排除筛选器。如果您使用的是显式@ComponentScan指示@SpringBootApplication-带注释的类,请注意这些过滤器将被禁用。如果您正在使用切片,您应该再次定义它们。

如果要自定义主配置,可以使用嵌套的@TestConfiguration班级,等级不像嵌套的@Configuration类,它将用于替代应用程序的主要配置,即嵌套的@TestConfiguration类除了应用程序的主要配置外,还使用。

[Note]

Spring的测试框架在测试之间缓存应用程序上下文。因此,只要您的测试共享相同的配置(无论如何发现),加载上下文的潜在耗时过程只会发生一次。

44.3.3不包括测试配置

如果应用程序使用组件扫描(例如,如果您使用@SpringBootApplication@ComponentScan),您可能会发现只为特定测试创建的顶级配置类在任何地方都会意外地被选中。

因为我们之前见过@TestConfiguration可以在测试的内部类上使用,以自定义主配置。当被安排到顶级班级时,@TestConfiguration表示src/test/java不应通过扫描来拾取。然后,可以在需要的地方显式导入该类,如以下示例所示:

@RunWith(SpringRunner.class)
@SpringBootTest
@Import(MyTestsConfiguration.class)
public class MyTests {

	@Test
	public void exampleTest() {
		...
	}

}
[Note]

如果你直接用@ComponentScan(也就是说,不是通过@SpringBootApplication)您需要注册TypeExcludeFilter用它。看见Javadoc关于细节。

44.3.4用模拟环境进行测试

默认情况下,@SpringBootTest没有启动服务器。如果您有要在此模拟环境中测试的web端点,则可以另外配置MockMvc如以下示例所示:

import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MockMvcExampleTests {

	@Autowired
	private MockMvc mvc;

	@Test
	public void exampleTest() throws Exception {
		this.mvc.perform(get("/")).andExpect(status().isOk())
				.andExpect(content().string("Hello World"));
	}

}
[Tip]

如果希望只关注web层而不启动完整的ApplicationContext,考虑使用@WebMvcTest相反.

或者,您可以配置WebTestClient如以下示例所示:

import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.reactive.server.WebTestClient;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureWebTestClient
public class MockWebTestClientExampleTests {

	@Autowired
	private WebTestClient webClient;

	@Test
	public void exampleTest() {
		this.webClient.get().uri("/").exchange().expectStatus().isOk()
				.expectBody(String.class).isEqualTo("Hello World");
	}

}

44.3.5使用运行中的服务器进行测试

如果您需要启动一个完整运行的服务器,我们建议您使用随机端口。如果你用@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT),每次测试运行时都会随机选择可用端口。

这,这个,那,那个@LocalServerPort注释可用于注入实际使用的端口进入你的测试。为了方便起见,需要对已启动的服务器进行REST调用的测试可以另外使用。@Autowire a WebTestClient,它解析与正在运行的服务器的相对链接,并附带一个用于验证响应的专用API,如以下示例所示:

import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.reactive.server.WebTestClient;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class RandomPortWebTestClientExampleTests {

	@Autowired
	private WebTestClient webClient;

	@Test
	public void exampleTest() {
		this.webClient.get().uri("/").exchange().expectStatus().isOk()
				.expectBody(String.class).isEqualTo("Hello World");
	}

}

此设置要求spring-webflux在类路径上。如果您不能或不愿添加网络流量,SpringBoot还提供了一个TestRestTemplate设施:

import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import static org.assertj.core.api.Assertions.assertThat;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class RandomPortTestRestTemplateExampleTests {

	@Autowired
	private TestRestTemplate restTemplate;

	@Test
	public void exampleTest() {
		String body = this.restTemplate.getForObject("/", String.class);
		assertThat(body).isEqualTo("Hello World");
	}

}

44.3.6使用JMX

由于测试上下文框架缓存上下文,因此默认情况下禁用JMX以防止相同组件在同一域中注册。如果这种测试需要访问MBeanServer,也考虑将其标记为脏的:

@RunWith(SpringRunner.class)
@SpringBootTest(properties = "spring.jmx.enabled=true")
@DirtiesContext
public class SampleJmxTests {

	@Autowired
	private MBeanServer mBeanServer;

	@Test
	public void exampleTest() {
		// ...
	}

}

44.3.7嘲弄和间谍豆

在运行测试时,有时需要在应用程序上下文中模拟某些组件。例如,在开发期间不可用的远程服务上可能有一个外观。当您想要模拟在实际环境中可能很难触发的失败时,模拟也是非常有用的。

弹簧启动包括一个@MockBean注释,可用于为您内部的bean定义一个Mockito模拟。ApplicationContext。您可以使用注释添加新bean或替换单个现有bean定义。该注释可直接用于测试类、测试中的字段或@Configuration类别和字段。在字段上使用时,也会注入创建的模拟实例。模拟bean在每个测试方法之后都会自动重置。

[Note]

如果您的测试使用SpringBoot的测试注释之一(如@SpringBootTest),此功能将自动启用。若要以不同的安排使用此功能,必须显式添加侦听器,如以下示例所示:

@TestExecutionListeners(MockitoTestExecutionListener.class)

下面的示例替换现有的RemoteService带有模拟实现的bean:

import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.context.*;
import org.springframework.boot.test.mock.mockito.*;
import org.springframework.test.context.junit4.*;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTests {

	@MockBean
	private RemoteService remoteService;

	@Autowired
	private Reverser reverser;

	@Test
	public void exampleTest() {
		// RemoteService has been injected into the reverser bean
		given(this.remoteService.someCall()).willReturn("mock");
		String reverse = reverser.reverseSomeCall();
		assertThat(reverse).isEqualTo("kcom");
	}

}

此外,您还可以使用@SpyBean若要用Mockito包装现有的bean,请执行以下操作spy。见Javadoc详细情况。

[Note]

Spring的测试框架在测试之间缓存应用程序上下文,并重用用于共享相同配置的测试的上下文,而使用@MockBean@SpyBean影响缓存键,这很可能会增加上下文的数量。

44.3.8自动配置测试

SpringBoot的自动配置系统在应用程序中运行良好,但有时对测试来说可能有点过了。它通常帮助只加载测试应用程序的“片段”所需的配置部分。例如,您可能希望测试SpringMVC控制器是否正确地映射URL,并且不希望在这些测试中涉及数据库调用,或者您可能希望测试JPA实体,并且在这些测试运行时对Web层不感兴趣。

这,这个,那,那个spring-boot-test-autoconfigure模块包含许多注释,这些注释可用于自动配置此类“片”。它们中的每一个都以类似的方式工作,提供了一个@…​Test加载ApplicationContext和一个或多个@AutoConfigure…​可用于自定义自动配置设置的注释。

[Note]

每个切片限制组件扫描到适当的组件,并加载一组非常受限的自动配置类。如果你需要排除其中一个@…​Test注释提供了一个excludeAutoConfiguration属性。或者,您可以使用@ImportAutoConfiguration#exclude.

[Tip]

也可以使用@AutoConfigure…​标准注释@SpringBootTest注释如果您对“切片”应用程序不感兴趣,但需要一些自动配置的测试bean,则可以使用此组合。

44.3.9自动配置的JSON测试

若要测试对象JSON序列化和反序列化是否正常工作,可以使用@JsonTest注释@JsonTest自动配置可用的受支持的JSON映射程序,它可以是以下库之一:

  • 杰克森ObjectMapper,任何@JsonComponent豆子和杰克逊Modules
  • Gson
  • Jsonb
[Tip]

启用的自动配置的列表。@JsonTest可以见附录.

如果需要配置自动配置的元素,可以使用@AutoConfigureJsonTesters注释

SpringBoot包括基于AssertJ的帮助程序,它们使用JSONAssert和JsonPath库来检查JSON是否如预期的那样出现。这,这个,那,那个JacksonTesterGsonTester,JsonbTester,和BasicJsonTester类可以分别用于Jackson、GSON、Jsonb和String。测试类上的任何辅助字段都可以是@Autowired使用时@JsonTest。下面的示例显示了Jackson的测试类:

import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.json.*;
import org.springframework.boot.test.context.*;
import org.springframework.boot.test.json.*;
import org.springframework.test.context.junit4.*;

import static org.assertj.core.api.Assertions.*;

@RunWith(SpringRunner.class)
@JsonTest
public class MyJsonTests {

	@Autowired
	private JacksonTester<VehicleDetails> json;

	@Test
	public void testSerialize() throws Exception {
		VehicleDetails details = new VehicleDetails("Honda", "Civic");
		// Assert against a `.json` file in the same package as the test
		assertThat(this.json.write(details)).isEqualToJson("expected.json");
		// Or use JSON path based assertions
		assertThat(this.json.write(details)).hasJsonPathStringValue("@.make");
		assertThat(this.json.write(details)).extractingJsonPathStringValue("@.make")
				.isEqualTo("Honda");
	}

	@Test
	public void testDeserialize() throws Exception {
		String content = "{\"make\":\"Ford\",\"model\":\"Focus\"}";
		assertThat(this.json.parse(content))
				.isEqualTo(new VehicleDetails("Ford", "Focus"));
		assertThat(this.json.parseObject(content).getMake()).isEqualTo("Ford");
	}

}
[Note]

JSON助手类也可以直接用于标准单元测试。为此,请调用initFields方法中的助手的@Before如果不使用@JsonTest.

44.3.10自动配置的SpringMVC测试

若要测试SpringMVC控制器是否按预期工作,请使用@WebMvcTest注释@WebMvcTest自动配置SpringMVC基础结构,并将扫描bean限制为@Controller@ControllerAdvice@JsonComponentConverterGenericConverterFilterWebMvcConfigurer,和HandlerMethodArgumentResolver。正规化@Component使用此注释时不会扫描bean。

[Tip]

启用的自动配置设置的列表。@WebMvcTest可以见附录.

[Tip]

如果您需要注册额外的组件,比如JacksonModule,则可以通过以下方法导入其他配置类:@Import在你的测试中。

通常,@WebMvcTest仅限于单个控制器,并与@MockBean为所需的协作者提供模拟实现。

@WebMvcTest也自动配置MockMvc。模拟MVC提供了一种功能强大的方法,可以快速测试MVC控制器,而无需启动完整的HTTP服务器。

[Tip]

您还可以自动配置MockMvc在一个非-@WebMvcTest(如@SpringBootTest)通过用@AutoConfigureMockMvc。下面的示例使用MockMvc:

import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.web.servlet.*;
import org.springframework.boot.test.mock.mockito.*;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringRunner.class)
@WebMvcTest(UserVehicleController.class)
public class MyControllerTests {

	@Autowired
	private MockMvc mvc;

	@MockBean
	private UserVehicleService userVehicleService;

	@Test
	public void testExample() throws Exception {
		given(this.userVehicleService.getVehicleDetails("sboot"))
				.willReturn(new VehicleDetails("Honda", "Civic"));
		this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
				.andExpect(status().isOk()).andExpect(content().string("Honda Civic"));
	}

}
[Tip]

如果需要配置自动配置的元素(例如,何时应用servlet筛选器),则可以在@AutoConfigureMockMvc注释

如果使用htmlUnit或Selenium,则自动配置还提供了HTMLUnit。WebClient豆和/或aWebDriver豆子以下示例使用HtmlUnit:

import com.gargoylesoftware.htmlunit.*;
import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.web.servlet.*;
import org.springframework.boot.test.mock.mockito.*;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;

@RunWith(SpringRunner.class)
@WebMvcTest(UserVehicleController.class)
public class MyHtmlUnitTests {

	@Autowired
	private WebClient webClient;

	@MockBean
	private UserVehicleService userVehicleService;

	@Test
	public void testExample() throws Exception {
		given(this.userVehicleService.getVehicleDetails("sboot"))
				.willReturn(new VehicleDetails("Honda", "Civic"));
		HtmlPage page = this.webClient.getPage("/sboot/vehicle.html");
		assertThat(page.getBody().getTextContent()).isEqualTo("Honda Civic");
	}

}
[Note]

默认情况下,SpringBootWebDriverbean在一个特殊的“作用域”中,以确保驱动程序在每次测试后退出,并注入一个新实例。如果不想要这种行为,可以添加@Scope("singleton")敬你的WebDriver @Bean定义。

如果你在类路径上有Spring保安,@WebMvcTest也会扫描WebSecurityConfigurer豆子您可以使用SpringSecurity的测试支持,而不是完全禁用此类测试的安全性。关于如何使用Spring安全的更多详细信息MockMvc支持可在以下内容中找到:第79章,用Spring安全性进行测试如何-到部分。

[Tip]

有时候编写SpringMVC测试是不够的;SpringBoot可以帮助您运行使用实际服务器进行完整的端到端测试。.

44.3.11自动配置的SpringWebFlux测试

来测试一下春季WebFlux控制器按预期工作,可以使用@WebFluxTest注释@WebFluxTest自动配置SpringWebFlux基础结构,并将扫描bean限制为@Controller@ControllerAdvice@JsonComponentConverterGenericConverter,和WebFluxConfigurer。正规化@Component对象时不扫描bean。@WebFluxTest使用注释。

[Tip]

启用的自动配置的列表。@WebFluxTest可以见附录.

[Tip]

如果您需要注册额外的组件,比如JacksonModule,您可以使用@Import在你的测试中。

通常,@WebFluxTest仅限于单个控制器,并与@MockBean注释为所需的协作者提供模拟实现。

@WebFluxTest也自动配置WebTestClient,它提供了一种功能强大的方法,可以快速测试WebFlux控制器,而无需启动完整的HTTP服务器。

[Tip]

您还可以自动配置WebTestClient在一个非-@WebFluxTest(如@SpringBootTest)通过用@AutoConfigureWebTestClient。下面的示例显示了一个同时使用这两种方法的类@WebFluxTest和一个WebTestClient:

import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.reactive.server.WebTestClient;

@RunWith(SpringRunner.class)
@WebFluxTest(UserVehicleController.class)
public class MyControllerTests {

	@Autowired
	private WebTestClient webClient;

	@MockBean
	private UserVehicleService userVehicleService;

	@Test
	public void testExample() throws Exception {
		given(this.userVehicleService.getVehicleDetails("sboot"))
				.willReturn(new VehicleDetails("Honda", "Civic"));
		this.webClient.get().uri("/sboot/vehicle").accept(MediaType.TEXT_PLAIN)
				.exchange()
				.expectStatus().isOk()
				.expectBody(String.class).isEqualTo("Honda Civic");
	}

}
[Tip]

此设置仅受WebFlux应用程序支持,因为WebTestClient在模拟的Web应用程序中,目前只使用WebFlux。

[Note]

@WebFluxTest无法检测通过功能Web框架注册的路由。用于测试RouterFunction上下文中的bean,请考虑导入RouterFunction通过@Import或使用@SpringBootTest.

[Tip]

有时编写SpringWebFlux测试是不够的;SpringBoot可以帮助您运行使用实际服务器进行完整的端到端测试。.

44.3.12自动配置的数据JPA测试

您可以使用@DataJpaTest用于测试JPA应用程序的注释。默认情况下,它配置内存内嵌入式数据库,扫描@Entity类,并配置Spring数据JPA存储库。正规化@Componentbean未加载到ApplicationContext.

[Tip]

启用的自动配置设置的列表。@DataJpaTest可以见附录.

默认情况下,数据JPA测试是事务性的,并且在每个测试结束时回滚。见相关部分在SpringFramework参考文档中获得更多细节。如果这不是您想要的,您可以禁用测试或整个类的事务管理,如下所示:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringRunner.class)
@DataJpaTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public class ExampleNonTransactionalTests {

}

DataJPA测试也可能会注入一个TestEntityManager,它提供了标准JPA的替代方案。EntityManager这是专门为测试设计的。如果你想用TestEntityManager@DataJpaTest实例,也可以使用@AutoConfigureTestEntityManager注释一个JdbcTemplate如果你需要的话也可以。下面的示例显示@DataJpaTest正在使用的注释:

import org.junit.*;
import org.junit.runner.*;
import org.springframework.boot.test.autoconfigure.orm.jpa.*;

import static org.assertj.core.api.Assertions.*;

@RunWith(SpringRunner.class)
@DataJpaTest
public class ExampleRepositoryTests {

	@Autowired
	private TestEntityManager entityManager;

	@Autowired
	private UserRepository repository;

	@Test
	public void testExample() throws Exception {
		this.entityManager.persist(new User("sboot", "1234"));
		User user = this.repository.findByUsername("sboot");
		assertThat(user.getUsername()).isEqualTo("sboot");
		assertThat(user.getVin()).isEqualTo("1234");
	}

}

内存中的嵌入式数据库通常用于测试,因为它们速度快,不需要任何安装。但是,如果您更愿意对实际数据库运行测试,则可以使用@AutoConfigureTestDatabase注释,如以下示例所示:

@RunWith(SpringRunner.class)
@DataJpaTest
@AutoConfigureTestDatabase(replace=Replace.NONE)
public class ExampleRepositoryTests {

	// ...

}

44.3.13自动配置的JDBC测试

@JdbcTest类似于@DataJpaTest而是用于只需要DataSource也不要使用SpringDataJDBC。默认情况下,它配置内存内嵌入数据库和JdbcTemplate。正规化@Componentbean未加载到ApplicationContext.

[Tip]

启用的自动配置的列表。@JdbcTest可以见附录.

默认情况下,JDBC测试是事务性的,并且在每个测试结束时回滚。见相关部分在SpringFramework参考文档中获得更多细节。如果这不是您想要的,您可以禁用测试或整个类的事务管理,如下所示:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringRunner.class)
@JdbcTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public class ExampleNonTransactionalTests {

}

如果您希望在实际数据库上运行测试,则可以使用@AutoConfigureTestDatabase注释的方式与DataJpaTest。(见“第44.3.12节,“自动配置数据JPA测试”".)

44.3.14自动配置的数据JDBC测试

@DataJdbcTest类似于@JdbcTest而是用于使用Spring数据JDBC存储库的测试。默认情况下,它配置内存内嵌入数据库,JdbcTemplate,以及Spring数据JDBC存储库。正规化@Componentbean未加载到ApplicationContext.

[Tip]

启用的自动配置的列表。@DataJdbcTest可以见附录.

默认情况下,数据JDBC测试是事务性的,并且在每个测试结束时回滚。见相关部分在SpringFramework参考文档中获得更多细节。如果这不是您想要的,您可以将测试或整个测试类的事务管理禁用为如jdbc示例所示.

如果您希望在实际数据库上运行测试,则可以使用@AutoConfigureTestDatabase注释的方式与DataJpaTest。(见“第44.3.12节,“自动配置数据JPA测试”".)

44.3.15自动配置的jOOQ测试

你可以用@JooqTest以类似的方式@JdbcTest但对于与jOOQ相关的测试。由于jOOQ严重依赖与数据库模式相对应的基于Java的模式,DataSource被利用了。如果要用内存中的数据库替换它,可以使用@AutoConfigureTestDatabase覆盖这些设置。(有关在SpringBoot中使用jOOQ的更多信息,请参见“第29.6节,“使用jOOQ”“,在本章前面。@Componentbean未加载到ApplicationContext.

[Tip]

启用的自动配置的列表。@JooqTest可以见附录.

@JooqTest配置DSLContext。正规化@Componentbean未加载到ApplicationContext。下面的示例显示@JooqTest正在使用的注释:

import org.jooq.DSLContext;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.jooq.JooqTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@JooqTest
public class ExampleJooqTests {

	@Autowired
	private DSLContext dslContext;
}

JOOQ测试是事务性的,默认情况下在每个测试结束时回滚。如果这不是您想要的,您可以将测试或整个测试类的事务管理禁用为如jdbc示例所示.

44.3.16自动配置的数据MongoDB测试

你可以用@DataMongoTest测试MongoDB应用程序。默认情况下,它配置内存中嵌入的MongoDB(如果可用),配置MongoTemplate,扫描@Document类,并配置Spring数据MongoDB存储库。正规化@Componentbean未加载到ApplicationContext。(有关在SpringBoot中使用MongoDB的更多信息,请参见“第30.2节,“MongoDB”“,在本章前面。

[Tip]

启用的自动配置设置的列表。@DataMongoTest可以见附录.

下面的类显示@DataMongoTest正在使用的注释:

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@DataMongoTest
public class ExampleDataMongoTests {

	@Autowired
	private MongoTemplate mongoTemplate;

	//
}

内存中嵌入的MongoDB通常适用于测试,因为它速度快,不需要任何开发人员安装。但是,如果您更愿意对真实的MongoDB服务器运行测试,则应该排除嵌入的MongoDB自动配置,如下面的示例所示:

import org.junit.runner.RunWith;
 import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class)
public class ExampleDataMongoNonEmbeddedTests {

}

44.3.17自动配置的数据Neo4j测试

你可以用@DataNeo4jTest测试Neo4j应用程序。默认情况下,它使用内存内嵌入的neo4j(如果嵌入式驱动程序可用),扫描@NodeEntity类,并配置Spring数据Neo4j存储库。正规化@Componentbean未加载到ApplicationContext。(有关在SpringBoot中使用Neo4J的更多信息,请参见“第30.3节,“Neo4j”“,在本章前面。

[Tip]

启用的自动配置设置的列表。@DataNeo4jTest可以见附录.

下面的示例展示了在SpringBoot中使用Neo4J测试的典型设置:

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@DataNeo4jTest
public class ExampleDataNeo4jTests {

	@Autowired
	private YourRepository repository;

	//
}

默认情况下,DataNeo4j测试是事务性的,在每个测试结束时回滚。见相关部分在SpringFramework参考文档中获得更多细节。如果这不是您想要的,您可以禁用测试或整个类的事务管理,如下所示:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringRunner.class)
@DataNeo4jTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public class ExampleNonTransactionalTests {

}

44.3.18自动配置的数据Redis测试

你可以用@DataRedisTest测试Redis应用程序。默认情况下,它扫描@RedisHash类和配置SpringDataRedis存储库。正规化@Componentbean未加载到ApplicationContext。(有关在SpringBoot中使用Redis的更多信息,请参见“第30.1节,“Redis”“,在本章前面。

[Tip]

启用的自动配置设置的列表。@DataRedisTest可以见附录.

下面的示例显示@DataRedisTest正在使用的注释:

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.redis.DataRedisTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@DataRedisTest
public class ExampleDataRedisTests {

	@Autowired
	private YourRepository repository;

	//
}

44.3.19自动配置的数据LDAP测试

你可以用@DataLdapTest测试LDAP应用程序。默认情况下,它配置内存中嵌入的ldap(如果可用),配置LdapTemplate,扫描@Entry类,并配置Spring数据LDAP存储库。正规化@Componentbean未加载到ApplicationContext。(有关在SpringBoot中使用LDAP的更多信息,请参见“第30.9节,“LDAP”“,在本章前面。

[Tip]

启用的自动配置设置的列表。@DataLdapTest可以见附录.

下面的示例显示@DataLdapTest正在使用的注释:

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@DataLdapTest
public class ExampleDataLdapTests {

	@Autowired
	private LdapTemplate ldapTemplate;

	//
}

内存中嵌入的LDAP通常适用于测试,因为它速度快,不需要任何开发人员安装。但是,如果您更愿意对实际的LDAP服务器运行测试,则应该排除嵌入式LDAP自动配置,如下面的示例所示:

import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration;
import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@DataLdapTest(excludeAutoConfiguration = EmbeddedLdapAutoConfiguration.class)
public class ExampleDataLdapNonEmbeddedTests {

}

44.3.20自动配置的REST客户端

您可以使用@RestClientTest用于测试REST客户端的注释。默认情况下,它自动配置Jackson、gson和jsonb支持,配置RestTemplateBuilder,并增加了对MockRestServiceServer。正规化@Componentbean未加载到ApplicationContext.

[Tip]

启用的自动配置设置的列表。@RestClientTest可以见附录.

属性指定要测试的特定bean。valuecomponents属性@RestClientTest,如以下示例所示:

@RunWith(SpringRunner.class)
@RestClientTest(RemoteVehicleDetailsService.class)
public class ExampleRestClientTest {

	@Autowired
	private RemoteVehicleDetailsService service;

	@Autowired
	private MockRestServiceServer server;

	@Test
	public void getVehicleDetailsWhenResultIsSuccessShouldReturnDetails()
			throws Exception {
		this.server.expect(requestTo("/greet/details"))
				.andRespond(withSuccess("hello", MediaType.TEXT_PLAIN));
		String greeting = this.service.callRestService();
		assertThat(greeting).isEqualTo("hello");
	}

}

44.3.21自动配置的SpringREST文档测试

您可以使用@AutoConfigureRestDocs要使用的注释弹簧休息文档在您的测试中使用Mock MVC还是放心。它消除了SpringREST文档中对JUnit规则的需求。

@AutoConfigureRestDocs可以用来覆盖默认输出目录(target/generated-snippets如果您正在使用Maven或build/generated-snippets如果您正在使用Gradle)。它还可以用于配置出现在任何文档URI中的主机、方案和端口。

用Mock MVC自动配置SpringREST文档测试

@AutoConfigureRestDocs自定义MockMvcbean使用SpringREST文档。您可以使用@Autowired并在测试中使用它,就像在使用Mock MVC和SpringREST文档时一样,如下面的示例所示:

import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringRunner.class)
@WebMvcTest(UserController.class)
@AutoConfigureRestDocs
public class UserDocumentationTests {

	@Autowired
	private MockMvc mvc;

	@Test
	public void listUsers() throws Exception {
		this.mvc.perform(get("/users").accept(MediaType.TEXT_PLAIN))
				.andExpect(status().isOk())
				.andDo(document("list-users"));
	}

}

如果您需要对SpringRESTDocs配置的控制比@AutoConfigureRestDocs,您可以使用RestDocsMockMvcConfigurationCustomizerbean,如以下示例所示:

@TestConfiguration
static class CustomizationConfiguration
		implements RestDocsMockMvcConfigurationCustomizer {

	@Override
	public void customize(MockMvcRestDocumentationConfigurer configurer) {
		configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
	}

}

如果要使用SpringRESTDocs对参数化输出目录的支持,可以创建RestDocumentationResultHandler豆子自动配置调用alwaysDo使用此结果处理程序,从而导致每个MockMvc调用以自动生成默认代码段。下面的示例显示RestDocumentationResultHandler定义如下:

@TestConfiguration
static class ResultHandlerConfiguration {

	@Bean
	public RestDocumentationResultHandler restDocumentation() {
		return MockMvcRestDocumentation.document("{method-name}");
	}

}

自动配置的SpringREST文档测试

@AutoConfigureRestDocs使.RequestSpecificationbean,预先配置为使用SpringREST文档,可用于测试。您可以使用@Autowired并在测试中使用它,就像在使用REST和SpringREST文档时一样,如下面的示例所示:

import io.restassured.specification.RequestSpecification;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.document;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureRestDocs
public class UserDocumentationTests {

	@LocalServerPort
	private int port;

	@Autowired
	private RequestSpecification documentationSpec;

	@Test
	public void listUsers() {
		given(this.documentationSpec).filter(document("list-users")).when()
				.port(this.port).get("/").then().assertThat().statusCode(is(200));
	}

}

如果您需要对SpringRESTDocs配置的控制比@AutoConfigureRestDocs..RestDocsRestAssuredConfigurationCustomizer可以使用bean,如以下示例所示:

@TestConfiguration
public static class CustomizationConfiguration
		implements RestDocsRestAssuredConfigurationCustomizer {

	@Override
	public void customize(RestAssuredRestDocumentationConfigurer configurer) {
		configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
	}

}

44.3.22附加自动配置和切片

每个切片提供一个或多个@AutoConfigure…​注释,即定义应该作为片的一部分包含的自动配置。可以通过创建自定义来添加其他自动配置。@AutoConfigure…​注释或简单地添加@ImportAutoConfiguration如下面的示例所示:

@RunWith(SpringRunner.class)
@JdbcTest
@ImportAutoConfiguration(IntegrationAutoConfiguration.class)
public class ExampleJdbcTests {

}
[Note]

确保不使用常规@Import注释导入自动配置,因为它们是由SpringBoot以特定方式处理的。

44.3.23用户配置和切片

如果你构造代码以一种明智的方式,你的@SpringBootApplication类是默认使用作为测试的配置。

然后,重要的是不要用特定于特定功能领域的配置设置丢弃应用程序的主类。

假设您正在使用Spring批处理,并依赖于它的自动配置。你可以定义你的@SpringBootApplication详情如下:

@SpringBootApplication
@EnableBatchProcessing
public class SampleApplication { ... }

因为这个类是测试的源配置,所以任何片测试实际上都试图启动Spring批处理,这肯定不是您想要做的。推荐的方法是将特定区域的配置移动到单独的。@Configuration在与应用程序相同的级别初始化,如以下示例所示:

@Configuration
@EnableBatchProcessing
public class BatchConfiguration { ... }
[Note]

根据应用程序的复杂性,您可能有一个@Configuration类为您的自定义或每个域区域中的一个类初始化。后一种方法允许您在测试中启用它,如果有必要,可以使用@Import注释

另一个造成混乱的原因是类路径扫描。假设,当您以合理的方式构造您的代码时,您需要扫描一个额外的包。您的应用程序可能类似以下代码:

@SpringBootApplication
@ComponentScan({ "com.example.app", "org.acme.another" })
public class SampleApplication { ... }

这样做可以有效地覆盖默认组件扫描指令,并附带扫描这两个包的副作用,而不管您选择的是哪个切片。例如,@DataJpaTest似乎突然扫描了应用程序的组件和用户配置。同样,将自定义指令移动到单独的类是解决此问题的好方法。

[Tip]

如果这不是一个选项,您可以创建一个@SpringBootConfiguration在测试的层次结构中的某个位置,这样就可以使用它了。或者,您可以为您的测试指定一个源,这将禁用查找默认测试的行为。

44.3.24使用Spock测试SpringBoot应用程序

如果希望使用Spock测试SpringBoot应用程序,则应该添加对Spock的依赖项spock-spring模块到应用程序的构建。spock-spring将Spring的测试框架集成到Spock中。建议您使用Spock 1.1或更高版本,以受益于对Spock的Spring框架和SpringBoot集成的许多改进。看见Spock的Spring模块文档更多细节。

44.4测试实用程序

测试应用程序时通常有用的一些测试实用程序类打包为spring-boot.

44.4.1 ConfigFileApplicationContextInitiizer

ConfigFileApplicationContextInitializerApplicationContextInitializer可以应用于测试来加载SpringBootapplication.properties档案。当您不需要@SpringBootTest,如以下示例所示:

@ContextConfiguration(classes = Config.class,
	initializers = ConfigFileApplicationContextInitializer.class)
[Note]

使用ConfigFileApplicationContextInitializer单独不提供对@Value("${…​}")注射。它唯一的任务就是确保application.properties文件被加载到Spring的Environment。为@Value支持,您需要另外配置PropertySourcesPlaceholderConfigurer或使用@SpringBootTest,它会自动为你配置一个。

44.4.2 TestPropertyValue

TestPropertyValues允许您快速将属性添加到ConfigurableEnvironmentConfigurableApplicationContext。你可以用key=value字符串如下:

TestPropertyValues.of("org=Spring", "name=Boot").applyTo(env);

44.4.3产出捕获

OutputCapture是JUnitRule你可以用来捕捉System.outSystem.err输出。可以将捕获声明为@Rule然后使用toString()对于断言,如下所示:

import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.test.rule.OutputCapture;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

public class MyTest {

	@Rule
	public OutputCapture capture = new OutputCapture();

	@Test
	public void testName() throws Exception {
		System.out.println("Hello World!");
		assertThat(capture.toString(), containsString("World"));
	}

}

44.4.4 TestRestTemplate

[Tip]

SpringFramework5.0提供了一个新的WebTestClientWebFlux集成测试两者都是WebFlux和mvc端到端测试。它为断言提供了一个流畅的API,不像TestRestTemplate.

TestRestTemplate是春天的另一种方便的选择RestTemplate这在集成测试中很有用。您可以获得一个普通模板或发送基本HTTP身份验证的模板(带有用户名和密码)。在这两种情况下,模板都以一种测试友好的方式运行,不对服务器端错误抛出异常。建议使用ApacheHTTP客户端(4.3.2或更高版本),但不是强制性的。如果你的类路径上有这个,TestRestTemplate通过适当配置客户端进行响应。如果您确实使用了Apache的HTTP客户端,则启用了一些额外的测试友好特性:

  • 没有遵循重定向(因此您可以断言响应位置)。
  • 忽略cookie(因此模板是无状态的)。

TestRestTemplate可以在集成测试中直接实例化,如以下示例所示:

public class MyTest {

	private TestRestTemplate template = new TestRestTemplate();

	@Test
	public void testRequest() throws Exception {
		HttpHeaders headers = this.template.getForEntity(
				"http://myhost.example.com/example", String.class).getHeaders();
		assertThat(headers.getLocation()).hasHost("other.example.com");
	}

}

或者,如果您使用@SpringBootTest注释WebEnvironment.RANDOM_PORTWebEnvironment.DEFINED_PORT,您可以注入一个完全配置的TestRestTemplate然后开始使用它。如果有必要,可以通过RestTemplateBuilder豆子没有指定主机和端口的任何URL都会自动连接到嵌入式服务器,如下面的示例所示:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class SampleWebClientTests {

	@Autowired
	private TestRestTemplate template;

	@Test
	public void testRequest() {
		HttpHeaders headers = this.template.getForEntity("/example", String.class)
				.getHeaders();
		assertThat(headers.getLocation()).hasHost("other.example.com");
	}

	@TestConfiguration
	static class Config {

		@Bean
		public RestTemplateBuilder restTemplateBuilder() {
			return new RestTemplateBuilder().setConnectTimeout(Duration.ofSeconds(1))
					.setReadTimeout(Duration.ofSeconds(1));
		}

	}

}

45.WebSocket

SpringBoot提供了用于嵌入式Tomcat、Jetty和Under拖车的WebSocket自动配置。如果将WAR文件部署到独立容器,SpringBoot假定容器负责WebSocket支持的配置。

Spring框架提供富WebSocket支持对于mvc web应用程序,可以通过spring-boot-starter-websocket模块。

WebSocket支持也可用于反应性Web应用并要求将WebSocketAPI与spring-boot-starter-webflux:

<dependency>
	<groupId>javax.websocket</groupId>
	<artifactId>javax.websocket-api</artifactId>
</dependency>

46.Web服务

Spring Boot提供了Web服务的自动配置,所以您必须做的就是定义Endpoints.

这,这个,那,那个SpringWeb服务特性可以轻松地使用spring-boot-starter-webservices模块。

SimpleWsdl11DefinitionSimpleXsdSchemabean可以分别为WSDL和XSD自动创建。为此,配置它们的位置,如下面的示例所示:

spring.webservices.wsdl-locations=classpath:/wsdl

47.调用Web服务WebServiceTemplate

如果需要从应用程序调用远程Web服务,可以使用WebServiceTemplate班级,等级自WebServiceTemplate实例在使用之前通常需要进行自定义,SpringBoot不提供任何单独的自动配置。WebServiceTemplate豆子但是,它会自动配置一个WebServiceTemplateBuilder,可以用来创建WebServiceTemplate需要时执行实例。

下面的代码显示了一个典型的示例:

@Service
public class MyService {

	private final WebServiceTemplate webServiceTemplate;

	public MyService(WebServiceTemplateBuilder webServiceTemplateBuilder) {
		this.webServiceTemplate = webServiceTemplateBuilder.build();
	}

	public DetailsResp someWsCall(DetailsReq detailsReq) {
		 return (DetailsResp) this.webServiceTemplate.marshalSendAndReceive(detailsReq, new SoapActionCallback(ACTION));

	}

}

默认情况下,WebServiceTemplateBuilder检测合适的基于HTTP的WebServiceMessageSender在类路径上使用可用的HTTP客户端库。您还可以自定义读取和连接超时,如下所示:

@Bean
public WebServiceTemplate webServiceTemplate(WebServiceTemplateBuilder builder) {
	return builder.messageSenders(new HttpWebServiceMessageSenderBuilder()
			.setConnectTimeout(5000).setReadTimeout(2000).build()).build();
}

48.创建自己的自动配置

如果您在开发共享库的公司工作,或者在开源或商业库上工作,您可能需要开发自己的自动配置。自动配置类可以打包在外部JAR中,并且仍然可以通过SpringBoot来获取。

自动配置可以与提供自动配置代码的“初学者”相关联,以及您将与其一起使用的典型库。我们首先介绍构建您自己的自动配置所需的知识,然后继续讨论创建自定义启动程序所需的典型步骤.

[Tip]

演示项目演示如何一步地创建初学者。

48.1理解自动配置bean

在引擎盖下,自动配置是用标准实现的。@Configuration上课。额外@Conditional注释用于限制何时应用自动配置。通常,自动配置类使用@ConditionalOnClass@ConditionalOnMissingBean注释。这确保了自动配置只在找到相关类和尚未声明自己的类时应用。@Configuration.

的源代码。spring-boot-autoconfigure去看@ConfigurationSpring提供的类(请参阅META-INF/spring.factories档案)。

48.2自动配置候选人的位置

弹簧启动检查是否存在META-INF/spring.factories文件在已发布的JAR中。文件应将配置类列在EnableAutoConfiguration键,如以下示例所示:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration

您可以使用@AutoConfigureAfter@AutoConfigureBefore如果您的配置需要按照特定的顺序应用,则进行注释。例如,如果您提供了特定于web的配置,则您的类可能需要在WebMvcAutoConfiguration.

如果您想订购某些不应该彼此直接了解的自动配置,也可以使用@AutoConfigureOrder。该注释具有与常规注释相同的语义。@Order注释,但为自动配置类提供了专用订单。

[Note]

自动配置必须以这种方式加载。。确保它们是在特定的包空间中定义的,特别是,它们永远不是组件扫描的目标。

48.3条件注释

您几乎总是希望包含一个或多个@Conditional自动配置类的注释。这,这个,那,那个@ConditionalOnMissingBean注释是一个常见的示例,用于允许开发人员在不满意默认设置的情况下覆盖自动配置。

Spring Boot包括@Conditional注释,您可以通过注释在自己的代码中重用这些注释。@Configuration阶级或个人@Bean方法。这些说明包括:

48.3.1类条件

这,这个,那,那个@ConditionalOnClass@ConditionalOnMissingClass注释允许根据特定类的存在与否包括配置。由于注释元数据是通过ASM,您可以使用value属性来引用真正的类,即使该类可能不会实际出现在正在运行的应用程序类路径中。您还可以使用name属性指定类名时,请使用String价值。

[Tip]

如果你用@ConditionalOnClass@ConditionalOnMissingClass作为元注释的一部分,您必须使用name因为在这种情况下,类是不被处理的。

48.3.2豆子条件

这,这个,那,那个@ConditionalOnBean@ConditionalOnMissingBean注释允许根据是否存在特定bean来包含bean。您可以使用value属性指定bean的类型或name若要按名称指定bean,请执行以下操作。这,这个,那,那个search属性允许您限制ApplicationContext在搜索bean时应考虑的层次结构。

当放置在@Bean方法时,目标类型默认为方法的返回类型,如以下示例所示:

@Configuration
public class MyAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean
	public MyService myService() { ... }

}

在前面的示例中,myService如果没有类型的bean,则将创建bean。MyService已包含在ApplicationContext.

[Tip]

对于添加bean定义的顺序,您需要非常小心,因为这些条件是根据到目前为止处理的内容来计算的。因此,我们建议只使用@ConditionalOnBean@ConditionalOnMissingBean关于自动配置类的注释(因为这些类保证在添加了任何用户定义的bean定义后加载)。

[Note]

@ConditionalOnBean@ConditionalOnMissingBean不要阻止@Configuration类被创建。在类级别使用这些条件与标记包含的每个条件之间的唯一区别@Bean方法的注释是,前者阻止注册@Configuration如果条件不匹配,则作为bean初始化。

48.3.3财产条件

这,这个,那,那个@ConditionalOnProperty注释允许基于SpringEnvironment属性包括配置。使用prefixname属性指定应该检查的属性。默认情况下,存在和不等于false是匹配的。还可以使用havingValuematchIfMissing属性。

48.3.4资源条件

这,这个,那,那个@ConditionalOnResource注释只允许在存在特定资源时包含配置。可以通过使用通常的Spring约定来指定资源,如下面的示例所示:file:/home/user/test.dat.

48.3.5 Web应用条件

这,这个,那,那个@ConditionalOnWebApplication@ConditionalOnNotWebApplication注释允许包含配置,这取决于应用程序是否是“web应用程序”。Web应用程序是使用Spring的任何应用程序WebApplicationContext,定义session范围,或具有StandardServletEnvironment.

48.3.6 Spel表达条件

这,这个,那,那个@ConditionalOnExpression注释允许根据Spel表达式.

48.4测试您的自动配置

自动配置可能受到许多因素的影响:用户配置(@Bean定义和Environment(定制)、条件评估(存在特定库)以及其他。具体而言,每个测试都应该创建一个定义良好的ApplicationContext表示这些自定义的组合。ApplicationContextRunner为实现这一目标提供了一种很好的方法。

ApplicationContextRunner通常定义为测试类的一个字段来收集基本的、通用的配置。下面的示例确保UserServiceAutoConfiguration总是被引用:

private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
		.withConfiguration(AutoConfigurations.of(UserServiceAutoConfiguration.class));
[Tip]

如果必须定义多个自动配置,则不需要对它们的声明排序,因为它们的调用顺序与运行应用程序时的顺序完全相同。

每个测试都可以使用运行程序来表示特定的用例。例如,下面的示例调用一个用户配置(UserConfiguration)并检查自动配置是否正确回退。调用run提供可与Assert4J.

@Test
public void defaultServiceBacksOff() {
	this.contextRunner.withUserConfiguration(UserConfiguration.class)
			.run((context) -> {
				assertThat(context).hasSingleBean(UserService.class);
				assertThat(context.getBean(UserService.class)).isSameAs(
						context.getBean(UserConfiguration.class).myUserService());
			});
}

@Configuration
static class UserConfiguration {

	@Bean
	public UserService myUserService() {
		return new UserService("mine");
	}

}

还可以轻松自定义Environment,如以下示例所示:

@Test
public void serviceNameCanBeConfigured() {
	this.contextRunner.withPropertyValues("user.name=test123").run((context) -> {
		assertThat(context).hasSingleBean(UserService.class);
		assertThat(context.getBean(UserService.class).getName()).isEqualTo("test123");
	});
}

转轮也可用于显示ConditionEvaluationReport。报告可在INFODEBUG水平。下面的示例演示如何使用ConditionEvaluationReportLoggingListener若要在自动配置测试中打印报表,请执行以下操作。

@Test
public void autoConfigTest {
	ConditionEvaluationReportLoggingListener initializer = new ConditionEvaluationReportLoggingListener(
			LogLevel.INFO);
	ApplicationContextRunner contextRunner = new ApplicationContextRunner()
			.withInitializer(initializer).run((context) -> {
					// Do something...
			});
}

48.4.1模拟Web上下文

如果需要测试仅在servlet或反应性web应用程序上下文中操作的自动配置,请使用WebApplicationContextRunnerReactiveWebApplicationContextRunner分别。

48.4.2凌驾于Classpath之上

还可以测试在运行时不存在特定的类和/或包时会发生什么。弹簧启动船FilteredClassLoader这很容易被跑步者使用。在下面的示例中,我们断言如果UserService不存在,则自动配置被正确禁用:

@Test
public void serviceIsIgnoredIfLibraryIsNotPresent() {
	this.contextRunner.withClassLoader(new FilteredClassLoader(UserService.class))
			.run((context) -> assertThat(context).doesNotHaveBean("userService"));
}

48.5创建自己的初学者

库的完整Spring启动程序可能包含以下组件:

  • 这,这个,那,那个autoconfigure模块,其中包含自动配置代码。
  • 这,这个,那,那个starter提供依赖项的autoconfigure模块以及库和任何通常有用的附加依赖项。简而言之,添加启动器应该提供开始使用该库所需的一切。
[Tip]

如果不需要将这两个关注点分开,则可以将自动配置代码和依赖关系管理组合在一个模块中。

48.5.1命名

您应该确保为初学者提供适当的命名空间。不要以spring-boot,即使您使用不同的MavengroupId。我们可能会提供官方支持的东西,您的自动配置在未来。

根据经验,您应该以初学者的名字命名组合模块。例如,假设您正在为“acme”创建一个启动程序,并将其命名为自动配置模块。acme-spring-boot-autoconfigure和启动器acme-spring-boot-starter。如果只有一个模块组合了这两个模块,请命名它。acme-spring-boot-starter.

另外,如果初学者提供配置键,请为它们使用唯一的命名空间。尤其是,不要将键包含在SpringBoot使用的命名空间中(例如servermanagementspring等等)。如果您使用相同的命名空间,我们将来可能会以破坏模块的方式修改这些命名空间。

确保触发元数据生成这样,IDE辅助也可以用于您的密钥。您可能需要查看生成的元数据(META-INF/spring-configuration-metadata.json)以确保您的钥匙有正确的文档记录。

48.5.2 autoconfigure模块

这,这个,那,那个autoconfigure模块包含开始使用库所需的所有内容。它还可能包含配置键定义(如@ConfigurationProperties)和任何可用于进一步自定义组件初始化方式的回调接口。

[Tip]

应该将库的依赖项标记为可选的,以便可以将autoconfigure模块在您的项目中更容易。如果这样做,就不会提供库,默认情况下,SpringBoot会退出。

SpringBoot使用注释处理器来收集元数据文件中自动配置的条件(META-INF/spring-autoconfigure-metadata.properties)如果该文件存在,则用于筛选不匹配的自动配置,这将缩短启动时间。建议在包含自动配置的模块中添加以下依赖项:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-autoconfigure-processor</artifactId>
	<optional>true</optional>
</dependency>

对于Gradle 4.5和更早版本,应该在compileOnly配置,如以下示例所示:

dependencies {
	compileOnly "org.springframework.boot:spring-boot-autoconfigure-processor"
}

对于Gradle 4.6及更高版本,应该在annotationProcessor配置,如以下示例所示:

dependencies {
	annotationProcessor "org.springframework.boot:spring-boot-autoconfigure-processor"
}

48.5.3启动模块

起动机实际上是一个空罐子。它的唯一目的是提供使用库所需的依赖项。你可以把它看作是对开始所需要的东西的一种固执己见的看法。

不要对添加启动程序的项目进行假设。如果您要自动配置的库通常需要其他启动程序,那么也要提到它们。提供一套合适的违约如果可选依赖项的数量很高,则依赖关系可能很困难,因为您应该避免包含对于库的典型使用来说不必要的依赖关系。换句话说,您不应该包括可选的依赖项。

[Note]

无论哪种方式,您的启动程序都必须引用核心SpringBootStart(spring-boot-starter)直接或间接地(也就是说,如果您的初学者依赖另一个启动器,则不需要添加它)。如果一个项目只使用您的自定义启动程序创建,SpringBoot的核心特性将因核心启动器的存在而受到尊重。

49.Kotlin支持

科特林是一种针对jvm(和其他平台)的静态类型语言,它允许编写简洁而优雅的代码,同时提供互操作性使用Java编写的现有库。

SpringBoot通过利用Spring框架、Spring数据和反应堆等其他Spring项目中的支持来提供Kotlin支持。见Spring Framework Kotlin支持文档想了解更多信息。

从SpringBoot和Kotlin开始,最简单的方法就是遵循本综合教程。您可以通过以下方式创建新的kotlin项目start.spring.io。欢迎加入#Spring频道科特林·斯拉克或者用springkotlin标签上堆栈溢出如果你需要支持的话。

49.1所需经费

Spring Boot支持Kotlin 1.2.x。利用Kotlin,org.jetbrains.kotlin:kotlin-stdliborg.jetbrains.kotlin:kotlin-reflect一定在类路径上。这,这个,那,那个kotlin-stdlib变体kotlin-stdlib-jdk7kotlin-stdlib-jdk8也可以使用。

默认情况下,kotlin类是最终类。,您可能希望配置科特林-弹簧插件,以便自动打开Spring注释的类,以便它们可以被代理.

Jackson的Kotlin模块用于序列化/反序列化Kotlin中的JSON数据。当在类路径上找到它时,它会自动注册。如果Jackson和Kotlin存在,则会记录一条警告消息,但Jackson Kotlin模块不存在。

[Tip]

这些依赖项和插件是默认情况下提供的,如果一个引导程序将kotlin项目引导到start.spring.io.

49.2零-安全

Kotlin的主要特征之一是零安全。它处理的是null值,而不是将问题推迟到运行时并遇到NullPointerException。这有助于消除常见的bug来源,而无需支付包装器的费用,例如Optional。Kotlin还允许使用带有可空值的函数构造,如科特林空安全综合指南.

尽管Java不允许在其类型系统中表示空安全性,但是Spring框架、Spring数据和反应堆现在通过工具友好的注释提供了API的空安全性。默认情况下,Kotlin中使用的JavaAPI中的类型被识别为平台类型对此,空检查是放松的。Kotlin对JSR 305注释的支持结合可空性,注释为Kotlin中相关的SpringAPI提供了空安全性。

可以通过添加-Xjsr305具有下列选项的编译器标志:-Xjsr305={strict|warn|ignore}。默认行为与-Xjsr305=warn。这,这个,那,那个strict值需要在从SpringAPI推断的Kotlin类型中被考虑到空安全性,但在使用时应该知道SpringAPI的可空性声明甚至可能在次要版本之间发展,而且将来可能会增加更多的检查)。

[Warning]

泛型类型参数、varargs和数组元素的空性还不支持。看见spr-15942最新的信息。还要注意SpringBoot自己的API是尚未附加说明.

49.3 Kotlin API

49.3.1运行应用程序

Spring Boot提供了一种惯用的方法来运行应用程序runApplication<MyApplication>(*args)如以下示例所示:

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

@SpringBootApplication
class MyApplication

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

这是对SpringApplication.run(MyApplication::class.java, *args)。它还允许定制应用程序,如以下示例所示:

runApplication<MyApplication>(*args) {
	setBannerMode(OFF)
}

49.3.2扩展

科特林扩展提供扩展具有其他功能的现有类的能力。SpringBootKotlinAPI利用这些扩展为现有的API添加新的Kotlin专用便利。

TestRestTemplate扩展,类似于Spring框架为RestOperations在Spring框架中提供。除其他外,扩展可以利用Kotlin具体化的类型参数。

49.4抚养管理

为了避免在类路径上混合不同版本的Kotlin依赖项,提供了以下Kotlin依赖项的依赖关系管理:

  • kotlin-reflect
  • kotlin-runtime
  • kotlin-stdlib
  • kotlin-stdlib-jdk7
  • kotlin-stdlib-jdk8
  • kotlin-stdlib-jre7
  • kotlin-stdlib-jre8

使用Maven,Kotlin版本可以通过kotlin.version属性和插件管理是为kotlin-maven-plugin。使用Gradle,SpringBoot插件自动对齐kotlin.version用Kotlin插件的版本。

49.5 @ConfigurationProperties

@ConfigurationProperties目前只适用于lateinit或可空var属性(建议使用前者),因为由构造函数初始化的不可变类是尚未得到支持.

@ConfigurationProperties("example.kotlin")
class KotlinExampleProperties {

	lateinit var name: String

	lateinit var description: String

	val myService = MyService()

	class MyService {

		lateinit var apiToken: String

		lateinit var uri: URI

	}

}
[Tip]

生成你自己的元数据使用注释处理器,kapt应该配置带着spring-boot-configuration-processor依赖。

49.6测试

虽然可以使用JUnit 4(默认情况下由spring-boot-starter-test)为了测试Kotlin代码,建议使用JUnit 5。JUnit 5使测试类能够实例化一次,并在类的所有测试中重用。这样就可以使用@BeforeAll@AfterAll关于非静态方法的注释,这很适合Kotlin。

若要使用JUnit 5,请排除junit:junit依赖于spring-boot-starter-test,添加JUnit 5依赖项,并相应地配置Maven或Gradle插件。见JUnit 5文件更多细节。你也需要将测试实例生命周期切换到“每类”。.

49.7资源

49.7.1进一步阅读

49.7.2例子

五十接下来要读什么?

如果您想了解本节中讨论的任何类的更多信息,可以查看SpringBootAPI文档或者您可以浏览直接源代码。如果您有特定的问题,请查看如何部分。

如果您对SpringBoot的核心特性感到满意,您可以继续阅读生产准备功能.

第五部分弹簧启动执行器:可生产的特性

SpringBoot包含了许多其他特性,以帮助您在将应用程序推向生产时监视和管理它。您可以选择使用HTTP端点或使用JMX来管理和监视应用程序。审计、健康和度量收集也可以自动应用于应用程序。

51.启用生产准备功能

这,这个,那,那个spring-boot-actuator模块提供了SpringBoot的所有生产准备功能。启用这些特性的最简单方法是将依赖项添加到spring-boot-starter-actuator“Starter”

执行器的定义

执行器是指用于移动或控制某物的机械装置的制造术语。执行器可以从一个小的变化中产生大量的运动。

若要将执行器添加到基于Maven的项目中,请添加以下“初学者”依赖项:

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-actuator</artifactId>
	</dependency>
</dependencies>

对于Gradle,使用以下声明:

dependencies {
	compile("org.springframework.boot:spring-boot-starter-actuator")
}

52.端点

执行器端点允许您监视应用程序并与其交互。SpringBoot包含许多内置端点,并允许您添加自己的端点。例如,health端点提供了基本的应用程序健康信息。

每个端点可以是启用或禁用。这将控制端点是否已创建,其bean是否存在于应用程序上下文中。要远程访问,端点还必须是通过JMX或HTTP公开。大多数应用程序选择HTTP,其中端点的ID以及前缀为/actuator映射到URL。例如,默认情况下,health端点映射到/actuator/health.

有以下与技术无关的端点:

ID描述默认启用

auditevents

公开当前应用程序的审核事件信息。

beans

显示应用程序中所有Springbean的完整列表。

caches

公开可用的缓存。

conditions

显示在配置类和自动配置类上计算的条件以及它们匹配或不匹配的原因。

configprops

显示所有@ConfigurationProperties.

env

公开Spring的属性ConfigurableEnvironment.

flyway

显示已应用的任何天桥数据库迁移。

health

显示应用程序健康信息。

httptrace

显示HTTP跟踪信息(默认情况下,最后100个HTTP请求-响应交换)。

info

显示任意应用程序信息。

integrationgraph

显示Spring集成图。

loggers

显示和修改应用程序中记录器的配置。

liquibase

显示已应用的任何Liquibase数据库迁移。

metrics

显示当前应用程序的“度量”信息。

mappings

显示所有@RequestMapping道路。

scheduledtasks

显示应用程序中的计划任务。

sessions

允许从Spring会话支持的会话存储中检索和删除用户会话。当使用Spring会话对反应性Web应用程序的支持时不可用。

shutdown

让应用程序优雅地关闭。

threaddump

执行线程转储。

如果您的应用程序是Web应用程序(SpringMVC、SpringWebFlux或泽西岛),则可以使用以下附加端点:

ID描述默认启用

heapdump

返回压缩的GZiphprof堆转储文件

jolokia

通过HTTP公开JMX bean(当Jolokia在类路径上时,WebFlux不可用)。

logfile

返回日志文件的内容(如果logging.filelogging.path属性已设置)。支持HTTP的使用Range标题检索日志文件的部分内容。

prometheus

以Prometheus服务器可以刮取的格式公开度量。

要了解更多关于Actuator端点及其请求和响应格式的信息,请参阅单独的API文档(HTMLPDF).

52.1启用端点

默认情况下,除shutdown都启用了。若要配置端点的启用,请使用其management.endpoint.<id>.enabled财产。下面的示例启用shutdown端点:

management.endpoint.shutdown.enabled=true

如果希望启用端点而不是选择退出,请将management.endpoints.enabled-by-default财产false并使用单个端点enabled属性选择返回。下面的示例启用info终结点并禁用所有其他端点:

management.endpoints.enabled-by-default=false
management.endpoint.info.enabled=true
[Note]

禁用的端点将从应用程序上下文中完全删除。如果只想更改公开端点的技术,请使用includeexclude特性相反。

52.2暴露终结点

由于端点可能包含敏感信息,因此应该仔细考虑何时公开它们。下表显示了内置端点的默认公开:

IDJMX万维网

auditevents

beans

conditions

configprops

env

flyway

health

heapdump

N/A

httptrace

info

integrationgraph

jolokia

N/A

logfile

N/A

loggers

liquibase

metrics

mappings

prometheus

N/A

scheduledtasks

sessions

shutdown

threaddump

若要更改公开的端点,请使用下列特定技术includeexclude物业:

财产违约

management.endpoints.jmx.exposure.exclude

 

management.endpoints.jmx.exposure.include

*

management.endpoints.web.exposure.exclude

 

management.endpoints.web.exposure.include

info, health

这,这个,那,那个include属性列出公开的端点的ID。这,这个,那,那个exclude属性列出不应公开的端点的ID。这,这个,那,那个exclude属性优先于include财产。双管齐下includeexclude属性可以配置为端点ID列表。

例如,停止在JMX上公开所有端点,而只公开healthinfo端点,使用以下属性:

management.endpoints.jmx.exposure.include=health,info

*可用于选择所有端点。例如,要通过HTTP公开所有内容,除了envbeans端点,使用以下属性:

management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=env,beans
[Note]

*在YAML中具有特殊意义,因此,如果希望包括(或排除)所有端点,请确保添加引号,如以下示例所示:

management:
	endpoints:
		web:
			exposure:
				include: "*"
[Note]

如果您的应用程序是公开的,我们强烈建议您也保护你的端点.

[Tip]

如果要实现自己的端点公开策略,可以注册EndpointFilter豆子

52.3保护HTTP端点

您应该注意以与任何其他敏感URL相同的方式保护HTTP端点。如果SpringSecurity存在,则使用SpringSecurity的内容协商策略在默认情况下保护端点。如果您希望为HTTP端点配置自定义安全性,例如,只允许具有特定角色的用户访问它们,SpringBoot提供了一些方便RequestMatcher对象,这些对象可以与SpringSecurity组合使用。

典型的Spring安全配置可能如下所示:

@Configuration
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests()
				.anyRequest().hasRole("ENDPOINT_ADMIN")
				.and()
			.httpBasic();
	}

}

前面的示例使用EndpointRequest.toAnyEndpoint()若要将请求与任何端点匹配,然后确保所有请求都具有ENDPOINT_ADMIN角色。其他几种匹配方法也可用于EndpointRequest。请参阅API文档(HTMLPDF)的细节。

如果您在防火墙后部署应用程序,您可能更希望您的所有执行器端点都可以被访问,而不需要身份验证。您可以通过更改management.endpoints.web.exposure.include财产如下:

应用特性。

management.endpoints.web.exposure.include=*

 

此外,如果SpringSecurity存在,则需要添加自定义安全配置,该配置允许对端点进行未经身份验证的访问,如下面的示例所示:

@Configuration
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests()
			.anyRequest().permitAll();
	}

}

52.4配置终结点

端点自动缓存不接受任何参数的读取操作的响应。若要配置端点缓存响应的时间量,请使用其cache.time-to-live财产。下面的示例设置beans端点的缓存为10秒:

应用特性。

management.endpoint.beans.cache.time-to-live=10s

 

[Note]

前缀management.endpoint.<name>用于唯一标识正在配置的终结点。

[Note]

发出经过身份验证的HTTP请求时,Principal被视为端点的输入,因此不会缓存响应。

52.5用于执行器Web端点的超媒体

添加了一个“发现页”,其中包含指向所有端点的链接。“发现页”可在/actuator默认情况下。

配置自定义管理上下文路径时,“发现页”将自动从/actuator管理上下文的根。例如,如果管理上下文路径是/management,则发现页可从/management。当管理上下文路径设置为/,则禁用发现页以防止与其他映射发生冲突的可能性。

52.6 CORS支助

跨源资源共享(CORS)是W3C规范这允许您以灵活的方式指定什么类型的跨域请求被授权。如果使用SpringMVC或SpringWebFlux,则可以配置Actuator的Web端点以支持此类场景。

默认情况下,CORS支持是禁用的,并且仅在management.endpoints.web.cors.allowed-origins属性已设置。以下配置允许GETPOSTexample.com域:

management.endpoints.web.cors.allowed-origins=http://example.com
management.endpoints.web.cors.allowed-methods=GET,POST
[Tip]

看见CorsEndpoint性质有关选项的完整列表。

52.7实现自定义端点

如果添加@Bean带注释@Endpoint,任何带有注释的方法@ReadOperation@WriteOperation,或@DeleteOperation自动在JMX上公开,在Web应用程序中也通过HTTP公开。可以使用泽西、SpringMVC或SpringWebFlux通过HTTP公开端点。

还可以通过以下方法编写特定于技术的端点:@JmxEndpoint@WebEndpoint。这些端点仅限于各自的技术。例如@WebEndpoint只能通过HTTP而不是通过JMX公开。

可以通过以下方法编写特定于技术的扩展:@EndpointWebExtension@EndpointJmxExtension。这些注释允许您提供特定于技术的操作来增强现有端点。

最后,如果需要访问特定于web框架的功能,则可以实现servlet或Spring。@Controller@RestController端点的代价是它们无法通过JMX或使用不同的Web框架获得。

52.7.1接收输入

端点上的操作通过其参数接收输入。当通过Web公开时,这些参数的值将从URL的查询参数和JSON请求体中获取。当通过JMX公开时,参数将映射到MBean操作的参数。默认情况下需要参数。它们可以通过用@org.springframework.lang.Nullable.

JSON请求体中的每个根属性都可以映射到端点的一个参数。考虑以下JSON请求体:

{
	"name": "test",
	"counter": 42
}

这可用于调用一个写操作,该操作将String nameint counter参数。

[Tip]

因为端点与技术无关,所以只能在方法签名中指定简单类型。特别是声明具有自定义类型的单个参数,该类型定义namecounter不支持属性。

[Note]

为了允许将输入映射到操作方法的参数,实现端点的Java代码应该用-parameters,实现端点的kotlin代码应该用-java-parameters。如果使用SpringBoot的Gradle插件或使用Maven和spring-boot-starter-parent.

输入类型转换

如果有必要,传递给端点操作方法的参数将自动转换为所需的类型。在调用操作方法之前,通过JMX或HTTP请求接收的输入将使用ApplicationConversionService.

52.7.2自定义Web终结点

上的操作。@Endpoint@WebEndpoint,或@EndpointWebExtension使用泽西、SpringMVC或SpringWebFlux通过HTTP自动公开。

Web端点请求谓词

对于Web公开的端点上的每个操作,都会自动生成请求谓词.

路径

谓词的路径由端点的ID和Web暴露的端点的基本路径决定。默认的基本路径是/actuator。例如,具有ID的端点sessions将使用/actuator/sessions作为谓词中的路径。

通过注释操作方法的一个或多个参数,可以进一步定制路径。@Selector。这样的参数作为路径变量添加到路径谓词中。当调用端点操作时,变量的值将传递给操作方法。

http方法

谓词的HTTP方法由操作类型确定,如下表所示:

操作http方法

@ReadOperation

GET

@WriteOperation

POST

@DeleteOperation

DELETE

消费

为了@WriteOperation(httpPOST),它使用请求体,谓词的USEES子句是application/vnd.spring-boot.actuator.v2+json, application/json。对于所有其他操作,USPES子句为空。

谓词的Products子句可以由produces属性的@DeleteOperation@ReadOperation,和@WriteOperation注释。属性是可选的。如果不使用它,则会自动确定Products子句。

如果操作方法返回voidVoidProducts子句为空。如果操作方法返回org.springframework.core.io.Resource,产生子句是application/octet-stream。对于所有其他操作,Products子句为application/vnd.spring-boot.actuator.v2+json, application/json.

Web端点响应状态

端点操作的默认响应状态取决于操作类型(读、写或删除)以及操作返回的内容(如果有的话)。

@ReadOperation返回一个值,响应状态为200(OK)。如果不返回值,则响应状态为404(未找到)。

如果@WriteOperation@DeleteOperation返回一个值,响应状态为200(OK)。如果不返回值,则响应状态为204(无内容)。

如果在没有必需参数的情况下调用操作,或者使用不能转换为所需类型的参数调用操作方法,则响应状态将为400(坏请求)。

Web端点范围请求

HTTP范围请求可用于请求HTTP资源的一部分。当使用SpringMVC或SpringWebFlux时,返回org.springframework.core.io.Resource自动支持范围请求。

[Note]

使用泽西时不支持范围请求。

Web端点安全

web端点或特定于web的端点扩展上的操作可以接收当前java.security.Principalorg.springframework.boot.actuate.endpoint.SecurityContext作为方法参数。前者通常与@Nullable为经过身份验证的用户和未经身份验证的用户提供不同的行为。后者通常用于使用其isUserInRole(String)方法。

52.7.3 servlet端点

Servlet通过实现带注释的类,可以将其公开为端点。@ServletEndpoint也实现了Supplier<EndpointServlet>。Servlet端点提供与servlet容器更深层次的集成,但代价是可移植性。它们用于公开现有的Servlet作为终点。对于新的端点,@Endpoint@WebEndpoint只要有可能,应该首选注释。

52.7.4主计长端点

@ControllerEndpoint@RestControllerEndpoint可以用于实现仅由SpringMVC或SpringWebFlux公开的端点。使用SpringMVC和SpringWebFlux的标准注释映射方法,如@RequestMapping@GetMapping,将端点的ID用作路径的前缀。控制器端点提供与Spring的Web框架更深层次的集成,但代价是可移植性。这,这个,那,那个@Endpoint@WebEndpoint只要有可能,应该首选注释。

52.8卫生信息

您可以使用健康信息来检查正在运行的应用程序的状态。当生产系统发生故障时,监控软件经常使用它来警告某人。公开的信息health端点依赖于management.endpoint.health.show-details属性,可以使用以下值之一配置该属性:

名字,姓名描述

never

细节永远不会显示。

when-authorized

详细信息只显示给授权用户。授权角色可以使用management.endpoint.health.roles.

always

详细信息显示给所有用户。

默认值是never。当用户处于端点的一个或多个角色时,他们被认为是被授权的。如果端点没有配置角色(默认),则所有经过身份验证的用户都被视为已授权。可以使用management.endpoint.health.roles财产。

[Note]

如果您已经保护了您的应用程序并希望使用always,您的安全配置必须允许通过身份验证和未经身份验证的用户访问运行状态端点。

健康信息是从 HealthIndicatorRegistry(默认情况下,所有HealthIndicator中定义的实例。ApplicationContext。Spring Boot包括许多自动配置的HealthIndicators你也可以自己写。默认情况下,最终系统状态由HealthAggregator对每个状态进行排序。HealthIndicator基于一个有序的状态列表。排序列表中的第一个状态用作总体健康状态。如果没有HealthIndicator返回已知的状态。HealthAggregator..UNKNOWN使用状态。

[Tip]

这,这个,那,那个HealthIndicatorRegistry可用于在运行时注册和注销运行状态指示符。

52.8.1自动配置的HealthIndicator

以下内容HealthIndicators在适当情况下由SpringBoot自动配置:

名字,姓名描述

CassandraHealthIndicator

检查卡桑德拉数据库是否启动。

DiskSpaceHealthIndicator

检查低磁盘空间。

DataSourceHealthIndicator

检查连接到DataSource是可以得到的。

ElasticsearchHealthIndicator

检查Elasticearch集群是否已启动。

InfluxDbHealthIndicator

检查InfluxDB服务器是否已启动。

JmsHealthIndicator

检查JMS代理是否已运行。

MailHealthIndicator

检查邮件服务器是否已启动。

MongoHealthIndicator

检查蒙戈数据库是否打开。

Neo4jHealthIndicator

检查Neo4j服务器是否已启动。

RabbitHealthIndicator

检查兔子服务器是否启动。

RedisHealthIndicator

检查Redis服务器是否已启动。

SolrHealthIndicator

检查Solr服务器是否已启动。

[Tip]

可以通过设置management.health.defaults.enabled财产。

52.8.2书写自定义健康指示器

若要提供自定义健康信息,可以注册实现HealthIndicator接口。您需要提供health()方法并返回Health回应。这,这个,那,那个Health响应应该包括状态,并且可以选择包括要显示的其他详细信息。下面的代码显示了一个示例HealthIndicator执行情况:

import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;

@Component
public class MyHealthIndicator implements HealthIndicator {

	@Override
	public Health health() {
		int errorCode = check(); // perform some specific health check
		if (errorCode != 0) {
			return Health.down().withDetail("Error Code", errorCode).build();
		}
		return Health.up().build();
	}

}
[Note]

给定值的标识符。HealthIndicator是没有HealthIndicator后缀,如果它存在的话。在前面的示例中,健康信息可在名为my.

除了SpringBoot的预定义Status类型,也有可能Health返回自定义Status表示新的系统状态的。在这种情况下,HealthAggregator接口,或者使用management.health.status.order配置属性。

例如,假设一个新的Status有代码FATAL正在用在你的HealthIndicator实现。若要配置严重程度顺序,请将以下属性添加到应用程序属性中:

management.health.status.order=FATAL, DOWN, OUT_OF_SERVICE, UNKNOWN, UP

响应中的HTTP状态代码反映了总体健康状况(例如,UP地图到200,同时OUT_OF_SERVICEDOWN地图到503)。如果通过HTTP访问健康端点,还可能希望注册自定义状态映射。例如,以下属性映射FATAL至503(服务不可用):

management.health.status.http-mapping.FATAL=503
[Tip]

如果您需要更多的控制,您可以定义自己的HealthStatusHttpMapper豆子

下表显示了内置状态的默认状态映射:

地位映射

向下

服务不可用(503)

停用

服务不可用(503)

向上

默认情况下不进行映射,因此http状态为200。

未知数

默认情况下不进行映射,因此http状态为200。

52.8.3反应性健康指标

对于反应性应用程序,如使用SpringWebFlux的应用程序,ReactiveHealthIndicator提供非阻塞契约,以获得应用程序健康。类似于传统HealthIndicator的内容收集健康信息。 ReactiveHealthIndicatorRegistry(默认情况下,所有HealthIndicator ReactiveHealthIndicator中定义的实例。ApplicationContext。正规化HealthIndicator在弹性调度程序上执行不针对反应性API的检查。

[Tip]

在反应性应用程序中,ReactiveHealthIndicatorRegistry可用于在运行时注册和注销运行状态指示符。

若要从反应性API中提供自定义健康信息,可以注册实现ReactiveHealthIndicator接口。下面的代码显示了一个示例ReactiveHealthIndicator执行情况:

@Component
public class MyReactiveHealthIndicator implements ReactiveHealthIndicator {

	@Override
	public Mono<Health> health() {
		return doHealthCheck() //perform some specific health check that returns a Mono<Health>
			.onErrorResume(ex -> Mono.just(new Health.Builder().down(ex).build())));
	}

}
[Tip]

若要自动处理错误,请考虑从AbstractReactiveHealthIndicator.

52.8.4自动配置的ReactiveHealthIndicator

以下内容ReactiveHealthIndicators在适当情况下由SpringBoot自动配置:

名字,姓名描述

CassandraReactiveHealthIndicator

检查卡桑德拉数据库是否启动。

MongoReactiveHealthIndicator

检查蒙戈数据库是否打开。

RedisReactiveHealthIndicator

检查Redis服务器是否已启动。

[Tip]

如有必要,应采用反应性指标取代常规指标。还有,任何HealthIndicator未显式处理的将自动包装。

52.9申请资料

应用程序信息公开从所有InfoContributor中定义的beanApplicationContext。Spring Boot包括许多自动配置的InfoContributor豆子,你可以自己写。

52.9.1自动配置的InfoContributor

以下内容InfoContributor在适当的情况下,Spring Boot会自动配置bean:

名字,姓名描述

EnvironmentInfoContributor

公开Environmentinfo钥匙

GitInfoContributor

如果git.properties文件是可用的。

BuildInfoContributor

如果META-INF/build-info.properties文件是可用的。

[Tip]

可以通过设置management.info.defaults.enabled财产。

52.9.2自定义应用程序信息

您可以自定义由info通过设置端点info.*弹簧特性。全Environment属性下的属性。info键会自动暴露。例如,可以将下列设置添加到application.properties档案:

info.app.encoding=UTF-8
info.app.java.source=1.8
info.app.java.target=1.8
[Tip]

与其硬编码这些值,您还可以在构建时展开info属性.

假设您使用了Maven,您可以重写前面的示例,如下所示:

info.app.encoding=@project.build.sourceEncoding@
info.app.java.source=@java.version@
info.app.java.target=@java.version@

52.9.3 Git提交信息

的另一个有用特性info端点是它发布有关git构建项目时的源代码存储库。如果GitPropertiesbean可用,则git.branchgit.commit.id,和git.commit.time属性暴露了。

[Tip]

GitPropertiesbean是自动配置的,如果git.properties文件在类路径的根目录下可用。见“生成git信息“更多细节。

如果要显示完整的git信息(即git.properties),使用management.info.git.mode财产如下:

management.info.git.mode=full

52.9.4构建信息

如果BuildPropertiesbean可用,则info端点还可以发布有关生成的信息。如果META-INF/build-info.properties文件可在类路径中使用。

[Tip]

Maven和Gradle插件都可以生成该文件。见“生成信息“更多细节。

52.9.5编写自定义信息贡献者

若要提供自定义应用程序信息,可以注册实现InfoContributor接口。

下面的示例提供了一个example具有单个值的条目:

import java.util.Collections;

import org.springframework.boot.actuate.info.Info;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.stereotype.Component;

@Component
public class ExampleInfoContributor implements InfoContributor {

	@Override
	public void contribute(Info.Builder builder) {
		builder.withDetail("example",
				Collections.singletonMap("key", "value"));
	}

}

如果你到达info端点,您应该会看到一个包含以下附加条目的响应:

{
	"example": {
		"key" : "value"
	}
}

53.HTTP上的监控与管理

如果您正在开发一个Web应用程序,SpringBootActuator会自动配置所有启用的端点,以便通过HTTP公开。默认约定是使用id的端点的前缀为/actuator作为URL路径。例如health暴露为/actuator/health。提示:SpringMVC、SpringWebFlux和泽西支持执行机构。

53.1自定义管理端点路径

有时,自定义管理端点的前缀是有用的。例如,您的应用程序可能已经使用了/actuator为了另一个目的。您可以使用management.endpoints.web.base-path属性更改管理端点的前缀,如以下示例所示:

management.endpoints.web.base-path=/manage

前文application.properties示例将端点更改为/actuator/{id}/manage/{id}(例如,/manage/info).

[Note]

除非已将管理端口配置为使用不同的HTTP端口公开端点management.endpoints.web.base-path相对于server.servlet.context-path。如果management.server.port配置,management.endpoints.web.base-path相对于management.server.servlet.context-path.

如果要将端点映射到其他路径,则可以使用management.endpoints.web.path-mapping财产。

下面的示例映射/actuator/health/healthcheck:

应用特性。

management.endpoints.web.base-path=/
management.endpoints.web.path-mapping.health=healthcheck

 

53.2自定义管理服务器端口

使用默认的HTTP端口公开管理端点是基于云的部署的明智选择。但是,如果应用程序在您自己的数据中心内运行,您可能更愿意使用不同的HTTP端口来公开端点。

您可以设置management.server.port属性更改HTTP端口,如以下示例所示:

management.server.port=8081

53.3配置特定于管理的SSL

当配置为使用自定义端口时,管理服务器也可以使用它自己的ssl通过以下各种配置management.server.ssl.*财产。例如,这样做可以让管理服务器在HTTP上可用,而主应用程序则使用HTTPS,如以下属性设置所示:

server.port=8443
server.ssl.enabled=true
server.ssl.key-store=classpath:store.jks
server.ssl.key-password=secret
management.server.port=8080
management.server.ssl.enabled=false

或者,主服务器和管理服务器都可以使用SSL,但可以使用不同的密钥存储,如下所示:

server.port=8443
server.ssl.enabled=true
server.ssl.key-store=classpath:main.jks
server.ssl.key-password=secret
management.server.port=8080
management.server.ssl.enabled=true
management.server.ssl.key-store=classpath:management.jks
management.server.ssl.key-password=secret

53.4自定义管理服务器地址

属性来自定义管理端点可用的地址。management.server.address财产。如果您只想在内部或面向操作的网络上侦听,或者只想侦听来自localhost.

[Note]

只有当端口与主服务器端口不同时,才能侦听不同的地址。

下面的示例application.properties不允许远程管理连接:

management.server.port=8081
management.server.address=127.0.0.1

53.5禁用HTTP端点

如果不希望通过HTTP公开端点,可以将管理端口设置为-1,如以下示例所示:

management.server.port=-1

这可以使用management.endpoints.web.exposure.exclude属性,如下面的示例所示:

management.endpoints.web.exposure.exclude=*

54.对JMX的监测和管理

Java管理扩展(JMX)提供了监视和管理应用程序的标准机制。默认情况下,SpringBoot将管理端点作为JMX MBean公开在org.springframework.boot域。

54.1定制MBean名称

MBean的名称通常是从id端点。例如,health端点公开为org.springframework.boot:type=Endpoint,name=Health.

如果应用程序包含多个SpringApplicationContext,你可能会发现名字冲突。若要解决此问题,可以将spring.jmx.unique-names财产true所以MBean名称总是唯一的。

您还可以自定义暴露端点的JMX域。下面的设置显示了在application.properties:

spring.jmx.unique-names=true
management.endpoints.jmx.domain=com.example.myapp

54.2禁用JMX端点

如果不希望在JMX上公开端点,则可以将management.endpoints.jmx.exposure.exclude财产*,如以下示例所示:

management.endpoints.jmx.exposure.exclude=*

54.3通过HTTP为JMX使用Jolokia

Jolokia是一种JMX-HTTP桥,它提供了一种访问JMXbean的替代方法。若要使用Jolokia,请将依赖项包含到org.jolokia:jolokia-core。例如,对于Maven,可以添加以下依赖项:

<dependency>
	<groupId>org.jolokia</groupId>
	<artifactId>jolokia-core</artifactId>
</dependency>

然后,可以通过添加jolokia*management.endpoints.web.exposure.include财产。然后,您可以通过以下方式访问它:/actuator/jolokia在您的管理HTTP服务器上。

54.3.1定制Jolokia

Jolokia有许多设置,传统上通过设置servlet参数来配置这些设置。使用SpringBoot,您可以使用application.properties档案。若要这样做,请在参数前面加上management.endpoint.jolokia.config.,如以下示例所示:

management.endpoint.jolokia.config.debug=true

54.3.2禁用Jolokia

如果使用Jolokia但不希望SpringBoot配置它,请将management.endpoint.jolokia.enabled财产false,如下:

management.endpoint.jolokia.enabled=false

55.伐木工

SpringBootActuator包括在运行时查看和配置应用程序日志级别的能力。您可以查看整个列表或单个记录器的配置,该配置由显式配置的日志级别以及日志框架提供的有效日志级别组成。这些级别可以是:

  • TRACE
  • DEBUG
  • INFO
  • WARN
  • ERROR
  • FATAL
  • OFF
  • null

null指示没有显式配置。

55.1配置记录器

若要配置给定的记录器,POST资源URI的部分实体,如以下示例所示:

{
	"configuredLevel": "DEBUG"
}
[Tip]

若要“重置”记录器的特定级别(并使用默认配置),可以传递null就像configuredLevel.

56.度量标准

SpringBoot执行器提供依赖关系管理和自动配置千分尺,支持多个监视系统的应用程序度量外观,包括:

[Tip]

要了解更多关于千分尺功能的信息,请参考其参考文献,特别是概念部分.

56.1开始

Spring Boot自动配置复合MeterRegistry并为它在类路径上找到的每个受支持的实现向复合添加一个注册表。依赖于micrometer-registry-{system}在运行时,类路径足以让SpringBoot配置注册表。

大多数注册中心都有共同的特性。例如,即使千分尺注册表实现在类路径上,也可以禁用特定的注册表。例如,要禁用Datadog:

management.metrics.export.datadog.enabled=false

Spring Boot还会将任何自动配置的注册表添加到Metrics除非您显式地告诉它不要:

management.metrics.use-global-registry=false

您可以注册任意数量的MeterRegistryCustomizerbean以进一步配置注册表,例如在向注册表注册任何表之前应用公共标记:

@Bean
MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
	return registry -> registry.config().commonTags("region", "us-east-1");
}

可以将自定义应用于特定的注册表实现,方法是更具体地说明泛型类型:

@Bean
MeterRegistryCustomizer<GraphiteMeterRegistry> graphiteMetricsNamingConvention() {
	return registry -> registry.config().namingConvention(MY_CUSTOM_CONVENTION);
}

有了这个设置,你就可以注入MeterRegistry在组件和注册度量中:

@Component
public class SampleBean {

	private final Counter counter;

	public SampleBean(MeterRegistry registry) {
		this.counter = registry.counter("received.messages");
	}

	public void handleMessage(String message) {
		this.counter.increment();
		// handle message implementation
	}

}

春靴配置内置的工具。(即:MeterBinder实现),您可以通过配置或专用注释标记进行控制。

56.2支持的监测系统

56.2.1 Atlas

默认情况下,度量被导出到阿特拉斯在你的本地机器上运行。的位置Atlas服务器可以使用以下方法提供使用:

management.metrics.export.atlas.uri=http://atlas.example.com:7101/api/v1/publish

56.2.2 Datadog

Datadog注册表将度量推送到datadoghq周期性的。将指标导出到Datadog,必须提供您的API密钥:

management.metrics.export.datadog.api-key=YOUR_KEY

还可以更改将度量发送到Datadog的间隔:

management.metrics.export.datadog.step=30s

56.2.3 Dynatraces

DynatraceRegistry周期性地将度量推送到配置的URI。将指标导出到戴纳通,必须提供API令牌、设备ID和URI:

management.metrics.export.dynatrace.api-token=YOUR_TOKEN
management.metrics.export.dynatrace.device-id=YOUR_DEVICE_ID
management.metrics.export.dynatrace.uri=YOUR_URI

您还可以更改将度量发送到Dynatraces的时间间隔:

management.metrics.export.dynatrace.step=30s

56.2.4弹性

默认情况下,度量被导出到弹性在你的本地机器上运行。可以使用以下属性提供要使用的弹性服务器的位置:

management.metrics.export.elastic.hosts=http://elastic.example.com:8086

56.2.5神经节

默认情况下,度量被导出到神经节在你的本地机器上运行。这,这个,那,那个Ganglia服务器可以使用以下方法提供要使用的主机和端口:

management.metrics.export.ganglia.host=ganglia.example.com
management.metrics.export.ganglia.port=9649

56.2.6石墨

默认情况下,度量被导出到石墨在你的本地机器上运行。这,这个,那,那个石墨服务器可以使用以下方法提供要使用的主机和端口:

management.metrics.export.graphite.host=graphite.example.com
management.metrics.export.graphite.port=9004

千分尺提供缺省值HierarchicalNameMapper它控制着维度米id的大小。映射到平面层次结构名称.

[Tip]

要控制这种行为,请定义GraphiteMeterRegistry提供你自己的HierarchicalNameMapper。自动配置的GraphiteConfigClock除非定义了自己的bean,否则将提供bean:

@Bean
public GraphiteMeterRegistry graphiteMeterRegistry(GraphiteConfig config, Clock clock) {
	return new GraphiteMeterRegistry(config, clock, MY_HIERARCHICAL_MAPPER);
}

56.2.7流入

默认情况下,度量被导出到流入在你的本地机器上运行。的位置流入服务器可以使用以下方法提供使用:

management.metrics.export.influx.uri=http://influx.example.com:8086

56.2.8 JMX

千分尺提供了一个分层映射到JMX,主要是一种廉价的、可移植的本地查看度量的方法。默认情况下,度量被导出到metricsJMX域可以使用以下方法提供要使用的域:

management.metrics.export.jmx.domain=com.example.app.metrics

千分尺提供缺省值HierarchicalNameMapper它控制着维度米id的大小。映射到平面层次结构名称.

[Tip]

要控制这种行为,请定义JmxMeterRegistry提供你自己的HierarchicalNameMapper。自动配置的JmxConfigClock除非定义了自己的bean,否则将提供bean:

@Bean
public JmxMeterRegistry jmxMeterRegistry(JmxConfig config, Clock clock) {
	return new JmxMeterRegistry(config, clock, MY_HIERARCHICAL_MAPPER);
}

56.2.9新文物

新的遗留注册中心将度量推送到新文物周期性的。将指标导出到新文物,必须提供您的API密钥和帐户ID:

management.metrics.export.newrelic.api-key=YOUR_KEY
management.metrics.export.newrelic.account-id=YOUR_ACCOUNT_ID

您还可以更改将度量发送到NewRelic的时间间隔:

management.metrics.export.newrelic.step=30s

56.2.10普罗米修斯

普罗米修斯期望对单个应用实例进行抓取或轮询,以获得度量标准。Spring Boot提供了一个执行器端点,可在/actuator/prometheus提出[医]擦伤普罗米修斯(Prometheus)适当的格式。

[Tip]

默认情况下,端点不可用,必须公开,请参见暴露端点更多细节。

下面是一个例子scrape_config添加到prometheus.yml:

scrape_configs:
  - job_name: 'spring'
	metrics_path: '/actuator/prometheus'
	static_configs:
	  - targets: ['HOST:PORT']

56.2.11 SignalFx

SignalFx注册表将度量推送到SignalFx周期性的。将指标导出到SignalFx,必须提供访问令牌:

management.metrics.export.signalfx.access-token=YOUR_ACCESS_TOKEN

还可以更改将度量发送到SignalFx的间隔:

management.metrics.export.signalfx.step=30s

56.2.12简单

千分尺附带一个简单的内存后端,如果没有配置其他注册表,它将自动用作后备。这允许您查看在度量端点.

当您使用其他可用后端时,内存中的后端会立即禁用自己。您还可以显式禁用它:

management.metrics.export.simple.enabled=false

56.2.13国家统计d

StatsD注册中心热切地将度量通过UDP推送给StatsD代理。默认情况下,度量被导出到StatsD探员在你的本地机器上运行。可以使用以下方法提供要使用的StatsD代理主机和端口:

management.metrics.export.statsd.host=statsd.example.com
management.metrics.export.statsd.port=9125

还可以将StatsD行协议更改为使用(默认为Datadog):

management.metrics.export.statsd.flavor=etsy

56.2.14波前

波前注册表将度量推送到波前周期性的。如果要将指标导出到波前直接地,必须提供您的API令牌:

management.metrics.export.wavefront.api-token=YOUR_API_TOKEN

或者,您可以使用在您的环境中设置的Wavefront Sideecar或内部代理将度量数据转发到Wavefront API主机:

management.metrics.export.wavefront.uri=proxy://localhost:2878
[Tip]

如果将度量发布到Wavefront代理(如文献),主机必须位于proxy://HOST:PORT格式。

还可以更改将度量发送到Wavefront的间隔:

management.metrics.export.wavefront.step=30s

56.3支助计量

SpringBoot在适用时注册了以下核心指标:

  • JVM指标,报告以下指标的使用情况:

    • 各种内存和缓冲池
    • 与垃圾收集有关的统计数据
    • 线程利用率
    • 装入/卸载的类数
  • CPU度量
  • 文件描述符度量
  • 卡夫卡消费者衡量标准
  • Log4j2度量:记录每个级别记录到Log4j2的事件数。
  • Logback度量:记录在每个级别登录到Logback的事件数
  • 正常运行时间度量:报告正常运行时间的度量和表示应用程序的绝对启动时间的固定度量
  • Tomcat度量
  • 弹簧集成度量标准

56.3.1 SpringMVC度量

自动配置支持SpringMVC处理的请求的检测。什么时候management.metrics.web.server.auto-time-requeststrue,此工具用于所有请求。或者,当设置为false,您可以通过添加@Timed请求处理方法:

@RestController
@Timed 
public class MyController {

	@GetMapping("/api/people")
	@Timed(extraTags = { "region", "us-east-1" }) @Timed(value = "all.people", longTask = true) 
	public List<Person> listPeople() { ... }

}

1

一个控制器类,用于在控制器中的每个请求处理程序上启用时间。

2

为单个端点启用的一种方法。如果类中有它,这是不必要的,但是可以用于进一步自定义这个特定端点的定时器。

3

一种方法longTask = true若要为该方法启用长任务定时器,请执行以下操作。长任务计时器需要单独的度量名称,可以用短任务计时器堆叠。

默认情况下,使用名称生成度量,http.server.requests。可以通过设置management.metrics.web.server.requests-metric-name财产。

默认情况下,与SpringMVC相关的指标被标记为以下信息:

标签描述

exception

处理请求时抛出的任何异常的简单类名。

method

请求的方法(例如,GETPOST)

outcome

请求的结果基于响应的状态代码。1XX是INFORMATIONAL,2xx是SUCCESS,3xx是REDIRECTION,4xxCLIENT_ERROR,而5xx是SERVER_ERROR

status

响应的HTTP状态代码(例如,200500)

uri

如果可能的话,在变量替换之前请求的URI模板(例如,/api/person/{id})

若要自定义标记,请提供@Bean实现WebMvcTagsProvider.

56.3.2 SpringWebFlux度量

自动配置支持由WebFlux控制器和功能处理程序处理的所有请求的检测.

默认情况下,使用名称生成度量。http.server.requests。可以通过设置management.metrics.web.server.requests-metric-name财产。

默认情况下,与WebFlux相关的度量使用以下信息进行标记:

标签描述

exception

处理请求时抛出的任何异常的简单类名。

method

请求的方法(例如,GETPOST)

outcome

请求的结果基于响应的状态代码。1XX是INFORMATIONAL,2xx是SUCCESS,3xx是REDIRECTION,4xxCLIENT_ERROR,而5xx是SERVER_ERROR

status

响应的HTTP状态代码(例如,200500)

uri

如果可能的话,在变量替换之前请求的URI模板(例如,/api/person/{id})

若要自定义标记,请提供@Bean实现WebFluxTagsProvider.

56.3.3 HTTP客户端度量

弹簧启动执行器管理两个RestTemplateWebClient。为此,必须注入一个自动配置的构建器,并使用它创建实例:

  • RestTemplateBuilderRestTemplate
  • WebClient.BuilderWebClient

还可以手动应用负责此工具的自定义器,即MetricsRestTemplateCustomizerMetricsWebClientCustomizer.

默认情况下,使用名称生成度量,http.client.requests。可以通过设置management.metrics.web.client.requests-metric-name财产。

默认情况下,工具化客户端生成的度量将使用以下信息进行标记:

  • method,请求的方法(例如,GETPOST).
  • uri,在变量替换之前请求的URI模板(如果可能的话)(例如,/api/person/{id}).
  • status,响应的HTTP状态代码(例如,200500).
  • clientNameURI的主机部分。

若要自定义标记,并根据客户端的选择,可以提供@Bean实现RestTemplateExchangeTagsProviderWebClientExchangeTagsProvider。中有一些方便的静态函数。RestTemplateExchangeTagsWebClientExchangeTags.

56.3.4缓存度量

自动配置启用所有可用的仪表。Caches在启动时以指标为前缀cache。对于一组基本的度量,缓存检测是标准化的。此外,缓存特定的指标也是可用的.

支持以下缓存库:

  • 咖啡因
  • EhCache 2
  • 哈泽尔卡斯特
  • 任何符合JCache(JSR-107)的实现

指标由缓存的名称和CacheManager它是从bean名称派生的。

[Note]

只有启动时可用的缓存才绑定到注册表。对于在启动阶段后动态创建或以编程方式创建的缓存,需要显式注册.一个CacheMetricsRegistrarbean可供使用,以使该过程更容易。

56.3.5数据源度量

自动配置启用所有可用的仪表。DataSource对象具有名为jdbc。数据源检测结果是表示池中当前活动的、最大允许的和最小允许的连接的量规。这些量规中的每一个都有一个前缀为jdbc.

度量标准也被标记为DataSource根据bean名称计算。

[Tip]

默认情况下,SpringBoot为所有受支持的数据源提供元数据;您可以添加其他DataSourcePoolMetadataProviderbean,如果不支持最喜欢的数据源的话。看见DataSourcePoolMetadataProvidersConfiguration举个例子。

另外,Hikari特有的度量也公开了一个hikaricp前缀。每个度量都由池的名称标记(可以用spring.datasource.name).

56.3.6冬眠度量

自动配置支持所有可用Hibernate的检测。EntityManagerFactory实例,这些实例使用名为hibernate.

度量标准也被标记为EntityManagerFactory它是从bean名称派生的。

要启用统计信息,标准的jpa属性hibernate.generate_statistics必须设置为true。您可以在自动配置的EntityManagerFactory如以下示例所示:

spring.jpa.properties.hibernate.generate_statistics=true

56.3.7兔MQ计量

自动配置将启用所有可用的RabbitMQ连接工厂的仪表,其度量名为rabbitmq.

56.4注册自定义指标

若要注册自定义度量,请插入MeterRegistry在您的组件中,如下面的示例所示:

class Dictionary {

	private final List<String> words = new CopyOnWriteArrayList<>();

	Dictionary(MeterRegistry registry) {
		registry.gaugeCollectionSize("dictionary.size", Tags.empty(), this.words);
	}

	// …

}

如果您发现在组件或应用程序之间反复测试一组度量,则可以将此套件封装在MeterBinder执行。默认情况下,所有MeterBinderbean将自动绑定到Spring管理的MeterRegistry.

56.5定制个人指标

如果需要将自定义应用于特定的Meter实例可以使用io.micrometer.core.instrument.config.MeterFilter接口。默认情况下,所有MeterFilter豆子将自动应用于千分尺。MeterRegistry.Config.

例如,如果要重命名mytag.region标记到mytag.area开始的所有仪表IDcom.example,您可以这样做:

@Bean
public MeterFilter renameRegionTagMeterFilter() {
	return MeterFilter.renameTag("com.example", "mytag.region", "mytag.area");
}

56.5.1通用标签

常见的标签通常用于操作环境中的维度向下钻取,如主机、实例、区域、堆栈等。公用标记应用于所有仪表,可以配置如下示例所示:

management.metrics.tags.region=us-east-1
management.metrics.tags.stack=prod

上面的示例添加了regionstack标记到所有值为us-east-1prod分别。

[Note]

如果使用Graphite,公共标记的顺序非常重要。由于使用这种方法无法保证公共标记的顺序,因此建议Graphite用户定义自定义MeterFilter相反。

每米56.5.2

除了……之外MeterFilterbean,也可以使用属性在每米的基础上应用有限的定制集。每米自定义适用于以给定名称开头的所有仪表ID.例如,以下内容将禁用任何具有ID的仪表。example.remote

management.metrics.enable.example.remote=false

以下属性允许每米定制:

表56.1.每米定制

财产描述

management.metrics.enable

是否拒绝仪表发射任何指标。

management.metrics.distribution.percentiles-histogram

是否发布适合于计算聚合(跨维度)百分位数近似的直方图。

management.metrics.distribution.percentiles

发布应用程序中计算的百分位数

management.metrics.distribution.sla

使用SLA定义的桶发布累积直方图。

 

有关背后概念的更多详细信息percentiles-histogrampercentilessla参考“直方图和百分位数”部分千分尺的文件。

56.6计量终点

Spring Boot提供了一个metrics可用于诊断性地检查应用程序收集的指标的端点。默认情况下,端点不可用,必须公开,请参见暴露端点更多细节。

导航到/actuator/metrics显示可用仪表名称的列表。您可以通过提供一个选择器的名称来向下查看有关特定仪表的信息。/actuator/metrics/jvm.memory.max.

[Tip]

您在这里使用的名称应该与代码中使用的名称相匹配,而不是在命名之后使用的名称。换句话说,如果jvm.memory.max显示为jvm_memory_max在普罗米修斯,因为它的蛇案例命名惯例,你仍然应该使用jvm.memory.max中的仪表时,作为选择器。metrics端点。

您还可以添加任意数量的tag=KEY:VALUE将参数查询到URL的末尾,以便在仪表上按尺寸向下钻取。/actuator/metrics/jvm.memory.max?tag=area:nonheap.

[Tip]

报告的测量结果是相加与表名匹配的所有仪表的统计数据以及已应用的任何标记。因此,在上面的示例中,返回的“value”统计数据是堆中“Code Cache”、“压缩类空间”和“Metaspace”区域的最大内存足迹的总和。如果您只想查看“Metaspace”的最大大小,可以添加一个额外的tag=id:Metaspace,即./actuator/metrics/jvm.memory.max?tag=area:nonheap&tag=id:Metaspace.

57.审计

SpringSecurity运行后,SpringBootActuator有一个灵活的审计框架来发布事件(默认情况下,“身份验证成功”、“失败”和“访问拒绝”异常)。此特性对于报告和实现基于身份验证失败的锁定策略非常有用。若要自定义已发布的安全事件,可以提供您自己的AbstractAuthenticationAuditListenerAbstractAuthorizationAuditListener.

您还可以将审计服务用于您自己的业务事件。要做到这一点,要么注入现有的AuditEventRepository在您自己的组件中直接使用该组件,或者发布AuditApplicationEvent与春天ApplicationEventPublisher(通过实施ApplicationEventPublisherAware).

58.http跟踪

所有HTTP请求都自动启用跟踪。您可以查看httptrace终结点并获取关于最后100个请求-响应交换的基本信息。

58.1自定义HTTP跟踪

若要自定义每个跟踪中包含的项,请使用management.trace.http.include配置属性。对于高级定制,请考虑注册自己的HttpExchangeTracer执行。

默认情况下,InMemoryHttpTraceRepository它存储最后100个请求响应交换的跟踪。如果需要扩展容量,可以定义您自己的InMemoryHttpTraceRepository豆子您还可以创建自己的备选方案。HttpTraceRepository执行。

59.过程监测

在.。spring-boot模块中,您可以找到两个类来创建通常对进程监视有用的文件:

  • ApplicationPidFileWriter创建包含应用程序PID的文件(默认情况下,在应用程序目录中,文件名为application.pid).
  • WebServerPortFileWriter创建一个文件(或多个文件),其中包含正在运行的web服务器的端口(默认情况下,在应用程序目录中,文件名为application.port).

默认情况下,不会激活这些写入器,但可以启用:

59.1扩展配置

在.。META-INF/spring.factories文件,您可以激活写入PID文件的监听器,如下面的示例所示:

org.springframework.context.ApplicationListener=\
org.springframework.boot.context.ApplicationPidFileWriter,\
org.springframework.boot.web.context.WebServerPortFileWriter

59.2以编程方式

还可以通过调用SpringApplication.addListeners(…​)方法并传递适当的Writer对象。此方法还允许您自定义Writer构造函数

六十云铸造支架

SpringBoot的执行器模块包括在部署到兼容的CloudFoundry实例时激活的额外支持。这,这个,那,那个/cloudfoundryapplicationPATH为所有用户提供了另一种安全路由。@Endpoint豆子

扩展支持使CloudFoundryManagementUI(例如可以用来查看已部署应用程序的Web应用程序)可以通过SpringBoot执行器信息得到增强。例如,应用程序状态页可能包含完整的健康信息,而不是典型的“运行”或“停止”状态。

[Note]

这,这个,那,那个/cloudfoundryapplication常规用户无法直接访问路径。为了使用端点,必须在请求中传递有效的UAA令牌。

60.1禁用扩展云铸造驱动器支持

如果要完全禁用/cloudfoundryapplication端点,可以将以下设置添加到application.properties档案:

应用特性。

management.cloudfoundry.enabled=false

 

60.2云铸造公司自签证书

默认情况下,/cloudfoundryapplication端点对各种CloudFoundry服务进行SSL调用。如果您的CloudFoundryUAA或CloudController服务使用自签名证书,则需要设置以下属性:

应用特性。

management.cloudfoundry.skip-ssl-validation=true

 

60.3自定义上下文路径

如果服务器的上下文路径已配置为/,CloudFoundry端点将无法在应用程序的根目录上使用。例如,如果server.servlet.context-path=/app,CloudFoundry端点将在/app/cloudfoundryapplication/*.

如果您期望CloudFoundry端点始终可用在/cloudfoundryapplication/*无论服务器的上下文路径如何,您都需要在应用程序中显式地配置它。根据使用中的Web服务器,配置将有所不同。对于Tomcat,可以添加以下配置:

@Bean
public TomcatServletWebServerFactory servletWebServerFactory() {
	return new TomcatServletWebServerFactory() {

		@Override
		protected void prepareContext(Host host,
				ServletContextInitializer[] initializers) {
			super.prepareContext(host, initializers);
			StandardContext child = new StandardContext();
			child.addLifecycleListener(new Tomcat.FixContextListener());
			child.setPath("/cloudfoundryapplication");
			ServletContainerInitializer initializer = getServletContextInitializer(
					getContextPath());
			child.addServletContainerInitializer(initializer, Collections.emptySet());
			child.setCrossContext(true);
			host.addChild(child);
		}

	};
}

private ServletContainerInitializer getServletContextInitializer(String contextPath) {
	return (c, context) -> {
		Servlet servlet = new GenericServlet() {

			@Override
			public void service(ServletRequest req, ServletResponse res)
					throws ServletException, IOException {
				ServletContext context = req.getServletContext()
						.getContext(contextPath);
				context.getRequestDispatcher("/cloudfoundryapplication").forward(req,
						res);
			}

		};
		context.addServlet("cloudfoundry", servlet).addMapping("/*");
	};
}

61.接下来要读什么?

如果您想探索本章中讨论的一些概念,您可以看看执行器。样本应用。您还可能希望阅读有关绘图工具的内容,例如石墨.

否则,您可以继续阅读有关“部署选项”或者跳出一些关于SpringBoot的深度信息构建工具插件.

第六部分。部署SpringBoot应用程序

SpringBoot的软包装选项在部署应用程序时提供了大量的选择。您可以将SpringBoot应用程序部署到各种云平台、容器映像(如Docker)或虚拟/真实机器上。

本节介绍了一些更常见的部署场景。

62.部署到云端

SpringBoot的可执行JAR已经为大多数流行的云PaaS(平台即服务)提供商做好了准备。这些提供者倾向于要求您“携带您自己的容器”。它们管理应用程序进程(而不是特定的Java应用程序),因此它们需要一个适配的中间层。你的云的正在运行的进程的概念。

两个流行的云提供商Heroku和CloudFoundry采用了一种“buildpack”方法。构建包将部署的代码封装在所需的任何内容中。启动你的申请。它可能是一个JDK和一个调用java、嵌入式Web服务器或成熟的应用服务器。构建包是可插拔的,但理想情况下,您应该能够尽可能少地对其进行自定义。这减少了不受您控制的功能的占用。它最大限度地减少了开发环境和生产环境之间的差异。

理想情况下,您的应用程序,如SpringBoot可执行JAR,包含了在其中打包运行所需的一切。

在本节中,我们将讨论如何获得我们开发的简单应用程序在“入门”部分启动并在云中运行。

62.1云铸造

云Foundry提供默认的构建包,如果没有指定其他的buildpack,这些包就会发挥作用。云铸造Javabuildpack对Spring应用程序有很好的支持,包括SpringBoot。您可以部署独立的可执行的jar应用程序以及传统的.war打包应用程序。

一旦构建了应用程序(例如,通过使用mvn clean package)安装cf命令行工具,使用cf push命令替换编译后的路径。.jar。一定要用你的cf命令行客户端在推送申请之前。下面的行使用cf push命令部署应用程序:

$ cf push acloudyspringtime -p target/demo-0.0.1-SNAPSHOT.jar
[Note]

在前面的示例中,我们将acloudyspringtime无论你付出了什么cf作为您的应用程序的名称。

cf push文献资料寻找更多的选择。如果有云铸造厂manifest.yml文件存在于同一目录中,则考虑。

在这一点上,cf开始上载应用程序,生成类似于以下示例的输出:

Uploading acloudyspringtime... OK
Preparing to start acloudyspringtime... OK
-----> Downloaded app package (8.9M)
-----> Java Buildpack Version: v3.12 (offline) | https://github.com/cloudfoundry/java-buildpack.git#6f25b7e
-----> Downloading Open Jdk JRE 1.8.0_121 from https://java-buildpack.cloudfoundry.org/openjdk/trusty/x86_64/openjdk-1.8.0_121.tar.gz (found in cache)
       Expanding Open Jdk JRE to .java-buildpack/open_jdk_jre (1.6s)
-----> Downloading Open JDK Like Memory Calculator 2.0.2_RELEASE from https://java-buildpack.cloudfoundry.org/memory-calculator/trusty/x86_64/memory-calculator-2.0.2_RELEASE.tar.gz (found in cache)
       Memory Settings: -Xss349K -Xmx681574K -XX:MaxMetaspaceSize=104857K -Xms681574K -XX:MetaspaceSize=104857K
-----> Downloading Container Certificate Trust Store 1.0.0_RELEASE from https://java-buildpack.cloudfoundry.org/container-certificate-trust-store/container-certificate-trust-store-1.0.0_RELEASE.jar (found in cache)
       Adding certificates to .java-buildpack/container_certificate_trust_store/truststore.jks (0.6s)
-----> Downloading Spring Auto Reconfiguration 1.10.0_RELEASE from https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-1.10.0_RELEASE.jar (found in cache)
Checking status of app 'acloudyspringtime'...
  0 of 1 instances running (1 starting)
  ...
  0 of 1 instances running (1 starting)
  ...
  0 of 1 instances running (1 starting)
  ...
  1 of 1 instances running (1 running)

App started

祝贺你!应用程序现在正在运行!

一旦应用程序处于活动状态,就可以使用cf apps命令,如以下示例所示:

$ cf apps
Getting applications in ...
OK

name                 requested state   instances   memory   disk   urls
...
acloudyspringtime    started           1/1         512M     1G     acloudyspringtime.cfapps.io
...

一旦CloudFoundry确认您的应用程序已经部署,您就可以在给定的URI中找到应用程序。在前面的示例中,您可以在http://acloudyspringtime.cfapps.io/.

62.1.1绑定到服务

默认情况下,有关正在运行的应用程序的元数据以及服务连接信息将作为环境变量公开给应用程序(例如:$VCAP_SERVICES)这个架构决定是由于CloudFoundry的Polyglot(任何语言和平台都可以作为构建包来支持)。过程范围内的环境变量与语言无关。

环境变量并不总是最简单的API,因此SpringBoot会自动提取它们,并将数据扁平化成可以通过Spring的属性访问的属性。Environment抽象,如以下示例所示:

@Component
class MyBean implements EnvironmentAware {

	private String instanceId;

	@Override
	public void setEnvironment(Environment environment) {
		this.instanceId = environment.getProperty("vcap.application.instance_id");
	}

	// ...

}

所有云铸造属性都以前缀vcap。你可以用vcap属性访问应用程序信息(例如应用程序的公共URL)和服务信息(例如数据库凭据)。见“CloudFoundryVcapEnvironment-PostProcessor”有关详细信息的Javadoc。

[Tip]

这,这个,那,那个弹簧云连接器项目更适合于配置DataSource等任务。Spring Boot包括自动配置支持和spring-boot-starter-cloud-connectors起动机。

62.2 Heroku

Heroku是另一个流行的PaaS平台。若要自定义Heroku构建,请提供Procfile,它提供了部署应用程序所需的咒语。Heroku分配port使Java应用程序使用并确保到外部URI的路由工作。

必须将应用程序配置为侦听正确的端口。下面的示例显示Procfile对于初学者REST应用程序:

web: java -Dserver.port=$PORT -jar target/demo-0.0.1-SNAPSHOT.jar

春靴-D作为从Spring访问的属性可用的参数Environment举个例子。这,这个,那,那个server.portConfiguration属性被输入到嵌入的Tomcat、Jetty或Undertu实例,然后在启动时使用端口。这,这个,那,那个$PORT环境变量由Heroku PaaS分配给我们。

这应该是你需要的一切。Heroku部署最常见的部署工作流是git push生产代码,如以下示例所示:

$ git push heroku master

Initializing repository, done.
Counting objects: 95, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (78/78), done.
Writing objects: 100% (95/95), 8.66 MiB | 606.00 KiB/s, done.
Total 95 (delta 31), reused 0 (delta 0)

-----> Java app detected
-----> Installing OpenJDK 1.8... done
-----> Installing Maven 3.3.1... done
-----> Installing settings.xml... done
-----> Executing: mvn -B -DskipTests=true clean install

       [INFO] Scanning for projects...
       Downloading: https://repo.spring.io/...
       Downloaded: https://repo.spring.io/... (818 B at 1.8 KB/sec)
		....
       Downloaded: http://s3pository.heroku.com/jvm/... (152 KB at 595.3 KB/sec)
       [INFO] Installing /tmp/build_0c35a5d2-a067-4abc-a232-14b1fb7a8229/target/...
       [INFO] Installing /tmp/build_0c35a5d2-a067-4abc-a232-14b1fb7a8229/pom.xml ...
       [INFO] ------------------------------------------------------------------------
       [INFO] BUILD SUCCESS
       [INFO] ------------------------------------------------------------------------
       [INFO] Total time: 59.358s
       [INFO] Finished at: Fri Mar 07 07:28:25 UTC 2014
       [INFO] Final Memory: 20M/493M
       [INFO] ------------------------------------------------------------------------

-----> Discovering process types
       Procfile declares types -> web

-----> Compressing... done, 70.4MB
-----> Launching... done, v6
       http://agile-sierra-1405.herokuapp.com/ deployed to Heroku

To git@heroku.com:agile-sierra-1405.git
 * [new branch]      master -> master

您的应用程序现在应该在Heroku上启动并运行。

62.3 OpenShift

OpenShift是Kubernetes容器编排平台的RedHat公共(和企业)扩展。与Kubernetes类似,OpenShift有许多安装基于SpringBoot的应用程序的选项。

OpenShift有许多描述如何部署SpringBoot应用程序的资源,包括:

62.4亚马逊网络服务(AWS)

AmazonWebServices提供多种方法来安装基于SpringBoot的应用程序,或者作为传统的Web应用程序(WAR)安装,或者作为带有嵌入式Web服务器的可执行JAR文件安装。备选方案包括:

  • AWS弹性豆柄
  • AWS代码部署
  • AWS OPS工程
  • AWS云形成
  • AWS集装箱登记处

每一种都有不同的特点和定价模式。在本文档中,我们只描述了最简单的选项:AWS弹性豆柄。

62.4.1 AWS弹性豆柄

如该官员所述弹性豆柄Java指南,部署Java应用程序有两个主要选项。您可以使用“Tomcat平台”或“JavaSE平台”。

使用Tomcat平台

此选项适用于生成WAR文件的SpringBoot项目。不需要特殊配置。你只需要遵循官方指南就行了。

使用JavaSE平台

此选项适用于生成JAR文件并运行嵌入式Web容器的SpringBoot项目。弹性Bean秸秆环境在端口80上运行一个nginx实例来代理实际应用程序,运行在端口5000上。若要配置它,请将以下行添加到您的application.properties档案:

server.port=5000
[Tip]

默认情况下,ElasticBean秸秆会上传源并在AWS中编译它们。但是,最好还是上传二进制文件。为此,请将类似于以下内容的行添加到您的.elasticbeanstalk/config.yml档案:

deploy:
	artifact: target/demo-0.0.1-SNAPSHOT.jar
[Tip]

默认情况下,弹性豆柄环境是负载平衡的。负载均衡器的成本很高。为了避免这种成本,请将环境类型设置为“单个实例”,如Amazon文档。还可以使用CLI和以下命令创建单个实例环境:

eb create -s

62.4.2摘要

这是实现AWS的最简单的方法之一,但是还有更多的事情要讨论,比如如何将ElasticBean秸秆集成到任何CI/CD工具中,使用ElasticBeansarMaven插件而不是CLI,等等。有一个博客帖子详细介绍这些主题。

62.5 BOXFUSE和AmazonWeb服务

箱式保险丝工作方式是将SpringBoot、可执行JAR或WAR转换成一个最小的VM映像,可以在VirtualBox或AWS上不作改动地部署。Box引信为SpringBoot提供了深度集成,并使用SpringBoot配置文件中的信息自动配置端口和健康检查URL。Box引信对它生成的图像以及它提供的所有资源(实例、安全组、弹性负载平衡器等)都利用了这些信息。

一旦创建了一个BOXFUSE帐户,将其连接到AWS帐户,安装BoxFUSE客户端的最新版本,并确保应用程序已由Maven或Gradle构建(例如,使用mvn clean package),您可以使用类似于以下命令的命令将SpringBoot应用程序部署到AWS:

$ boxfuse run myapp-1.0.jar -env=prod

boxfuse run文献资料寻找更多的选择。如果有一个boxfuse.conf文件存在于当前目录中,则考虑。

[Tip]

默认情况下,BoxFUSE激活一个名为Spring的概要文件boxfuse刚开始的时候。如果可执行JAR或WAR包含application-boxfuse.properties文件中,Box引信的配置基于它包含的属性。

在这一点上,boxfuse为您的应用程序创建一个映像,上传它,并在AWS上配置和启动必要的资源,从而产生类似于以下示例的输出:

Fusing Image for myapp-1.0.jar ...
Image fused in 00:06.838s (53937 K) -> axelfontaine/myapp:1.0
Creating axelfontaine/myapp ...
Pushing axelfontaine/myapp:1.0 ...
Verifying axelfontaine/myapp:1.0 ...
Creating Elastic IP ...
Mapping myapp-axelfontaine.boxfuse.io to 52.28.233.167 ...
Waiting for AWS to create an AMI for axelfontaine/myapp:1.0 in eu-central-1 (this may take up to 50 seconds) ...
AMI created in 00:23.557s -> ami-d23f38cf
Creating security group boxfuse-sg_axelfontaine/myapp:1.0 ...
Launching t2.micro instance of axelfontaine/myapp:1.0 (ami-d23f38cf) in eu-central-1 ...
Instance launched in 00:30.306s -> i-92ef9f53
Waiting for AWS to boot Instance i-92ef9f53 and Payload to start at http://52.28.235.61/ ...
Payload started in 00:29.266s -> http://52.28.235.61/
Remapping Elastic IP 52.28.233.167 to i-92ef9f53 ...
Waiting 15s for AWS to complete Elastic IP Zero Downtime transition ...
Deployment completed successfully. axelfontaine/myapp:1.0 is up and running at http://myapp-axelfontaine.boxfuse.io/

您的应用程序现在应该在AWS上启动并运行。

请看博客上的文章在EC2上部署SpringBoot应用程序以及BoxfueSpringBoot集成文档要开始使用Maven构建来运行这个应用程序。

62.6谷歌云

GoogleCloud有几个选项可用于启动SpringBoot应用程序。最容易开始使用的可能是AppEngine,但您也可以找到在容器中运行SpringBoot的方法,或者在带有Compute引擎的虚拟机上运行SpringBoot。

要在AppEngine中运行,您可以首先在UI中创建一个项目,该项目为您设置唯一标识符,还可以设置HTTP路由。将Java应用程序添加到项目中,并将其保留为空,然后使用GoogleCloudSDK要将SpringBoot应用程序从命令行或CI构建中插入到该槽中,请执行以下操作。

应用引擎标准要求您使用WAR包装。跟随这些步骤将AppEngine标准应用程序部署到GoogleCloud。

或者,AppEngine Flex要求您创建一个app.yaml文件来描述应用程序所需的资源。通常,你把这个文件放进src/main/appengine,它应该类似于以下文件:

service: default

runtime: java
env: flex

runtime_config:
  jdk: openjdk8

handlers:
- url: /.*
  script: this field is required, but ignored

manual_scaling:
  instances: 1

health_check:
  enable_health_check: False

env_variables:
  ENCRYPT_KEY: your_encryption_key_here

您可以通过将项目ID添加到构建配置中来部署应用程序(例如,使用Maven插件),如下面的示例所示:

<plugin>
	<groupId>com.google.cloud.tools</groupId>
	<artifactId>appengine-maven-plugin</artifactId>
	<version>1.3.0</version>
	<configuration>
		<project>myproject</project>
	</configuration>
</plugin>

然后用mvn appengine:deploy(如果需要先进行身份验证,则生成失败)。

63.安装SpringBoot应用程序

除了运行SpringBoot应用程序之外,还可以使用java -jar,也可以为Unix系统制作完全可执行的应用程序。完全可执行的JAR可以像任何其他可执行的二进制文件一样执行,也可以是init.dsystemd。这使得在常见的生产环境中安装和管理SpringBoot应用程序变得非常容易。

[Caution]谨慎

完全可执行的JAR通过在文件前面嵌入一个额外的脚本来工作。目前,有些工具不接受这种格式,因此您可能并不总是能够使用这种技术。例如jar -xf可能无法悄悄提取已完全可执行的JAR或WAR。建议您只在打算直接执行JAR或WAR时才使JAR或WAR完全可执行,而不是使用java -jar或者将其部署到servlet容器中。

若要使用Maven创建一个“完全可执行”的JAR,请使用以下插件配置:

<plugin>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-maven-plugin</artifactId>
	<configuration>
		<executable>true</executable>
	</configuration>
</plugin>

下面的示例显示了等效的Gradle配置:

bootJar {
	launchScript()
}

然后,您可以通过键入./my-application.jar(在哪里my-application是你的艺术品的名字)。包含JAR的目录用作应用程序的工作目录。

63.1支持的操作系统

默认脚本支持大多数Linux发行版,并在CentOS和Ubuntu上进行测试。其他平台,如OSX和FreeBSD,需要使用自定义embeddedLaunchScript.

63.2 Unix/Linux服务

可以轻松地以unix/linux服务的形式启动SpringBoot应用程序,方法是init.dsystemd.

63.2.1安装为init.d服务(系统五)

如果您将SpringBoot的Maven或Gradle插件配置为生成一个完全可执行JAR,并且您不使用自定义embeddedLaunchScript,您的应用程序可以用作init.d服务。为此,将JAR符号链接到init.d支持标准startstoprestart,和status命令。

该脚本支持以下特性:

  • 以拥有JAR文件的用户身份启动服务。
  • 通过使用/var/run/<appname>/<appname>.pid
  • 将控制台日志写入/var/log/<appname>.log

假设您已经安装了SpringBoot应用程序/var/myapp,将SpringBoot应用程序安装为init.d服务,创建一个符号链接,如下所示:

$ sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp

安装完毕后,您可以按照通常的方式启动和停止服务。例如,在基于Debian的系统上,可以使用以下命令启动它:

$ service myapp start
[Tip]

如果应用程序启动失败,请检查写入的日志文件。/var/log/<appname>.log因为错误。

还可以使用标准操作系统工具将应用程序标记为自动启动。例如,在Debian上,可以使用以下命令:

$ update-rc.d myapp defaults <priority>

确保init.d服务

[Note]

下面是一组关于如何保护作为init.d服务运行的SpringBoot应用程序的指导方针。它并不打算是一份详尽的清单,列出为强化应用程序和运行应用程序的环境而应该做的所有事情。

当作为root执行时,就像在使用root启动init.d服务时一样,默认的可执行脚本以拥有JAR文件的用户的身份运行应用程序。您不应该将SpringBoot应用程序作为root因此,应用程序的JAR文件永远不应该属于root。相反,创建一个特定的用户来运行您的应用程序并使用chown要使它成为JAR文件的所有者,如下面的示例所示:

$ chown bootapp:bootapp your-app.jar

在这种情况下,默认的可执行脚本以bootapp用户。

[Tip]

为了减少应用程序的用户帐户被破坏的可能性,您应该考虑阻止它使用登录shell。例如,可以将帐户的shell设置为/usr/sbin/nologin.

您还应该采取措施防止修改应用程序的JAR文件。首先,配置其权限,使其不能被写入,并且只能由其所有者读取或执行,如下面的示例所示:

$ chmod 500 your-app.jar

其次,如果您的应用程序或运行它的帐户被破坏,您还应该采取措施限制损坏。如果攻击者确实获得了访问权限,他们可以使JAR文件可写并更改其内容。防止这种情况的一种方法是通过使用chattr,如以下示例所示:

$ sudo chattr +i your-app.jar

这将防止任何用户(包括root用户)修改JAR。

如果根用户用于控制应用程序的服务,则.conf档案若要自定义其启动,请将.conf文件由根用户读取和计算。应当相应地加以担保。使用chmod这样,该文件只能由所有者读取并使用。chown要使所有者具有根,如下面的示例所示:

$ chmod 400 your-app.conf
$ sudo chown root:root your-app.conf

63.2.2安装为systemd服务

systemd是SystemV init系统的继承者,现在许多现代Linux发行版都在使用它。虽然您可以继续使用init.d脚本systemd,也可以通过以下方式启动SpringBoot应用程序systemd“服务”脚本。

假设您已经安装了SpringBoot应用程序/var/myapp,将SpringBoot应用程序安装为systemd服务,创建一个名为myapp.service把它放进去/etc/systemd/system目录。以下脚本提供了一个示例:

[Unit]
Description=myapp
After=syslog.target

[Service]
User=myapp
ExecStart=/var/myapp/myapp.jar
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target
[Important]重要

请记住更改DescriptionUser,和ExecStart应用程序的字段。

[Note]

这,这个,那,那个ExecStart字段不声明脚本操作命令,这意味着run命令默认使用。

注意,与作为init.d服务,运行应用程序的用户、PID文件和控制台日志文件由systemd因此,必须通过在“service”脚本中使用适当的字段来配置它本身。咨询服务单元配置手册页更多细节。

若要在系统启动时将应用程序标记为自动启动,请使用以下命令:

$ systemctl enable myapp.service

请参阅man systemctl更多细节。

63.2.3自定义启动脚本

由Maven或Gradle插件编写的默认嵌入式启动脚本可以通过多种方式进行定制。对于大多数人来说,使用默认脚本和一些自定义通常就足够了。如果发现无法自定义所需的内容,请使用embeddedLaunchScript选项可以完全写入您自己的文件。

在编写开始脚本时自定义它

当开始脚本被写入JAR文件时,定制它的元素通常是有意义的。例如,init.d脚本可以提供“描述”。因为您预先知道了描述(并且它不需要更改),所以您最好在JAR生成时提供它。

若要自定义编写的元素,请使用embeddedLaunchScriptProperties选择SpringBootMaven或Gradle插件。

默认脚本支持以下属性替换:

名字,姓名描述分级违约Maven缺省

mode

脚本模式。

auto

auto

initInfoProvides

这,这个,那,那个Provides“INIT信息”一节

${task.baseName}

${project.artifactId}

initInfoRequiredStart

Required-Start“INIT信息”一节。

$remote_fs $syslog $network

$remote_fs $syslog $network

initInfoRequiredStop

Required-Stop“INIT信息”一节。

$remote_fs $syslog $network

$remote_fs $syslog $network

initInfoDefaultStart

Default-Start“INIT信息”一节。

2 3 4 5

2 3 4 5

initInfoDefaultStop

Default-Stop“INIT信息”一节。

0 1 6

0 1 6

initInfoShortDescription

Short-Description“INIT信息”一节。

单行版本${project.description}(回落到${task.baseName})

${project.name}

initInfoDescription

Description“INIT信息”一节。

${project.description}(回落到${task.baseName})

${project.description}(回落到${project.name})

initInfoChkconfig

chkconfig“INIT信息”一节

2345 99 01

2345 99 01

confFolder

的默认值CONF_FOLDER

包含罐子的文件夹

包含罐子的文件夹

inlinedConfScript

引用默认启动脚本中应该内联的文件脚本。这可用于设置环境变量,如JAVA_OPTS在加载任何外部配置文件之前

  

logFolder

默认值LOG_FOLDER。只对init.d服务

  

logFilename

默认值LOG_FILENAME。只对init.d服务

  

pidFolder

默认值PID_FOLDER。只对init.d服务

  

pidFilename

中的PID文件名的默认值。PID_FOLDER。只对init.d服务

  

useStartStopDaemon

是否start-stop-daemon命令,当它可用时,应该使用它来控制进程。

true

true

stopWaitTime

默认值STOP_WAIT_TIME几秒钟之内。只对init.d服务

60

60

在脚本运行时自定义脚本

用于需要自定义的脚本项。已经编写了JAR,您可以使用环境变量或配置文件.

默认脚本支持下列环境属性:

变量描述

MODE

操作的“模式”。默认情况取决于JAR的构建方式,但通常是auto(这意味着它试图通过检查init脚本是否是目录中的符号链接来猜测它是否为init脚本)。init.d)可以显式地将其设置为service所以stop|start|status|restart命令工作或到run如果您想在前台运行脚本。

USE_START_STOP_DAEMON

是否start-stop-daemon命令,当它可用时,应该使用它来控制进程。默认为true.

PID_FOLDER

PID文件夹的根名称(/var/run(默认情况下)。

LOG_FOLDER

要在其中放置日志文件的文件夹的名称(/var/log(默认情况下)。

CONF_FOLDER

要从其中读取.conf文件的文件夹的名称(默认情况下,该文件夹与jar-file相同)。

LOG_FILENAME

控件中日志文件的名称。LOG_FOLDER (<appname>.log(默认情况下)。

APP_NAME

应用程序的名称。如果JAR是从符号链接运行的,脚本就会猜测应用程序的名称。如果它不是符号链接,或者您希望显式设置应用程序名称,这可能是有用的。

RUN_ARGS

传递给程序的参数(SpringBoot应用程序)。

JAVA_HOME

的位置java可执行文件是通过使用PATH默认情况下,但如果有可执行文件,则可以显式设置$JAVA_HOME/bin/java.

JAVA_OPTS

在JVM启动时传递给它的选项。

JARFILE

JAR文件的显式位置,以防脚本被用来启动一个实际上没有嵌入的JAR。

DEBUG

如果不为空,则设置-x标记在shell进程上,使得在脚本中很容易看到逻辑。

STOP_WAIT_TIME

在强制关闭之前停止应用程序时等待的时间(以秒为单位)(60(默认情况下)。

[Note]

这,这个,那,那个PID_FOLDERLOG_FOLDER,和LOG_FILENAME变量仅对init.d服务。为systemd,等效的自定义是通过使用“service”脚本进行的。见服务单元配置手册页更多细节。

除了.JARFILEAPP_NAME,则上一节中列出的设置可以通过使用.conf档案。该文件应位于JAR文件的旁边,并且具有相同的名称,但后缀为.conf而不是.jar。例如,一个名为/var/myapp/myapp.jar使用名为/var/myapp/myapp.conf,如以下示例所示:

myapp.conf.

JAVA_OPTS=-Xmx1024M
LOG_FOLDER=/custom/log/folder

 

[Tip]

如果不喜欢将配置文件放在JAR文件旁边,则可以设置CONF_FOLDER环境变量来自定义配置文件的位置。

若要了解如何适当保护此文件,请参见确保init.d服务安全的指南.

63.3微软Windows服务

可以将SpringBoot应用程序作为Windows服务启动,方法是winsw.

A(单独维护样本)描述如何为SpringBoot应用程序创建Windows服务。

64.接下来要读什么?

检查一下云铸造赫鲁库OpenShift,和箱式保险丝有关PaaS可以提供的功能种类的更多信息,请参见网站。这些只是最流行的JavaPaaS供应商中的四个。由于SpringBoot非常适合基于云的部署,所以您也可以自由地考虑其他提供者。

下一节继续讨论弹簧启动CLI或者你可以跳到前面去读构建工具插件.

第七部分弹簧启动CLI

SpringBootCLI是一个命令行工具,如果您想要快速开发Spring应用程序,可以使用它。它允许您运行Groovy脚本,这意味着您有一个熟悉的类似Java的语法,而没有太多的样板代码。您还可以引导一个新项目或为它编写您自己的命令。

65.安装CLI

使用SDKMAN可以手动安装SpringBootCLI(命令行接口)!(SDK管理器),如果您是OSX用户,则可以使用HomeBREW或MacPorts。看见10.2节,“安装SpringBoot CLI”在“入门”一节中获得全面的安装说明。

66.使用CLI

一旦安装了CLI,就可以通过键入spring并在命令行按Enter。如果你跑spring在没有任何参数的情况下,将显示一个简单的帮助屏幕,如下所示:

$ spring
usage: spring [--help] [--version]
       <command> [<args>]

Available commands are:

  run [options] <files> [--] [args]
    Run a spring groovy script

  ... more command help is shown here

你可以打字spring help若要获取有关任何受支持命令的更多详细信息,请参见以下示例:

$ spring help run
spring run - Run a spring groovy script

usage: spring run [options] <files> [--] [args]

Option                     Description
------                     -----------
--autoconfigure [Boolean]  Add autoconfigure compiler
                             transformations (default: true)
--classpath, -cp           Additional classpath entries
-e, --edit                 Open the file with the default system
                             editor
--no-guess-dependencies    Do not attempt to guess dependencies
--no-guess-imports         Do not attempt to guess imports
-q, --quiet                Quiet logging
-v, --verbose              Verbose logging of dependency
                             resolution
--watch                    Watch the specified file for changes

这,这个,那,那个version命令提供了一种快速检查使用的SpringBoot版本的方法,如下所示:

$ spring version
Spring CLI v2.1.0.BUILD-SNAPSHOT

66.1使用CLI运行应用程序

方法可以编译和运行Groovy源代码。run命令。SpringBootCLI是完全独立的,所以您不需要安装任何外部Groovy。

下面的示例显示了用Groovy编写的“Hello World”Web应用程序:

你好,太棒了。

@RestController
class WebApplication {

	@RequestMapping("/")
	String home() {
		"Hello World!"
	}

}

 

要编译和运行应用程序,输入以下命令:

$ spring run hello.groovy

若要向应用程序传递命令行参数,请使用--若要将命令与“Spring”命令参数分离,请参见以下示例:

$ spring run hello.groovy -- --server.port=9000

要设置jvm命令行参数,可以使用JAVA_OPTS环境变量,如以下示例所示:

$ JAVA_OPTS=-Xmx1024m spring run hello.groovy
[Note]

设置时JAVA_OPTS在MicrosoftWindows上,确保引用整个指令,如set "JAVA_OPTS=-Xms256m -Xmx2048m"。这样做可以确保将值正确传递给进程。

66.1.1推导出“抓取”属地

标准Groovy包括@Grab注释,它允许您声明对第三方库的依赖关系。这个有用的技术可以让Groovy以与Maven或Gradle相同的方式下载JAR,但不需要使用构建工具。

SpringBoot进一步扩展了这一技术,并试图根据您的代码推断出要“抓取”哪些库。例如,由于WebApplication前面显示的代码使用@RestController注解,SpringBoot抓住了“Tomcat”和“SpringMVC”。

以下项目用作“抓取提示”:

项目抓取

JdbcTemplateNamedParameterJdbcTemplateDataSource

JDBC应用

@EnableJms

JMS应用

@EnableCaching

缓存抽象。

@Test

JUnit

@EnableRabbit

拉比·MQ

延展Specification

史波克测试。

@EnableBatchProcessing

弹簧批。

@MessageEndpoint @EnableIntegration

弹簧集成。

@Controller @RestController @EnableWebMvc

SpringMVC+嵌入式Tomcat。

@EnableWebSecurity

春季保安。

@EnableTransactionManagement

春季事务管理

[Tip]

CompilerAutoConfiguration在SpringBootCLI源代码中,可以准确地了解如何应用自定义。

66.1.2推导出“抓取”坐标

SpringBoot扩展了Groovy的标准@Grab通过允许您在没有组或版本的情况下指定依赖项(例如,@Grab('freemarker'))这样做可以参考SpringBoot的默认依赖元数据来推断工件的组和版本。

[Note]

默认元数据绑定到您使用的CLI版本。只有当您移动到CLI的新版本时,它才会更改,这将使您控制依赖项的版本何时会更改。显示默认元数据中包含的依赖项及其版本的表可以在附录.

66.1.3默认导入语句

为了帮助缩小Groovy代码的大小,以下几个import语句自动包括在内。注意前面的示例如何引用@Component@RestController,和@RequestMapping不需要使用完全限定的名称或import陈述。

[Tip]

许多Spring注释无需使用import陈述。尝试在添加导入之前运行应用程序以查看哪些失败。

66.1.4自动主法

与等效的Java应用程序不同,不需要包含public static void main(String[] args)方法与您的Groovy剧本。一个SpringApplication自动创建,编译后的代码将充当source.

66.1.5自定义依赖关系管理

默认情况下,cli使用spring-boot-dependencies解析时@Grab依赖关系。可以使用@DependencyManagementBom注释注释的值应该指定坐标(groupId:artifactId:version)一个或多个Maven Boms。

例如,考虑以下声明:

@DependencyManagementBom("com.example.custom-bom:1.0.0")

前面的声明显示custom-bom-1.0.0.pom在Maven存储库中com/example/custom-versions/1.0.0/.

当您指定多个BOM时,将按照声明它们的顺序应用它们,如下面的示例所示:

@DependencyManagementBom(["com.example.custom-bom:1.0.0",
		"com.example.another-bom:1.0.0"])

上面的示例表明another-bom中重写依赖关系管理。custom-bom.

你可以用@DependencyManagementBom任何你可以使用的地方@Grab。但是,要确保依赖关系管理的顺序一致,可以使用@DependencyManagementBom在您的应用程序中最多一次。依赖管理的一个有用来源(它是SpringBoot的依赖管理的超集)是弹簧IO平台,您可以将其包含在以下行中:

@DependencyManagementBom('io.spring.platform:platform-bom:1.1.2.RELEASE')

66.2具有多源文件的应用程序

您可以在接受文件输入的所有命令中使用“shell globing”。这样做可以让您使用来自单个目录的多个文件,如下面的示例所示:

$ spring run *.groovy

66.3包装您的应用程序

您可以使用jar命令将应用程序打包到一个自包含的可执行JAR文件中,如下面的示例所示:

$ spring jar my-app.jar *.groovy

生成的JAR包含通过编译应用程序和应用程序的所有依赖项生成的类,这样就可以使用java -jar。JAR文件还包含来自应用程序类路径的条目。可以向JAR添加和移除显式路径,方法是--include--exclude。两者都是逗号分隔的,并且都接受前缀,以“+”和“-”的形式表示应该从默认值中删除它们。默认包含如下:

public/**, resources/**, static/**, templates/**, META-INF/**, *

默认排除如下:

.*, repository/**, build/**, target/**, **/*.jar, **/*.groovy

类型spring help jar在命令行上获取更多信息。

66.4启动一个新项目

这,这个,那,那个init命令可以通过以下方式创建一个新项目:start.spring.io而不离开shell,如下面的示例所示:

$ spring init --dependencies=web,data-jpa my-project
Using service at https://start.spring.io
Project extracted to '/Users/developer/example/my-project'

前面的示例创建了my-project目录中包含一个基于Maven的项目,该项目使用spring-boot-starter-webspring-boot-starter-data-jpa。方法可以列出服务的功能。--list标志,如以下示例所示:

$ spring init --list
=======================================
Capabilities of https://start.spring.io
=======================================

Available dependencies:
-----------------------
actuator - Actuator: Production ready features to help you monitor and manage your application
...
web - Web: Support for full-stack web development, including Tomcat and spring-webmvc
websocket - Websocket: Support for WebSocket development
ws - WS: Support for Spring Web Services

Available project types:
------------------------
gradle-build -  Gradle Config [format:build, build:gradle]
gradle-project -  Gradle Project [format:project, build:gradle]
maven-build -  Maven POM [format:build, build:maven]
maven-project -  Maven Project [format:project, build:maven] (default)

...

这,这个,那,那个init命令支持许多选项。见help输出更多细节。例如,下面的命令创建一个使用Java 8和war包装:

$ spring init --build=gradle --java-version=1.8 --dependencies=websocket --packaging=war sample-app.zip
Using service at https://start.spring.io
Content saved to 'sample-app.zip'

66.5使用嵌入式Shell

SpringBoot包括用于Bash和zsh shell的命令行完成脚本。如果您不使用这些shell(可能您是Windows用户),则可以使用shell命令启动集成shell,如以下示例所示:

$ spring shell
Spring Boot (v2.1.0.BUILD-SNAPSHOT)
Hit TAB to complete. Type \'help' and hit RETURN for help, and \'exit' to quit.

在嵌入的shell中,可以直接运行其他命令:

$ version
Spring CLI v2.1.0.BUILD-SNAPSHOT

嵌入式外壳支持ANSI颜色输出以及tab完成。如果需要运行本机命令,可以使用!前缀。若要退出嵌入的外壳,请按ctrl-c.

66.6向CLI添加扩展

可以使用install命令。该命令以格式接受一组或多组工件坐标。group:artifact:version,如以下示例所示:

$ spring install com.example:spring-boot-cli-extension:1.0.0.RELEASE

除了安装您所提供的坐标所标识的工件之外,还安装了所有工件的依赖关系。

若要卸载依赖项,请使用uninstall命令。就像install命令中,它接受一组或多组工件坐标,格式为group:artifact:version,如以下示例所示:

$ spring uninstall com.example:spring-boot-cli-extension:1.0.0.RELEASE

它卸载您提供的坐标和它们的依赖项所标识的工件。

若要卸载所有其他依赖项,可以使用--all选项,如以下示例所示:

$ spring uninstall --all

67.使用GroovyBeans DSL开发应用程序

SpringFramework4.0对beans{}“DSL”(借用自砂砾),并且可以使用相同的格式将bean定义嵌入到Groovy应用程序脚本中。这有时是包含中间件声明等外部特性的好方法,如下面的示例所示:

@Configuration
class Application implements CommandLineRunner {

	@Autowired
	SharedService service

	@Override
	void run(String... args) {
		println service.message
	}

}

import my.company.SharedService

beans {
	service(SharedService) {
		message = "Hello World"
	}
}

您可以将类声明与beans{}在同一个文件中,只要它们停留在顶层,或者,如果您愿意,可以将Beans DSL放在一个单独的文件中。

68.配置CLIsettings.xml

SpringBootCLI使用Aether(Maven的依赖解析引擎)来解决依赖关系。CLI使用了~/.m2/settings.xml配置乙醚。CLI遵守下列配置设置:

  • 离线
  • 镜子
  • 服务器
  • 代理
  • 剖面图

    • 活化
    • 储存库
  • 活动剖面

看见Maven设置文档以获取更多信息。

69.接下来要读什么?

有一些示例groovy脚本可以从GitHub存储库中获得,您可以使用它来尝试SpringBootCLI。也有广泛的Javadoc贯穿于源代码.

如果您发现您已经达到了CLI工具的极限,那么您可能希望将您的应用程序转换为一个完整的Gradle或Maven构建的“Groovy项目”。下一节将介绍SpringBoot的“构建工具插件,可以与Gradle或Maven一起使用。

第八编构建工具插件

SpringBoot为Maven和Gradle提供了构建工具插件。插件提供了多种特性,包括可执行JAR的打包。本节提供了更多关于这两个插件的详细信息,以及在需要扩展不受支持的构建系统时提供的一些帮助。如果你才刚开始,你可能想读“第13章,构建系统“从”第三部分,“使用Spring Boot”“第一节。

70.Spring Boot Maven插件

这,这个,那,那个Spring Boot Maven插件在Maven中提供SpringBoot支持,允许您打包可执行的JAR或WAR存档,并运行应用程序“就地”。要使用它,必须使用Maven 3.2(或更高版本)。

[Note]

Spring Boot Maven插件站点获得完整的插件文档。

70.1包括插件

若要使用SpringBootMaven插件,请在plugins你的部分pom.xml,如以下示例所示:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<!-- ... -->
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<version>2.1.0.BUILD-SNAPSHOT</version>
				<executions>
					<execution>
						<goals>
							<goal>repackage</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

前面的配置重新打包了一个JAR或WAR,该JAR或WAR是在packageMaven生命周期的阶段。下面的示例既显示了重新打包的JAR,也显示了target目录:

$ mvn package
$ ls target/*.jar
target/myproject-1.0.0.jar target/myproject-1.0.0.jar.original

如果不包括<execution/>如前面的示例所示,配置可以自己运行插件(但也必须使用包目标),如下面的示例所示:

$ mvn package spring-boot:repackage
$ ls target/*.jar
target/myproject-1.0.0.jar target/myproject-1.0.0.jar.original

如果使用里程碑或快照发行版,还需要添加适当的pluginRepository元素,如以下清单所示:

<pluginRepositories>
	<pluginRepository>
		<id>spring-snapshots</id>
		<url>https://repo.spring.io/snapshot</url>
	</pluginRepository>
	<pluginRepository>
		<id>spring-milestones</id>
		<url>https://repo.spring.io/milestone</url>
	</pluginRepository>
</pluginRepositories>

70.2包装可执行罐和战争文件

一次spring-boot-maven-plugin已经包含在您的pom.xml,它会自动尝试重写档案,以便通过使用spring-boot:repackage进球。您应该将您的项目配置为构建JAR或WAR(视情况而定),方法是使用通常的packaging元素,如以下示例所示:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<!-- ... -->
	<packaging>jar</packaging>
	<!-- ... -->
</project>

package相位。要启动的主类可以通过使用配置选项或添加Main-Class属性以通常的方式添加到清单。如果未指定主类,则插件将搜索具有public static void main(String[] args)方法。

要构建和运行项目工件,可以键入以下内容:

$ mvn package
$ java -jar target/mymodule-0.0.1-SNAPSHOT.jar

要构建一个既可执行又可部署到外部容器中的WAR文件,您需要将嵌入的容器依赖项标记为“提供”,如下面的示例所示:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<!-- ... -->
	<packaging>war</packaging>
	<!-- ... -->
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>
		<!-- ... -->
	</dependencies>
</project>
[Tip]

见“第91.1节,“创建可部署的战争文件”“有关如何创建可部署的WAR文件的更多详细信息,请参见。

高级配置选项和示例可在插件信息页面.

71.弹簧启动级插件

SpringBootGradle插件在Gradle中提供了SpringBoot支持,允许您打包可执行的JAR或WAR存档,运行SpringBoot应用程序,并使用由spring-boot-dependencies。它需要Gradle 4.4或更高版本。请参阅插件的文档以了解更多信息:

72.弹簧启动AntLib模块

SpringBootAntLib模块为ApacheAnt提供了基本的SpringBoot支持。您可以使用该模块创建可执行的JAR。要使用该模块,您需要声明一个额外的spring-boot命名空间中的build.xml,如以下示例所示:

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

您需要记住使用-lib选项,如以下示例所示:

$ ant -lib <folder containing spring-boot-antlib-2.1.0.BUILD-SNAPSHOT.jar>
[Tip]

“使用SpringBoot”部分包含了一个更完整的示例使用ApacheAntspring-boot-antlib.

72.1 Spring启动Ant任务

曾经spring-boot-antlib命名空间已声明,可使用下列附加任务:

72.1.1 spring-boot:exejar

您可以使用exejar创建SpringBoot可执行JAR的任务。任务支持以下属性:

属性描述所需

destfile

要创建的目标JAR文件

classes

Java类文件的根目录

start-class

要运行的主应用程序类。

(默认值是第一个找到的类,它声明main方法)

以下嵌套元素可用于该任务:

元素描述

resources

一个或多个资源收集描述一组资源应该将其添加到创建的JAR文件的内容中。

lib

一个或多个资源收集应该将其添加到组成应用程序运行时依赖类路径的一组JAR库中。

72.1.2实例

本节展示了两个Ant任务示例。

指定开始类。

<spring-boot:exejar destfile="target/my-application.jar"
		classes="target/classes" start-class="com.example.MyApplication">
	<resources>
		<fileset dir="src/main/resources" />
	</resources>
	<lib>
		<fileset dir="lib" />
	</lib>
</spring-boot:exejar>

 

开始上课。

<exejar destfile="target/my-application.jar" classes="target/classes">
	<lib>
		<fileset dir="lib" />
	</lib>
</exejar>

 

72.2 spring-boot:findmainclass

这,这个,那,那个findmainclass任务在内部由exejar若要找到声明main。如果有必要,也可以在构建中直接使用此任务。支持下列属性:

属性描述所需

classesroot

Java类文件的根目录

(除非mainclass指定)

mainclass

可用于短路main类搜索

property

应该与结果一起设置的Ant属性

(如果未指定结果,将记录结果)

72.2.1实例

本节包含三个使用findmainclass.

找到并记录。

<findmainclass classesroot="target/classes" />

 

找到并准备好。

<findmainclass classesroot="target/classes" property="main-class" />

 

覆盖并设置。

<findmainclass mainclass="com.example.MainClass" property="main-class" />

 

73.支持其他构建系统

如果您想使用Maven、Gradle或Ant以外的构建工具,则可能需要开发自己的插件。可执行的JAR需要遵循特定的格式,某些条目需要以未压缩的形式编写(请参阅“可执行JAR格式“详见附录中的一节)。

SpringBootMaven和Gradle插件都使用spring-boot-loader-tools才能真正产生罐子。如果需要,可以直接使用这个库。

73.1重新包装档案馆

若要重新打包现有存档,使其成为自带的可执行存档,请使用org.springframework.boot.loader.tools.Repackager。这,这个,那,那个Repackager类接受引用现有JAR或WAR存档的单个构造函数参数。使用两种可用的一种repackage()方法替换原始文件或写入新目标。在重新打包程序运行之前,还可以在其上配置各种设置。

73.2嵌套库

重新打包存档时,可以使用org.springframework.boot.loader.tools.Libraries接口。我们没有提供任何具体的实现Libraries在这里,因为它们通常是特定于构建系统的。

如果您的存档已经包含了库,则可以使用Libraries.NONE.

73.3找到主修班

如果你不使用Repackager.setMainClass()若要指定主类,rePackager将使用ASM若要读取类文件并尝试使用public static void main(String[] args)方法。如果找到多个候选人,则引发异常。

73.4重新包装实现示例

下面的示例显示了一个典型的重新打包实现:

Repackager repackager = new Repackager(sourceJarFile);
repackager.setBackupSource(false);
repackager.repackage(new Libraries() {
			@Override
			public void doWithLibraries(LibraryCallback callback) throws IOException {
				// Build system specific implementation, callback for each dependency
				// callback.library(new Library(nestedFile, LibraryScope.COMPILE));
			}
		});

74.接下来要读什么?

如果您对构建工具插件的工作方式感兴趣,可以查看spring-boot-toolsGitHub上的模块。可执行JAR格式的更多技术细节将在附录.

如果您有特定的与构建相关的问题,可以查看“如何“向导。

第九编“How-to”指南

本节给出了一些常见的‘我如何做那个…’的答案​在使用SpringBoot时经常出现的问题。它的覆盖范围并非详尽无遗,但确实涵盖了相当多的内容。

如果您有特定的问题,我们在这里不讨论,您可能需要检查。stackoverflow.com看看是否有人已经给出了答案。这也是一个问新问题的好地方(请使用spring-boot(标签)。

我们也非常乐意扩展这一节。如果您想添加“如何-to”,请给我们发送一个拉请求.

75.弹簧引导应用

本节包含与SpringBoot应用程序直接相关的主题。

75.1创建自己的FailureAnalyzer

FailureAnalyzer是一种很好的方法,可以在启动时拦截异常并将其转换为人类可读的消息,包装在FailureAnalysis。SpringBoot为应用程序上下文相关的异常、JSR-303验证等提供了这样的分析器。您也可以创建自己的。

AbstractFailureAnalyzer的方便扩展。FailureAnalyzer它检查要处理的异常中是否存在指定的异常类型。您可以对此进行扩展,以便您的实现只有在异常实际存在时才有机会处理它。如果由于任何原因无法处理异常,则返回null给另一个实现一个处理异常的机会。

FailureAnalyzer实现必须在META-INF/spring.factories。下面的示例注册ProjectConstraintViolationFailureAnalyzer:

org.springframework.boot.diagnostics.FailureAnalyzer=\
com.example.ProjectConstraintViolationFailureAnalyzer
[Note]

如果需要访问BeanFactory或者Environment,你的FailureAnalyzer可以简单地实现BeanFactoryAwareEnvironmentAware分别。

75.2自动配置故障排除

SpringBoot自动配置尽力“做正确的事情”,但有时失败,很难说出原因。

有一个非常有用的ConditionEvaluationReport可在任何SpringBoot中获得ApplicationContext。如果您启用DEBUG测井输出如果您使用spring-boot-actuator(见执行者章节),也有一个conditions在JSON中呈现报表的端点。使用该端点调试应用程序,并查看SpringBoot在运行时添加了哪些特性(哪些特性尚未添加)。

更多的问题可以通过查看源代码和Javadoc来回答。阅读代码时,请记住以下经验规则:

  • 查找名为*AutoConfiguration阅读他们的资料来源。特别注意@Conditional*注释,以了解它们启用了哪些特性以及何时启用。加--debug到命令行或系统属性。-Ddebug在您的应用程序中获得所有自动配置决策的控制台日志。在运行中的Actuator应用程序中,请查看conditions端点(/actuator/conditions或相同信息的JMX等价物)。
  • 查找@ConfigurationProperties(如ServerProperties)并从中读取可用的外部配置选项。这,这个,那,那个@ConfigurationProperties注释有一个name属性,用作外部属性的前缀。因此,ServerPropertiesprefix="server"它的配置属性是server.portserver.address和其他人。在运行中的Actuator应用程序中,请查看configprops端点。
  • 查找bind方法的Binder将配置值显式地从Environment以轻松的方式。它常与前缀连用。
  • 寻找@Value直接绑定到Environment.
  • 寻找@ConditionalOnExpression为响应Spel表达式而打开和关闭功能的注释,通常使用从Environment.

75.3在环境或ApplicationContext启动之前定制它

SpringApplicationApplicationListenersApplicationContextInitializers用于将自定义应用于上下文或环境的。SpringBoot从META-INF/spring.factories。注册其他自定义的方法不止一种:

  • 通过调用addListenersaddInitializers方法SpringApplication在你运行之前。
  • 通过设置context.initializer.classescontext.listener.classes财产。
  • 以声明方式,为所有应用程序添加META-INF/spring.factories并打包应用程序都用作库的JAR文件。

这,这个,那,那个SpringApplication送些特别的ApplicationEvents到侦听器(有些甚至在创建上下文之前),然后为由ApplicationContext也是见“第23.5节,“应用程序事件和侦听器”“在‘SpringBoot特性’部分获得完整列表。

还可以自定义Environment在通过以下方法刷新应用程序上下文之前EnvironmentPostProcessor。每个实现都应在META-INF/spring.factories,如以下示例所示:

org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor

实现可以加载任意文件并将它们添加到Environment。例如,以下示例从类路径加载YAML配置文件:

public class EnvironmentPostProcessorExample implements EnvironmentPostProcessor {

	private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();

	@Override
	public void postProcessEnvironment(ConfigurableEnvironment environment,
			SpringApplication application) {
		Resource path = new ClassPathResource("com/example/myapp/config.yml");
		PropertySource<?> propertySource = loadYaml(path);
		environment.getPropertySources().addLast(propertySource);
	}

	private PropertySource<?> loadYaml(Resource path) {
		if (!path.exists()) {
			throw new IllegalArgumentException("Resource " + path + " does not exist");
		}
		try {
			return this.loader.load("custom-resource", path).get(0);
		}
		catch (IOException ex) {
			throw new IllegalStateException(
					"Failed to load yaml configuration from " + path, ex);
		}
	}

}
[Tip]

这,这个,那,那个Environment已经准备好了SpringBoot默认加载的所有常用属性源。因此,可以从环境中获取文件的位置。前面的示例添加了custom-resource属性源在列表的末尾,以便在任何通常的其他位置中定义的键优先。自定义实现可以定义另一个顺序。

[Caution]谨慎

使用时@PropertySource你的@SpringBootApplication类中加载自定义资源的一种方便和简单的方法。Environment,我们不推荐它,因为SpringBoot准备了EnvironmentApplicationContext重新振作起来。用@PropertySource加载太晚,无法对自动配置产生任何影响。

75.4构建ApplicationContext层次结构(添加父上下文或根上下文)

您可以使用ApplicationBuilder类来创建父/子ApplicationContext等级制度。见“第23.4节,“FLUENT Builder API”“在‘SpringBoot特性’一节中可以获得更多信息。

75.5创建一个非web应用程序

并非所有Spring应用程序都必须是Web应用程序(或Web服务)。如果您想在main方法,还可以引导Spring应用程序来设置要使用的基础设施,可以使用SpringApplication春靴的特征。一个SpringApplication改变它的ApplicationContext类,取决于它是否认为需要Web应用程序。您可以做的第一件事是将与服务器相关的依赖关系(例如ServletAPI)排除在类路径之外。如果不能这样做(例如,从同一个代码库运行两个应用程序),则可以显式调用setWebApplicationType(WebApplicationType.NONE)你的SpringApplication实例或设置applicationContextClass属性(通过JavaAPI或具有外部属性)。您希望作为业务逻辑运行的应用程序代码可以实现为CommandLineRunner作为一个@Bean定义。

76.属性和配置

本节包括有关设置和读取属性、配置设置及其与SpringBoot应用程序的交互的主题。

76.1在构建时自动展开属性

您可以使用现有的构建配置来自动展开这些属性,而不是硬编码项目的构建配置中也指定的一些属性。这在Maven和Gradle中都是可能的。

76.1.1使用Maven自动扩展属性

可以使用资源筛选从Maven项目自动展开属性。如果您使用spring-boot-starter-parent,然后您可以引用Maven的“项目属性”@..@占位符,如以下示例所示:

app.encoding=@project.build.sourceEncoding@
app.java.version=@java.version@
[Note]

只有产品配置是这样过滤的(换句话说,不对其应用过滤)。src/test/resources).

[Tip]

如果启用addResources旗子spring-boot:run目标可以添加src/main/resources直接到类路径(用于热重装)。这样做可以绕过资源筛选和此特性。相反,您可以使用exec:java目标或自定义插件的配置。见插件使用页面更多细节。

如果不使用初学者父级,则需要在<build/>元素pom.xml:

<resources>
	<resource>
		<directory>src/main/resources</directory>
		<filtering>true</filtering>
	</resource>
</resources>

您还需要在其中包含以下元素<plugins/>:

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-resources-plugin</artifactId>
	<version>2.7</version>
	<configuration>
		<delimiters>
			<delimiter>@</delimiter>
		</delimiters>
		<useDefaultDelimiters>false</useDefaultDelimiters>
	</configuration>
</plugin>
[Note]

这,这个,那,那个useDefaultDelimiters如果使用标准Spring占位符(如${placeholder})在您的配置中。如果该属性未设置为false,这些可以通过构建来扩展。

76.1.2使用分级自动扩展属性

您可以通过配置Java插件来自动扩展Gradle项目中的属性processResources这样做的任务,如以下示例所示:

processResources {
	expand(project.properties)
}

然后,可以使用占位符引用Gradle项目的属性,如以下示例所示:

app.name=${name}
app.description=${description}
[Note]

格拉德尔氏expand方法使用Groovy的SimpleTemplateEngine,它改变了${..}代币。这,这个,那,那个${..}样式与Spring自己的属性占位符机制相冲突。若要将Spring属性占位符与自动展开一起使用,请按以下方式转义Spring属性占位符:\${..}.

76.2外部化SpringApplication

SpringApplication有bean属性(主要是setter),所以在创建应用程序以修改其行为时,可以使用它的JavaAPI。或者,您可以通过在spring.main.*。例如,在application.properties,您可能具有以下设置:

spring.main.web-application-type=none
spring.main.banner-mode=off

然后SpringBoot横幅不会在启动时打印,应用程序也不会启动嵌入式Web服务器。

外部配置中定义的属性覆盖用Java API指定的值,但用于创建ApplicationContext。考虑以下申请:

new SpringApplicationBuilder()
	.bannerMode(Banner.Mode.OFF)
	.sources(demo.MyApp.class)
	.run(args);

现在考虑以下配置:

spring.main.sources=com.acme.Config,com.acme.ExtraConfig
spring.main.banner-mode=console

实际应用现在显示横幅(由配置覆盖),并使用三个源作为ApplicationContext(按以下顺序排列):demo.MyAppcom.acme.Config,和com.acme.ExtraConfig.

76.3更改应用程序外部属性的位置

默认情况下,来自不同来源的属性将添加到Spring中Environment按规定的顺序(见“第24章,外化配置“在‘SpringBoot特性’一节中得到确切的顺序)。

增加和修改此顺序的一个很好的方法是添加@PropertySource对应用程序源的注释。类传递给SpringApplication静态方便方法和使用setSources()检查他们是否有@PropertySources。如果有,则将这些属性添加到Environment的所有阶段都可以使用。ApplicationContext生命周期。以这种方式添加的属性比通过使用默认位置添加的属性具有更低的优先级(如application.properties)、系统属性、环境变量或命令行。

还可以提供以下系统属性(或环境变量)来更改行为:

  • spring.config.name (SPRING_CONFIG_NAME):默认为application作为文件名的根目录。
  • spring.config.location (SPRING_CONFIG_LOCATION):要加载的文件(例如类路径资源或URL)。单独的Environment属性源是为该文档设置的,它可以被系统属性、环境变量或命令行覆盖。

无论您在环境中设置了什么,SpringBoot总是加载application.properties如上文所述。默认情况下,如果使用YAML,那么扩展名为“.yml”的文件也会添加到列表中。

SpringBoot记录加载在DEBUG级别和它没有找到的候选人TRACE水平。

看见ConfigFileApplicationListener更多细节。

76.4使用“短”命令行参数

有些人喜欢使用(例如)--port=9000而不是--server.port=9000若要在命令行上设置配置属性,请执行以下操作。中的占位符可以启用此行为。application.properties,如以下示例所示:

server.port=${port:8080}
[Tip]

如果您从spring-boot-starter-parent对象的默认筛选器令牌pom。maven-resources-plugins已经从${*}@(也就是说,@maven.token@而不是${maven.token})以防止与Spring样式占位符发生冲突。如果已启用Maven筛选,则为application.properties直接地,您可能还想更改默认的筛选器令牌以使用其他定界符.

[Note]

在这种特殊情况下,端口绑定在PaaS环境(如Heroku或CloudFoundry)中工作。在这两个平台中,PORT环境变量自动设置,Spring可以绑定到大写同义词Environment财产。

76.5将YAML用于外部属性

YAML是JSON的超集,因此是以分层格式存储外部属性的方便语法,如以下示例所示:

spring:
	application:
		name: cruncher
	datasource:
		driverClassName: com.mysql.jdbc.Driver
		url: jdbc:mysql://localhost/test
server:
	port: 9000

创建一个名为application.yml把它放在你的类路径的根部。然后添加snakeyaml到依赖项(Maven坐标)org.yaml:snakeyaml,如果使用spring-boot-starter)将YAML文件解析为JavaMap<String,Object>(就像一个JSON对象),SpringBoot将地图平放,这样它就像许多人习惯的那样,具有一个层次深和周期分隔的键。PropertiesJava文件。

前面的示例YAML对应于以下内容application.properties档案:

spring.application.name=cruncher
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost/test
server.port=9000

见“第24.6节,“使用YAML而不是属性”“有关YAML的更多信息,请参见‘SpringBoot功能’部分。

76.6设置活动Spring配置文件

春天Environment有一个API,但是您通常会设置一个系统属性(spring.profiles.active)或OS环境变量(SPRING_PROFILES_ACTIVE)此外,您还可以使用-D参数(请记住将其放在主类或JAR存档之前),如下所示:

$ java -jar -Dspring.profiles.active=production demo-0.0.1-SNAPSHOT.jar

在SpringBoot中,还可以在application.properties,如以下示例所示:

spring.profiles.active=production

以这种方式将值集替换为系统属性或环境变量设置,而不是由SpringApplicationBuilder.profiles()方法。因此,后一种JavaAPI可以用于在不更改默认值的情况下增强概要文件。

见“第25章,剖面图在“SpringBoot功能”一节中获得更多信息。

76.7根据环境变化配置

YAML文件实际上是一系列由---行,每个文档分别解析成一个扁平的地图。

如果YAML文档包含spring.profiles键,则配置文件值(以逗号分隔的配置文件列表)输入Spring。Environment.acceptsProfiles()方法。如果其中任何一个配置文件是活动的,则该文档将包含在最后的合并中(否则,它不会),如下面的示例所示:

server:
	port: 9000
---

spring:
	profiles: development
server:
	port: 9001

---

spring:
	profiles: production
server:
	port: 0

在前面的示例中,默认端口是9000。但是,如果名为“Development”的Spring配置文件是活动的,那么端口是9001。如果“Production”处于活动状态,则端口为0。

[Note]

YAML文档按遇到它们的顺序合并。后面的值覆盖先前的值。

要对属性文件执行相同的操作,可以使用application-${profile}.properties若要指定特定于配置文件的值,请执行以下操作。

76.8发现外部属性的内置选项

Spring Boot绑定外部属性application.properties(或.yml文件和其他位置)在运行时进入应用程序。在单个位置上没有(技术上也不可能)列出所有受支持的属性,因为贡献可以来自类路径上的其他JAR文件。

具有Actuator特性的正在运行的应用程序具有configprops显示所有绑定和绑定属性的终结点。@ConfigurationProperties.

附录包括application.properties示例包含SpringBoot支持的最常见属性的列表。最终列表来自于搜索源代码@ConfigurationProperties@Value注释以及偶尔使用Binder。有关加载属性的确切顺序的更多信息,请参见“第24章,外化配置".

77.嵌入式Web服务器

每个SpringBootWeb应用程序都包括一个嵌入式Web服务器。这个特性带来了许多如何解决的问题,包括如何更改嵌入式服务器和如何配置嵌入式服务器。本节回答这些问题。

77.1使用另一个Web服务器

许多SpringBootStarter包括默认的嵌入式容器。

  • 对于servlet堆栈应用程序,spring-boot-starter-web包括Tomcatspring-boot-starter-tomcat,但你可以用spring-boot-starter-jettyspring-boot-starter-undertow相反。
  • 对于反应性堆栈应用程序,spring-boot-starter-webflux包括反应堆Nettyspring-boot-starter-reactor-netty,但你可以用spring-boot-starter-tomcatspring-boot-starter-jetty,或spring-boot-starter-undertow相反。

切换到不同的HTTP服务器时,除了包含所需的依赖项外,还需要排除默认的依赖项。SpringBoot为HTTP服务器提供了单独的启动程序,以帮助尽可能简化此过程。

下面的Maven示例展示了如何排除Tomcat并包含SpringMVC的JettyforSpringMVC:

<properties>
	<servlet-api.version>3.1.0</servlet-api.version>
</properties>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
	<exclusions>
		<!-- Exclude the Tomcat dependency -->
		<exclusion>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
		</exclusion>
	</exclusions>
</dependency>
<!-- Use Jetty instead -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
[Note]

The version of the Servlet API has been overridden as, unlike Tomcat 9 and Undertow 2.0, Jetty 9.4 does not support Servlet 4.0.

下面的Gradle示例演示了如何排除Netty,并包括SpringWebFlux的UndertoforSpringWebFlux:

configurations {
	// exclude Reactor Netty
	compile.exclude module: 'spring-boot-starter-reactor-netty'
}

dependencies {
	compile 'org.springframework.boot:spring-boot-starter-webflux'
	// Use Undertow instead
	compile 'org.springframework.boot:spring-boot-starter-undertow'
	// ...
}
[Note]

spring-boot-starter-reactor-netty必须使用WebClient类,因此即使需要包含不同的HTTP服务器,也可能需要保持对Netty的依赖。

77.2禁用Web服务器

如果类路径包含启动Web服务器所需的比特,SpringBoot将自动启动它。若要禁用此行为,请配置WebApplicationType在你的application.properties,如以下示例所示:

spring.main.web-application-type=none

77.3更改HTTP端口

在独立应用程序中,主HTTP端口默认为8080但是可以用server.port(例如,在application.properties或作为系统属性)。由于放宽了对.的约束Environment值,也可以使用SERVER_PORT(例如,作为OS环境变量)。

若要完全关闭HTTP端点,但仍要创建一个WebApplicationContext,使用server.port=-1。(这样做有时对测试很有用。)

有关详细信息,请参阅“第27.4.4节,“定制嵌入式servlet容器”“在‘SpringBoot特性’部分,或ServerProperties源代码。

77.4使用随机未分配的HTTP端口

若要扫描自由端口(使用OS本机防止冲突),请使用server.port=0.

77.5在运行时发现HTTP端口

您可以从日志输出或从ServletWebServerApplicationContext通过它WebServer。获得该值并确保它已初始化的最佳方法是添加@Bean类型ApplicationListener<ServletWebServerInitializedEvent>并在事件发布时将容器从事件中取出。

使用的测试@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)还可以通过使用@LocalServerPort注释,如以下示例所示:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
public class MyWebIntegrationTests {

	@Autowired
	ServletWebServerApplicationContext server;

	@LocalServerPort
	int port;

	// ...

}
[Note]

@LocalServerPort的元注释。@Value("${local.server.port}")。不要尝试在常规应用程序中注入端口。正如我们刚才看到的,只有在容器被初始化之后才会设置这个值。与测试相反,应用程序代码回调会提前处理(在实际可用值之前)。

77.6启用HTTP响应压缩

Http响应压缩由Jetty、Tomcat和安德托支持。可以在application.properties,如下:

server.compression.enabled=true

默认情况下,要执行压缩,响应长度必须至少为2048字节。可以通过设置server.compression.min-response-size财产。

默认情况下,只有当响应的内容类型为下列之一时,才会压缩其响应:

  • text/html
  • text/xml
  • text/plain
  • text/css
  • text/javascript
  • application/javascript
  • application/json
  • application/xml

可以通过设置server.compression.mime-types财产。

77.7配置SSL

可以通过设置各种server.ssl.*属性,通常在application.propertiesapplication.yml。下面的示例显示如何在application.properties:

server.port=8443
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=secret
server.ssl.key-password=another-secret

看见Ssl有关所有受支持属性的详细信息。

使用前面示例中的配置意味着应用程序不再支持端口8080处的普通HTTP连接器。Spring Boot不支持通过以下方式配置HTTP连接器和HTTPS连接器application.properties。如果希望两者兼得,则需要以编程方式配置其中之一。我们建议使用application.properties要配置HTTPS,HTTP连接器更容易以编程方式进行配置。见spring-boot-sample-tomcat-multi-connectors示例项目示例。

77.8配置HTTP/2

可以在SpringBoot应用程序中启用HTTP/2支持,server.http2.enabled配置属性。这种支持取决于所选择的Web服务器和应用程序环境,因为JDK 8不支持该协议。

[Note]

春靴不支持h2cHTTP/2协议的明文版本。所以你必须首先配置SSL.

77.8.1带有以下内容的HTTP/2

对于Ruby1.4.0+,支持HTTP/2,而不需要对JDK 8进行任何额外的要求。

77.8.2HTTP/2与Jetty

在Jetty9.4.8中,HTTP/2也被氪库。要启用这种支持,应用程序需要有两个额外的依赖项:org.eclipse.jetty:jetty-alpn-conscrypt-serverorg.eclipse.jetty.http2:http2-server.

使用Tomcat的77.8.3 HTTP/2

SpringBoot默认附带Tomcat9.0.x,它在使用JDK 9或更高版本时支持HTTP/2。或者,可以在JDK 8上使用HTTP/2,如果libtcnative库及其依赖项安装在主机操作系统上。

库文件夹必须可用(如果还没有)到JVM库路径。您可以使用jvm参数(如-Djava.library.path=/usr/local/opt/tomcat-native/lib。关于这一点的更多信息官方Tomcat文件.

在JDK 8上启动Tomcat 9.0.x,如果没有本机支持,将记录以下错误:

ERROR 8787 --- [           main] o.a.coyote.http11.Http11NioProtocol      : The upgrade handler [org.apache.coyote.http2.Http2Protocol] for [h2] only supports upgrade via ALPN but has been configured for the ["https-jsse-nio-8443"] connector that does not support ALPN.

此错误并不致命,应用程序仍然以HTTP/1.1SSL支持启动。

77.8.4带有反应堆Netty的HTTP/2

这,这个,那,那个spring-boot-webflux-starter默认情况下使用反应堆Netty作为服务器。使用JDK 9或更高版本的JDK支持,可以为HTTP/2配置ResiveNetty。对于JDK 8环境或最佳运行时性能,此服务器还支持带有本机库的HTTP/2。为此,应用程序需要有额外的依赖项。

Spring Boot管理io.netty:netty-tcnative-boringssl-static“uber jar”,包含所有平台的本机库。开发人员可以选择仅使用分类器导入所需的依赖项(请参阅Netty官方文件).

77.9配置Web服务器

通常,您应该首先考虑使用许多可用的配置键之一,并通过在application.properties(或application.yml,或环境等见“第76.8节,“发现外部属性的内置选项”“)这,这个,那,那个server.*命名空间在这里非常有用,它包括了如下所示的名称空间server.tomcat.*server.jetty.*而其他的则是针对特定于服务器的特性。见附录A,通用应用特性.

前面的部分已经介绍了许多常见的用例,例如压缩、SSL或HTTP/2。但是,如果用例中不存在配置密钥,则应该查看WebServerFactoryCustomizer。您可以声明这样的组件并访问与您的选择相关的服务器工厂:您应该为所选的服务器(Tomcat、Jetty、ReactiveNetty、Under拖车)和所选的Web堆栈(servlet或反应性)选择变量。

下面的示例用于Tomcatspring-boot-starter-web(servlet堆栈):

@Component
public class MyTomcatWebServerCustomizer
		implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

	@Override
	public void customize(TomcatServletWebServerFactory factory) {
		// customize the factory here
	}
}

此外,SpringBoot还提供:

服务器Servlet堆栈反应堆栈

猫猫

TomcatServletWebServerFactory

TomcatReactiveWebServerFactory

码头

JettyServletWebServerFactory

JettyReactiveWebServerFactory

下引

UndertowServletWebServerFactory

UndertowReactiveWebServerFactory

反应器

N/A

NettyReactiveWebServerFactory

一旦您可以访问WebServerFactory,您通常可以向其添加自定义器,以配置特定的部件,如连接器、服务器资源或服务器本身-所有这些都使用特定于服务器的API。

作为最后的手段,你也可以宣布你自己的WebServerFactory组件,它将覆盖SpringBoot提供的组件。在本例中,不能依赖server命名空间了。

77.10向应用程序添加servlet、过滤器或侦听器

在servlet堆栈应用程序中,即使用spring-boot-starter-web,有两种方法可以添加ServletFilterServletContextListener,以及ServletAPI对应用程序支持的其他侦听器:

77.10.1使用SpringBean添加servlet、过滤器或侦听器

若要添加ServletFilter,或Servlet*Listener通过使用Springbean,您必须提供一个@Bean它的定义。当您想注入配置或依赖项时,这样做非常有用。但是,您必须非常小心,以免它们导致太多其他bean的急切初始化,因为它们必须在应用程序生命周期的早期就安装在容器中。(例如,让它们依赖于您的DataSource或JPA配置)您可以通过在第一次使用时而不是在初始化时延迟初始化bean来绕过这些限制。

如属FiltersServlets,还可以添加映射和init参数。FilterRegistrationBean或者是ServletRegistrationBean代替或补充基础组件。

[Note]

如果没有dispatcherType在筛选器注册上指定,REQUEST被利用了。这与Servlet规范的默认Dispatcher类型是一致的。

与任何其他Springbean一样,您可以定义servlet过滤器bean的顺序;请确保检查“这一节名为“将servlet、过滤器和侦听器注册为Springbean”“分段。

禁用servlet或过滤器的注册

前文描述,任何ServletFilterbean自动在servlet容器中注册。若要禁用特定的注册,请执行以下操作FilterServletbean,为它创建一个注册bean并将其标记为禁用,如下面的示例所示:

@Bean
public FilterRegistrationBean registration(MyFilter filter) {
	FilterRegistrationBean registration = new FilterRegistrationBean(filter);
	registration.setEnabled(false);
	return registration;
}

77.10.2使用Classpath扫描添加servlet、过滤器和侦听器

@WebServlet@WebFilter,和@WebListener带注释的类可以自动在嵌入式servlet容器中注册。@Configuration@ServletComponentScan并指定包含要注册的组件的包。默认情况下,@ServletComponentScan从带注释的类的包中进行扫描。

77.11配置访问日志记录

访问日志可以通过各自的名称空间为Tomcat、Under拖车和Jetty配置。

例如,在Tomcat上使用定制模式.

server.tomcat.basedir=my-tomcat
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%t %a "%r" %s (%D ms)
[Note]

日志的默认位置是logs目录相对于Tomcat基目录。默认情况下,logs目录是一个临时目录,因此您可能希望修复Tomcat的基本目录或使用日志的绝对路径。在前面的示例中,日志可在my-tomcat/logs相对于应用程序的工作目录。

下面的访问日志可以类似的方式配置,如下面的示例所示:

server.undertow.accesslog.enabled=true
server.undertow.accesslog.pattern=%t %a "%r" %s (%D ms)

日志存储在logs相对于应用程序的工作目录。可以通过设置server.undertow.accesslog.directory财产。

最后,Jetty的访问日志也可以配置如下:

server.jetty.accesslog.enabled=true
server.jetty.accesslog.filename=/var/log/jetty-access.log

默认情况下,日志重定向到System.err。有关详细信息,请参阅码头文件.

77.12运行在前端代理服务器后面

您的应用程序可能需要发送302用绝对链接重定向或呈现内容。在代理后面运行时,调用方需要一个指向代理的链接,而不是指向承载应用程序的机器的物理地址的链接。通常,这样的情况是通过与代理的契约来处理的,代理会添加标题来告诉后端如何构造指向自己的链接。

如果代理添加常规X-Forwarded-ForX-Forwarded-Proto头(大多数代理服务器都这样做),应该正确地呈现绝对链接,前提是server.use-forward-headers设置为true在你的application.properties.

[Note]

如果应用程序在CloudFoundry或Heroku中运行,则server.use-forward-headers属性默认值为true。在所有其他情况下,它默认为false.

77.12.1自定义Tomcat的代理配置

如果使用Tomcat,则还可以配置用于携带“转发”信息的标头的名称,如下面的示例所示:

server.tomcat.remote-ip-header=x-your-remote-ip-header
server.tomcat.protocol-header=x-your-protocol-header

Tomcat还配置了一个与要信任的内部代理匹配的默认正则表达式。默认情况下,10/8192.168/16169.254/16127/8是值得信任的。您可以自定义阀门的配置,方法是在application.properties,如以下示例所示:

server.tomcat.internal-proxies=192\\.168\\.\\d{1,3}\\.\\d{1,3}
[Note]

只有在使用属性文件进行配置时才需要双反斜杠。如果使用YAML,则单反斜杠就足够了,与前面示例中所示的值相等的值将为192\.168\.\d{1,3}\.\d{1,3}.

[Note]

通过设置internal-proxies空(但不要在生产中这样做)。

您可以完全控制Tomcat的配置RemoteIpValve通过关闭自动开关(为此,设置server.use-forward-headers=false)中添加了一个新的阀门实例。TomcatServletWebServerFactory豆子

77.13使用Tomcat启用多个连接器

您可以添加一个org.apache.catalina.connector.ConnectorTomcatServletWebServerFactory,它允许多个连接器,包括HTTP和HTTPS连接器,如以下示例所示:

@Bean
public ServletWebServerFactory servletContainer() {
	TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
	tomcat.addAdditionalTomcatConnectors(createSslConnector());
	return tomcat;
}

private Connector createSslConnector() {
	Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
	Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
	try {
		File keystore = new ClassPathResource("keystore").getFile();
		File truststore = new ClassPathResource("keystore").getFile();
		connector.setScheme("https");
		connector.setSecure(true);
		connector.setPort(8443);
		protocol.setSSLEnabled(true);
		protocol.setKeystoreFile(keystore.getAbsolutePath());
		protocol.setKeystorePass("changeit");
		protocol.setTruststoreFile(truststore.getAbsolutePath());
		protocol.setTruststorePass("changeit");
		protocol.setKeyAlias("apitester");
		return connector;
	}
	catch (IOException ex) {
		throw new IllegalStateException("can't access keystore: [" + "keystore"
				+ "] or truststore: [" + "keystore" + "]", ex);
	}
}

77.14使用Tomcat的LegacyCookieProcessor

默认情况下,SpringBoot使用的嵌入式Tomcat不支持Cookie格式的“Version 0”,因此您可能会看到以下错误:

java.lang.IllegalArgumentException: An invalid character [32] was present in the Cookie value

如果可能的话,您应该考虑更新代码,使其只存储符合后续Cookie规范的值。但是,如果不能更改cookie的编写方式,则可以将Tomcat配置为使用LegacyCookieProcessor。切换到LegacyCookieProcessor,使用WebServerFactoryCustomizerbean,它添加了一个TomcatContextCustomizer,如以下示例所示:

@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieProcessorCustomizer() {
	return (factory) -> factory.addContextCustomizers(
			(context) -> context.setCookieProcessor(new LegacyCookieProcessor()));
}

77.15使用以下方式启用多个侦听器

添加一个UndertowBuilderCustomizerUndertowServletWebServerFactory并将侦听器添加到Builder,如以下示例所示:

@Bean
public UndertowServletWebServerFactory servletWebServerFactory() {
	UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
	factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {

		@Override
		public void customize(Builder builder) {
			builder.addHttpListener(8080, "0.0.0.0");
		}

	});
	return factory;
}

77.16使用@ServerEndpoint创建WebSocketEndpoint

如果你想用@ServerEndpoint在使用嵌入式容器的SpringBoot应用程序中,必须声明一个ServerEndpointExporter @Bean,如以下示例所示:

@Bean
public ServerEndpointExporter serverEndpointExporter() {
	return new ServerEndpointExporter();
}

前面示例中显示的bean注册任何@ServerEndpoint带有基础WebSocket容器的注释bean。当部署到独立servlet容器时,此角色由servlet容器初始化器执行,ServerEndpointExporterbean不是必需的。

78.SpringMVC

SpringBoot有许多启动程序,包括SpringMVC。请注意,有些初学者包括对SpringMVC的依赖,而不是直接包含它。本节回答关于SpringMVC和SpringBoot的常见问题。

78.1编写JSON REST服务

任何春天@RestController在SpringBoot应用程序中,只要Jackson 2在类路径上,默认情况下应该呈现JSON响应,如下面的示例所示:

@RestController
public class MyController {

	@RequestMapping("/thing")
	public MyThing thing() {
			return new MyThing();
	}

}

只要MyThing可以由Jackson 2(对于普通POJO或Groovy对象为true)序列化,然后localhost:8080/thing默认情况下为它提供JSON表示。请注意,在浏览器中,有时可能会看到XML响应,因为浏览器倾向于发送更喜欢XML的接受标头。

78.2编写XML REST服务

如果您有Jackson XML扩展(jackson-dataformat-xml)在类路径上,您可以使用它来呈现XML响应。我们用于JSON的前面的示例将起作用。若要使用Jackson XML呈现程序,请将以下依赖项添加到项目中:

<dependency>
	<groupId>com.fasterxml.jackson.dataformat</groupId>
	<artifactId>jackson-dataformat-xml</artifactId>
</dependency>

您还可能希望添加对Woodstox的依赖。它比JDK提供的默认StAX实现更快,还添加了漂亮的打印支持和改进的命名空间处理。下面的清单显示了如何将依赖项包含在伍德斯托克斯:

<dependency>
	<groupId>org.codehaus.woodstox</groupId>
	<artifactId>woodstox-core-asl</artifactId>
</dependency>

如果Jackson的XML扩展不可用,则使用JAXB(默认情况下在JDK中提供),另外还要求MyThing注释为@XmlRootElement,如以下示例所示:

@XmlRootElement
public class MyThing {
	private String name;
	// .. getters and setters
}

要使服务器呈现XML而不是JSON,您可能需要发送一个Accept: text/xml标题(或使用浏览器)。

78.3自定义Jackson ObjectMapper

SpringMVC(客户机和服务器端)使用HttpMessageConverters若要协商HTTP交换中的内容转换,请执行以下操作。如果Jackson在类路径上,则您已经获得了由Jackson2ObjectMapperBuilder的实例是为您自动配置的。

这,这个,那,那个ObjectMapper(或XmlMapper对于Jackson XML转换器)实例(默认情况下创建)具有以下自定义属性:

  • MapperFeature.DEFAULT_VIEW_INCLUSION残废
  • DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES残废
  • SerializationFeature.WRITE_DATES_AS_TIMESTAMPS残废

SpringBoot还提供了一些特性,使定制这种行为更加容易。

您可以配置ObjectMapperXmlMapper通过使用环境执行实例。Jackson提供了一系列简单的ON/OFF功能,可用于配置处理的各个方面。在映射到环境中的属性的六个枚举(在Jackson中)中描述了这些特性:

Enum财产价值

com.fasterxml.jackson.databind.DeserializationFeature

spring.jackson.deserialization.<feature_name>

truefalse

com.fasterxml.jackson.core.JsonGenerator.Feature

spring.jackson.generator.<feature_name>

truefalse

com.fasterxml.jackson.databind.MapperFeature

spring.jackson.mapper.<feature_name>

truefalse

com.fasterxml.jackson.core.JsonParser.Feature

spring.jackson.parser.<feature_name>

truefalse

com.fasterxml.jackson.databind.SerializationFeature

spring.jackson.serialization.<feature_name>

truefalse

com.fasterxml.jackson.annotation.JsonInclude.Include

spring.jackson.default-property-inclusion

alwaysnon_nullnon_absentnon_defaultnon_empty

例如,要启用漂亮的打印,请设置spring.jackson.serialization.indent_output=true。请注意,由于使用了松弛结合,案件indent_output不需要匹配对应的枚举常量的情况,即INDENT_OUTPUT.

此基于环境的配置应用于自动配置。Jackson2ObjectMapperBuilder并应用于通过使用构建器创建的任何映射器,包括自动配置的ObjectMapper豆子

语境Jackson2ObjectMapperBuilder可以由一个或多个自定义Jackson2ObjectMapperBuilderCustomizer豆子这样的定制bean可以被订购(Boot自己的定制器的订单为0),允许在Boot自定义之前和之后应用额外的定制。

任何类型的豆类com.fasterxml.jackson.databind.Module将自动注册到自动配置的Jackson2ObjectMapperBuilder并适用于任何ObjectMapper它创建的实例。这提供了在向应用程序添加新功能时提供自定义模块的全局机制。

如果要替换默认值ObjectMapper完全,要么定义@Bean并将其标记为@Primary或者,如果您更喜欢基于构建器的方法,则定义Jackson2ObjectMapperBuilder@Bean。注意,在任何一种情况下,这样做都会禁用ObjectMapper.

如果你提供任何@Beans类型MappingJackson2HttpMessageConverter,它们替换了MVC配置中的默认值。另外,一个类型的方便beanHttpMessageConverters提供(如果使用默认的MVC配置,则始终可用)。它有一些有用的方法来访问默认的和用户增强的消息转换器。

见“第78.4节,“自定义@ResponseBody呈现”“分段和WebMvcAutoConfiguration有关更多细节的源代码。

78.4自定义@ResponseBody呈现

弹簧使用HttpMessageConverters渲染@ResponseBody(或来自@RestController)您可以通过在SpringBoot上下文中添加适当类型的bean来贡献额外的转换器。如果您添加的bean是默认包含的类型(如MappingJackson2HttpMessageConverter对于JSON转换),它将替换默认值。一种方便型豆类HttpMessageConverters如果使用默认的MVC配置,则始终可用。它有一些有用的方法来访问默认的和用户增强的消息转换器(例如,如果您想手动将它们注入到自定义中,则可能很有用。)RestTemplate).

与正常的mvc用法一样,任何WebMvcConfigurer您提供的bean还可以通过覆盖configureMessageConverters方法。但是,与普通的MVC不同,您只能提供所需的额外转换器(因为SpringBoot使用相同的机制来贡献其缺省值)。最后,如果您选择退出SpringBoot默认MVC配置,提供您自己的@EnableWebMvc配置,您可以完全控制并手动执行所有操作。getMessageConverters从…WebMvcConfigurationSupport.

WebMvcAutoConfiguration有关更多细节的源代码。

78.5处理多部分文件上载

Spring Boot包含Servlet 3javax.servlet.http.PartAPI支持上传文件。默认情况下,SpringBoot在单个请求中配置SpringMVC,最大大小为每个文件1MB,文件数据最多为10 MB。您可以重写这些值,即存储中间数据的位置(例如,到/tmp目录),以及通过使用公开的属性将数据刷新到磁盘的阈值。MultipartProperties班级,等级例如,如果要指定文件是无限的,请将spring.servlet.multipart.max-file-size财产-1.

当您希望将多部分编码的文件数据作为@RequestParam-带注释的类型参数MultipartFile在SpringMVC控制器处理程序方法中。

MultipartAutoConfiguration有关更多细节的消息来源。

78.6关闭SpringMVC DispatcherServlet

默认情况下,所有内容都来自应用程序的根(/)如果您希望映射到另一条路径,则可以按以下方式配置路径:

spring.mvc.servlet.path=/acme

如果有其他servlet,则可以声明@Bean类型ServletServletRegistrationBean对于每个和SpringBoot,它们将透明地注册到容器中。因为servlet是以这种方式注册的,所以可以将它们映射到DispatcherServlet而不调用它。

配置DispatcherServlet你自己是不寻常的,但如果你真的需要这样做,@Bean类型DispatcherServletPath还必须提供自定义路径的方法。DispatcherServlet.

78.7关闭默认MVC配置

要完全控制mvc配置,最简单的方法是提供您自己的@Configuration带着@EnableWebMvc注释这样做的话,所有的MVC配置都将掌握在您的手中。

78.8自定义视图转换器

ViewResolver是SpringMVC的核心组件,在@Controller到实际View实现。请注意ViewResolvers主要用于ui应用程序,而不是REST样式的服务(View不用于呈现@ResponseBody)的实现有很多种。ViewResolver选择和Spring本身并不是关于您应该使用哪一种选择的意见。另一方面,Spring Boot为您安装一个或两个,这取决于它在类路径和应用程序上下文中找到了什么。这,这个,那,那个DispatcherServlet使用它在应用程序上下文中找到的所有解析器,依次尝试每个解析器,直到得到结果为止,因此,如果添加自己的解析器,则必须知道顺序和添加解析器的位置。

WebMvcAutoConfiguration添加以下内容ViewResolvers关于你的背景:

  • InternalResourceViewResolver名为“defaultViewResolver”。此方法定位可以通过使用DefaultServlet(如果使用静态资源和JSP页面,则包括这些页面)。它将前缀和后缀应用于视图名称,然后在servlet上下文中查找具有该路径的物理资源(默认值均为空,但可通过以下方式进行外部配置)spring.mvc.view.prefixspring.mvc.view.suffix)您可以通过提供相同类型的bean来覆盖它。
  • BeanNameViewResolver名为“beanNameViewResolver”。这是视图解析器链的有用成员,并获取与View被解决了。不应该有必要重写或替换它。
  • ContentNegotiatingViewResolver名为“viewResolver”的实际上是豆类View现在时这是一个“主”解析器,它将委托给所有其他解析器,并试图找到与客户端发送的“接受”HTTP头匹配的内容。有一个有用的博客ContentNegotiatingViewResolver您可能希望学习更多,也可以查看源代码以获得详细信息。您可以关闭自动配置的ContentNegotiatingViewResolver通过定义一个名为“viewResolver”的bean。
  • 如果您使用Thymeleaf,您也有一个ThymeleafViewResolver名为“hymeleafViewResolver”。它通过用前缀和后缀包围视图名称来查找资源。前缀是spring.thymeleaf.prefix,后缀是spring.thymeleaf.suffix。前缀和后缀的值分别默认为“classpath:/模板/”和“.html”。你可以覆盖ThymeleafViewResolver通过提供同名的bean。
  • 如果您使用FreeMarker,您也有一个FreeMarkerViewResolver名为“FreeMarkerViewResolver”。它在加载程序路径中查找资源(外部化为spring.freemarker.templateLoaderPath并以前缀和后缀包围视图名称,其默认值为“classpath:/Template/”。前缀外部化为spring.freemarker.prefix,并且后缀被外部化为spring.freemarker.suffix。前缀和后缀的默认值分别为空和.ftl。你可以覆盖FreeMarkerViewResolver通过提供同名的bean。
  • 如果使用Groovy模板(实际上,如果groovy-templates在您的类路径上),您也有一个GroovyMarkupViewResolver名为“groovyMarkupViewResolver”。它在加载程序路径中查找资源,方法是在视图名称周围加上前缀和后缀(外部化为spring.groovy.template.prefixspring.groovy.template.suffix)前缀和后缀的默认值分别为“classpath:/模板/”和“.tpl”。你可以覆盖GroovyMarkupViewResolver通过提供同名的bean。

有关更多细节,请参见以下各节:

79.用Spring安全性进行测试

SpringSecurity支持以特定用户的身份运行测试。例如,下面的代码段中的测试将与具有ADMIN角色。

@Test
@WithMockUser(roles="ADMIN")
public void requestProtectedUrlWithUser() throws Exception {
	mvc
		.perform(get("/"))
		...
}

SpringSecurity提供了与SpringMVC测试的全面集成,这也可以用于使用@WebMvcTest切片和MockMvc.

有关SpringSecurity的测试支持的详细信息,请参阅SpringSecurity的参考文献).

80.泽西

80.1使用Spring安全保护泽西端点

SpringSecurity可以用于保护基于泽西岛的Web应用程序,其方式与用于保护基于SpringMVC的Web应用程序的方式非常相似。但是,如果您想在泽西使用SpringSecurity的方法级安全性,则必须将泽西配置为使用setStatus(int)相反sendError(int)。这使泽西无法在SpringSecurity有机会向客户端报告身份验证或授权失败之前提交响应。

这,这个,那,那个jersey.config.server.response.setStatusOverSendError属性必须设置为true关于申请ResourceConfigbean,如以下示例所示:

@Component
public class JerseyConfig extends ResourceConfig {

	public JerseyConfig() {
		register(Endpoint.class);
		setProperties(Collections.singletonMap(
				"jersey.config.server.response.setStatusOverSendError", true));
	}

}

81.http客户端

SpringBoot提供了许多与HTTP客户端一起工作的启动程序。本节回答与使用它们有关的问题。

81.1配置RestTemplate以使用代理

如上文所述第33.1节,“餐厅模板定制”,您可以使用RestTemplateCustomizer带着RestTemplateBuilder要构建自定义的RestTemplate。这是创建RestTemplate配置为使用代理。

代理配置的确切细节取决于正在使用的底层客户端请求工厂。下面的示例配置HttpComponentsClientRequestFactory带着HttpClient,它对所有主机都使用一个代理,除了192.168.0.5:

static class ProxyCustomizer implements RestTemplateCustomizer {

	@Override
	public void customize(RestTemplate restTemplate) {
		HttpHost proxy = new HttpHost("proxy.example.com");
		HttpClient httpClient = HttpClientBuilder.create()
				.setRoutePlanner(new DefaultProxyRoutePlanner(proxy) {

					@Override
					public HttpHost determineProxy(HttpHost target,
							HttpRequest request, HttpContext context)
							throws HttpException {
						if (target.getHostName().equals("192.168.0.5")) {
							return null;
						}
						return super.determineProxy(target, request, context);
					}

				}).build();
		restTemplate.setRequestFactory(
				new HttpComponentsClientHttpRequestFactory(httpClient));
	}

}

82.测井

SpringBoot没有强制的日志记录依赖项,但CommonsLoggingAPI除外,它通常由Spring框架的spring-jcl模块。使用Logback,你需要把它包括进去spring-jcl在类路径上。做到这一点的最简单的方法是通过启动程序,这都依赖于spring-boot-starter-logging。对于web应用程序,只需spring-boot-starter-web,因为它依赖于日志记录启动程序。如果使用Maven,下面的依赖项将为您添加日志记录:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

春靴LoggingSystem试图根据类路径的内容配置日志记录的抽象。如果登录是可用的,这是第一选择。

如果您需要对日志记录所做的唯一更改是设置各种记录器的级别,则可以在application.properties通过使用“logging.level”前缀,如下面的示例所示:

logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR

还可以使用“logging.file”设置要写入日志的文件的位置(除了控制台)。

若要配置日志系统的更细粒度设置,需要使用LoggingSystem有疑问。默认情况下,SpringBoot从系统的默认位置获取本机配置(如classpath:logback.xml,但是可以使用“logging.config”属性设置配置文件的位置。

82.1为日志配置Logback

如果你把logback.xml在您的类路径的根,它是从那里(或从logback-spring.xml,以利用Boot提供的模板功能)。SpringBoot提供了一个默认的基本配置,如果您想设置级别,可以包括它,如下面的示例所示:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
	<include resource="org/springframework/boot/logging/logback/base.xml"/>
	<logger name="org.springframework.web" level="DEBUG"/>
</configuration>

如果你看看base.xml在Spring-boot jar中,您可以看到它使用了一些有用的系统属性,LoggingSystem负责为您创建:

  • ${PID}*当前进程ID。
  • ${LOG_FILE}*是否logging.file设置在Boot的外部配置中。
  • ${LOG_PATH}*是否logging.path(表示日志文件驻留的目录)在Boot的外部配置中设置。
  • ${LOG_EXCEPTION_CONVERSION_WORD}*是否logging.exception-conversion-word设置在Boot的外部配置中。

SpringBoot还通过使用自定义的Logback转换器在控制台(但不是在日志文件中)提供一些很好的ANSI彩色终端输出。参见默认值base.xml详细配置。

如果Groovy在类路径上,您应该能够用logback.groovy也是如果存在,则优先考虑此设置。

82.1.1为纯文件输出配置Logback

如果要禁用控制台日志记录并只将输出写入文件,则需要自定义logback-spring.xml进口file-appender.xml但不是console-appender.xml,如以下示例所示:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
	<include resource="org/springframework/boot/logging/logback/defaults.xml" />
	<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
	<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
	<root level="INFO">
		<appender-ref ref="FILE" />
	</root>
</configuration>

您还需要添加logging.file敬你的application.properties,如以下示例所示:

logging.file=myapplication.log

82.2配置用于日志记录的Log4j

弹簧启动支架Log4j 2如果它位于类路径上,则用于日志配置。如果将启动程序用于组装依赖项,则必须排除Logback,然后包含log4j2。如果不使用启动程序,则需要提供(至少)spring-jcl除了Log4j 2。

最简单的路径可能是通过启动,尽管它需要一些与排除。下面的示例演示如何在Maven中设置Starter:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter</artifactId>
	<exclusions>
		<exclusion>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-logging</artifactId>
		</exclusion>
	</exclusions>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

下面的示例展示了在Gradle中设置Starter的一种方法:

dependencies {
	compile 'org.springframework.boot:spring-boot-starter-web'
	compile 'org.springframework.boot:spring-boot-starter-log4j2'
}

configurations {
	all {
		exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
	}
}
[Note]

Log4j启动程序将常见日志记录需求的依赖项集合在一起(例如让Tomcat使用)。java.util.logging但是使用Log4j 2配置输出)。见执行机构Log4j 2更详细的样品,并看到它的行动。

[Note]

以确保使用java.util.logging被路由到Log4j 2中,配置其JDK日志适配器通过设置java.util.logging.manager系统属性org.apache.logging.log4j.jul.LogManager.

82.2.1使用YAML或JSON配置Log4j 2

除了默认的XML配置格式之外,Log4j 2还支持YAML和JSON配置文件。若要将Log4j 2配置为使用替代配置文件格式,请将适当的依赖项添加到类路径中,并将配置文件命名为与所选文件格式匹配的配置文件,如下面的示例所示:

格式相依性文件名

YAML

com.fasterxml.jackson.core:jackson-databindcom.fasterxml.jackson.dataformat:jackson-dataformat-yaml

log4j2.yaml log4j2.yml

杰森

com.fasterxml.jackson.core:jackson-databind

log4j2.json log4j2.jsn

83.数据存取

SpringBoot包括许多用于处理数据源的启动程序。本节回答与此相关的问题。

83.1配置自定义数据源

配置自己的DataSource,定义@Bean在你的配置中。Spring Boot重用您的DataSource任何需要的地方,包括数据库初始化。如果需要将某些设置外部化,则可以绑定DataSource对环境的影响(见“第24.7.1节,“第三方配置””).

下面的示例演示如何在bean中定义数据源:

@Bean
@ConfigurationProperties(prefix="app.datasource")
public DataSource dataSource() {
	return new FancyDataSource();
}

下面的示例演示如何通过设置属性来定义数据源:

app.datasource.url=jdbc:h2:mem:mydb
app.datasource.username=sa
app.datasource.pool-size=30

假设你FancyDataSource具有URL、用户名和池大小的常规JavaBean属性,这些设置在DataSource提供给其他组件。常客数据库初始化也会发生(所以相关的子集spring.datasource.*仍然可以与您的自定义配置一起使用)。

如果配置自定义JNDI,则可以应用相同的原则。DataSource,如以下示例所示:

@Bean(destroyMethod="")
@ConfigurationProperties(prefix="app.datasource")
public DataSource dataSource() throws Exception {
	JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
	return dataSourceLookup.getDataSource("java:comp/env/jdbc/YourDS");
}

SpringBoot还提供了一个实用程序生成器类,称为DataSourceBuilder,它可以用于创建标准数据源之一(如果它位于类路径上)。构建器可以根据类路径上可用的内容来检测要使用的对象。它还可以根据JDBCURL自动检测驱动程序。

下面的示例演示如何使用DataSourceBuilder:

@Bean
@ConfigurationProperties("app.datasource")
public DataSource dataSource() {
	return DataSourceBuilder.create().build();
}

用它运行一个应用程序DataSource,您所需要的只是连接信息。还可以提供特定于池的设置。有关更多细节,请检查将在运行时使用的实现。

下面的示例演示如何通过设置属性来定义JDBC数据源:

app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.pool-size=30

然而,有一个陷阱。由于未公开连接池的实际类型,因此在您的自定义元数据中不会生成任何键。DataSource而且您的IDE中没有可用的完成(因为DataSource接口不公开属性)。此外,如果您碰巧在类路径上有Hikari,则此基本设置不起作用,因为Hikari没有url属性(但确实有jdbcUrl财产)。在这种情况下,您必须按照以下方式重写您的配置:

app.datasource.jdbc-url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.maximum-pool-size=30

您可以通过强制连接池使用并返回专用实现来解决这个问题,而不是DataSource。不能在运行时更改实现,但选项列表将是显式的。

下面的示例演示如何创建HikariDataSource带着DataSourceBuilder:

@Bean
@ConfigurationProperties("app.datasource")
public HikariDataSource dataSource() {
	return DataSourceBuilder.create().type(HikariDataSource.class).build();
}

你甚至可以通过利用DataSourceProperties为您做-也就是说,提供一个默认的嵌入式数据库与一个合理的用户名和密码,如果没有提供URL。您可以很容易地初始化DataSourceBuilder从任何DataSourceProperties对象,因此您还可以注入SpringBoot自动创建的DataSource。但是,这将您的配置分为两个名称空间:urlusernamepasswordtype,和driver在……上面spring.datasource其余的在您的自定义命名空间上(app.datasource)为了避免这种情况,您可以重新定义一个自定义。DataSourceProperties在您的自定义命名空间上,如下面的示例所示:

@Bean
@Primary
@ConfigurationProperties("app.datasource")
public DataSourceProperties dataSourceProperties() {
	return new DataSourceProperties();
}

@Bean
@ConfigurationProperties("app.datasource")
public HikariDataSource dataSource(DataSourceProperties properties) {
	return properties.initializeDataSourceBuilder().type(HikariDataSource.class)
			.build();
}

这个设置让你同步默认情况下,SpringBoot为您做了什么,只是选择了一个专用连接池(在代码中),并且在同一个命名空间中公开了它的设置。因为DataSourceProperties是照顾url/jdbcUrl为您翻译,您可以按以下方式配置它:

app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.maximum-pool-size=30
[Note]

因为您的自定义配置选择了Hikari,app.datasource.type没有效果。实际上,构建器是用您在那里设置的任何值初始化的,然后通过调用.type().

见“第29.1节,“配置数据源”“在”SpringBoot特性“部分和DataSourceAutoConfiguration获取更多详细信息。

83.2配置两个DataSources

如果需要配置多个数据源,则可以应用上一节中描述的相同技巧。但是,您必须标记其中一个DataSource实例@Primary,因为道路上的各种自动配置都希望能够按类型获得一个。

如果你自己创造DataSource,自动配置退出。在下面的示例中,我们提供了精确性与自动配置在主数据源上提供的特性集相同:

@Bean
@Primary
@ConfigurationProperties("app.datasource.first")
public DataSourceProperties firstDataSourceProperties() {
	return new DataSourceProperties();
}

@Bean
@Primary
@ConfigurationProperties("app.datasource.first")
public DataSource firstDataSource() {
	return firstDataSourceProperties().initializeDataSourceBuilder().build();
}

@Bean
@ConfigurationProperties("app.datasource.second")
public BasicDataSource secondDataSource() {
	return DataSourceBuilder.create().type(BasicDataSource.class).build();
}
[Tip]

firstDataSourceProperties必须标记为@Primary以便数据库初始化器功能使用您的副本(如果使用初始化程序)。

这两个数据源也为高级自定义绑定。例如,您可以按照以下方式配置它们:

app.datasource.first.type=com.zaxxer.hikari.HikariDataSource
app.datasource.first.maximum-pool-size=30

app.datasource.second.url=jdbc:mysql://localhost/test
app.datasource.second.username=dbuser
app.datasource.second.password=dbpass
app.datasource.second.max-total=30

您可以将相同的概念应用于二级DataSource同样,如以下示例所示:

@Bean
@Primary
@ConfigurationProperties("app.datasource.first")
public DataSourceProperties firstDataSourceProperties() {
	return new DataSourceProperties();
}

@Bean
@Primary
@ConfigurationProperties("app.datasource.first")
public DataSource firstDataSource() {
	return firstDataSourceProperties().initializeDataSourceBuilder().build();
}

@Bean
@ConfigurationProperties("app.datasource.second")
public DataSourceProperties secondDataSourceProperties() {
	return new DataSourceProperties();
}

@Bean
@ConfigurationProperties("app.datasource.second")
public DataSource secondDataSource() {
	return secondDataSourceProperties().initializeDataSourceBuilder().build();
}

前面的示例使用SpringBoot在自动配置中使用的相同逻辑在自定义命名空间上配置两个数据源。

83.3使用Spring数据存储库

Spring数据可以创建@Repository各种口味的界面。Spring Boot为您处理所有这些,只要那些@Repositories的包(或子包)中包含。@EnableAutoConfiguration班级,等级

对于许多应用程序,只需在类路径上放置正确的Spring数据依赖项(有一个spring-boot-starter-data-jpa对于JPA和一个spring-boot-starter-data-mongodb(对于MongoDB),并创建一些存储库接口来处理@Entity物品。示例在JPA样品MongoDB样本.

Spring Boot试图猜测您@Repository定义,根据@EnableAutoConfiguration它找到了。若要获得更多控制,请使用@EnableJpaRepositories注释(来自SpringDataJPA)。

有关Spring数据的更多信息,请参见春季数据项目页面.

83.4将@实体定义与Spring配置分开

Spring Boot试图猜测您@Entity定义,根据@EnableAutoConfiguration它找到了。要获得更多的控制,可以使用@EntityScan注释,如以下示例所示:

@Configuration
@EnableAutoConfiguration
@EntityScan(basePackageClasses=City.class)
public class Application {

	//...

}

83.5配置JPA属性

SpringDataJPA已经提供了一些与供应商无关的配置选项(例如用于SQL日志记录的配置选项),SpringBoot将这些选项以及Hibernate的一些选项公开为外部配置属性。其中一些是根据上下文自动检测到的,因此您不需要设置它们。

这,这个,那,那个spring.jpa.hibernate.ddl-auto是一个特例,因为根据运行时条件,它有不同的默认值。如果使用嵌入式数据库,并且没有架构管理器(如Liquibase或Flyway)处理DataSource,默认为create-drop。在所有其他情况下,它默认为none.

要使用的方言也会根据当前的DataSource,但你可以spring.jpa.database如果你想要显式的,并且绕过启动时的检查,那就是你自己。

[Note]

指定database导致配置一个定义良好的Hibernate方言。多个数据库有多个Dialect,这可能不适合你的需要。在这种情况下,您可以设置spring.jpa.databasedefault通过设置spring.jpa.database-platform财产。

下面的示例显示了最常用的设置选项:

spring.jpa.hibernate.naming.physical-strategy=com.example.MyPhysicalNamingStrategy
spring.jpa.show-sql=true

此外,spring.jpa.properties.*作为普通的jpa属性传递(前缀去掉了前缀)。EntityManagerFactory是被创造出来的。

[Tip]

如果需要将高级自定义应用于Hibernate属性,请考虑注册HibernatePropertiesCustomizer类之前将调用的bean。EntityManagerFactory。这优先于任何由自动配置应用的内容。

83.6配置Hibernate命名策略

Hibernate使用两种不同的命名策略若要将名称从对象模型映射到相应的数据库名称,请执行以下操作。物理和隐式策略实现的完全限定类名可以通过设置spring.jpa.hibernate.naming.physical-strategyspring.jpa.hibernate.naming.implicit-strategy分别属性。或者,如果ImplicitNamingStrategyPhysicalNamingStrategybean在应用程序上下文中可用,Hibernate将被自动配置为使用它们。

默认情况下,SpringBoot使用SpringPhysicalNamingStrategy。此实现提供了与Hibernate 4相同的表结构:所有点都被下划线替换,camel大小写也被下划线替换。默认情况下,所有表名都以小写形式生成,但如果架构需要该标志,则可以重写该标志。

例如,TelephoneNumber实体映射到telephone_number桌子

如果您更喜欢使用Hibernate 5的默认设置,请设置以下属性:

spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

或者,您可以配置以下bean:

@Bean
public PhysicalNamingStrategy physicalNamingStrategy() {
	return new PhysicalNamingStrategyStandardImpl();
}

看见HibernateJpaAutoConfigurationJpaBaseConfiguration更多细节。

83.7使用自定义EntityManagerFactory

控件的配置完全控制EntityManagerFactory,您需要添加一个@Bean名为“实体经理工厂”。Spring Boot自动配置在存在该类型bean的情况下关闭其实体管理器。

83.8使用两个实体管理器

即使默认EntityManagerFactory很好,你需要定义一个新的。否则,该类型的第二个bean的存在将关闭默认值。为了便于操作,您可以使用方便。EntityManagerBuilder由SpringBoot提供。或者,您可以只在LocalContainerEntityManagerFactoryBean直接来自SpringORM,如下面的示例所示:

// add two data sources configured as above

@Bean
public LocalContainerEntityManagerFactoryBean customerEntityManagerFactory(
		EntityManagerFactoryBuilder builder) {
	return builder
			.dataSource(customerDataSource())
			.packages(Customer.class)
			.persistenceUnit("customers")
			.build();
}

@Bean
public LocalContainerEntityManagerFactoryBean orderEntityManagerFactory(
		EntityManagerFactoryBuilder builder) {
	return builder
			.dataSource(orderDataSource())
			.packages(Order.class)
			.persistenceUnit("orders")
			.build();
}

上面的配置几乎是独立工作的。要完成图片,您需要配置TransactionManagers对于这两个人EntityManagers也是如果你把其中一个标记为@Primary,它可以在默认情况下被捡起。JpaTransactionManager春靴。另一个必须显式地注入到一个新实例中。或者,您可以使用跨两者的JTA事务管理器。

如果使用Spring数据,则需要配置@EnableJpaRepositories因此,如以下示例所示:

@Configuration
@EnableJpaRepositories(basePackageClasses = Customer.class,
		entityManagerFactoryRef = "customerEntityManagerFactory")
public class CustomerConfiguration {
	...
}

@Configuration
@EnableJpaRepositories(basePackageClasses = Order.class,
		entityManagerFactoryRef = "orderEntityManagerFactory")
public class OrderConfiguration {
	...
}

83.9使用传统persistence.xml档案

Spring Boot将不会搜索或使用META-INF/persistence.xml默认情况下。如果你喜欢使用传统的persistence.xml,您需要定义自己的@Bean类型LocalEntityManagerFactoryBean(ID为‘ghtyManagerFactory’)并在那里设置持久性单元名。

看见JpaBaseConfiguration用于默认设置。

83.10使用Spring数据JPA和MONGO存储库

Spring数据JPA和Spring Data MONGO都可以自动创建Repository为您实现。如果它们都存在于类路径中,那么您可能需要做一些额外的配置来告诉SpringBoot要创建哪个存储库。最明确的方法是使用标准的Spring数据@EnableJpaRepositories@EnableMongoRepositories注释,并提供Repository接口。

还有旗子(spring.data.*.repositories.enabledspring.data.*.repositories.type),可以用来在外部配置中打开或关闭自动配置的存储库。这样做是有用的,例如,如果您想关闭MONGO存储库,但仍然使用自动配置。MongoTemplate.

对于其他自动配置的Spring数据存储库类型(Elasticearch、Solr和其他类型),存在相同的障碍和相同的特性。要使用它们,请相应地更改注释和标志的名称。

83.11将Spring数据存储库公开为REST端点

Spring数据REST可以公开Repository为您提供REST端点的实现,前提是为应用程序启用了SpringMVC。

Spring Boot公开了一组有用的属性(来自spring.data.rest命名空间),自定义RepositoryRestConfiguration。如果需要提供其他自定义,则应使用RepositoryRestConfigurer豆子

[Note]

如果您没有在您的自定义中指定任何订单RepositoryRestConfigurer,它运行在SpringBoot内部使用的One Spring Boot之后。如果需要指定订单,请确保订单高于0。

83.12配置JPA使用的组件

如果要配置JPA使用的组件,则需要确保在JPA之前初始化该组件。当组件自动配置时,SpringBoot会为您处理这个问题。例如,当Flyway自动配置时,Hibernate被配置为依赖于Flyway,这样Flyway就有机会在Hibernate尝试使用之前初始化数据库。

如果您自己正在配置组件,则可以使用EntityManagerFactoryDependsOnPostProcessor子类作为设置所需依赖项的方便方法。例如,如果将Hibernate搜索与Elasticearch一起用作索引管理器,则任何EntityManagerFactorybean必须配置为依赖于elasticsearchClientbean,如以下示例所示:

/**
 * {@link EntityManagerFactoryDependsOnPostProcessor} that ensures that
 * {@link EntityManagerFactory} beans depend on the {@code elasticsearchClient} bean.
 */
@Configuration
static class ElasticsearchJpaDependencyConfiguration
		extends EntityManagerFactoryDependsOnPostProcessor {

	ElasticsearchJpaDependencyConfiguration() {
		super("elasticsearchClient");
	}

}

83.13用两个DataSources配置jOOQ

如果需要对多个数据源使用jOOQ,则应创建自己的DSLContext每个人。请参阅JooqAutoConfiguration更多细节。

[Tip]

特别是,JooqExceptionTranslatorSpringTransactionProvider可以重复使用,以提供与自动配置对单个DataSource.

84.数据库初始化

根据堆栈的不同,可以不同的方式初始化SQL数据库。当然,如果数据库是一个单独的进程,您也可以手动完成。

84.1使用JPA初始化数据库

JPA具有生成DDL的功能,这些特性可以设置为在数据库启动时运行。这是通过两个外部属性控制的:

  • spring.jpa.generate-ddl(Boole)打开和关闭功能,并且与供应商无关。
  • spring.jpa.hibernate.ddl-auto(Enum)是一个Hibernate特性,它以更细粒度的方式控制行为。本指南后面将对此特性进行更详细的描述。

84.2使用Hibernate初始化数据库

你可以spring.jpa.hibernate.ddl-auto显式和标准Hibernate属性值为nonevalidateupdatecreate,和create-drop。SpringBoot根据它是否认为您的数据库是嵌入式的,为您选择一个默认值。默认为create-drop如果没有检测到架构管理器,则为none在所有其他情况下。通过查看Connection类型。hsqldbh2,和derby是嵌入的,而其他的则不是。在从内存中切换到“真实”数据库时,要小心,不要对新平台中的表和数据的存在做出假设。你要么必须设置ddl-auto显式或使用其他机制之一初始化数据库。

[Note]

可以通过启用org.hibernate.SQL伐木工。如果启用调试模式.

此外,一个名为import.sql在类路径的根中,如果Hibernate从头创建模式(也就是说,如果ddl-auto属性设置为createcreate-drop)这对于演示和测试(如果您很小心的话)都是有用的,但是您可能不希望在生产中的类路径上出现这种情况。它是Hibernate特性(与Spring无关)。

84.3初始化数据库

Spring Boot可以自动创建您的架构(DDL脚本)。DataSource并初始化它(DML脚本)。它从标准根类路径位置加载SQL:schema.sqldata.sql分别。此外,SpringBoot还处理schema-${platform}.sqldata-${platform}.sql文件(如果存在),其中platform的价值spring.datasource.platform。这允许您在必要时切换到特定于数据库的脚本。例如,您可以选择将其设置为数据库的供应商名称(hsqldbh2oraclemysqlpostgresql等等)。

[Note]

Spring Boot自动创建嵌入式系统的架构。DataSource。可以使用spring.datasource.initialization-mode财产。例如,如果希望始终初始化DataSource不论其类型:

spring.datasource.initialization-mode=always

默认情况下,SpringBoot启用SpringJDBC初始化程序的故障快速特性。这意味着,如果脚本导致异常,应用程序将无法启动。您可以通过设置spring.datasource.continue-on-error.

[Note]

在基于jpa的应用程序中,您可以选择让Hibernate创建模式或使用schema.sql但你不能两者兼得。确保禁用spring.jpa.hibernate.ddl-auto如果你用schema.sql.

84.4初始化Spring批处理数据库

如果您使用SpringBatch,则它附带了用于大多数流行数据库平台的SQL初始化脚本。SpringBoot可以检测数据库类型,并在启动时执行这些脚本。如果使用嵌入式数据库,默认情况下会发生这种情况。您还可以为任何数据库类型启用它,如以下示例所示:

spring.batch.initialize-schema=always

还可以通过设置spring.batch.initialize-schema=never.

84.5使用高级数据库迁移工具

SpringBoot支持两个更高级的迁移工具:立交桥液基.

84.5.1启动时执行天桥数据库移动

若要在启动时自动运行Flyway数据库迁移,请添加org.flywaydb:flyway-core到你的类路径。

迁移是表单中的脚本。V<VERSION>__<NAME>.sql(与<VERSION>以下划线分隔的版本,如“1”或“2_1”)。默认情况下,它们位于一个名为classpath:db/migration,但是您可以通过设置spring.flyway.locations。这是由一个或多个逗号分隔的列表。classpath:filesystem:地点。例如,下面的配置将在默认类路径位置和/opt/migration目录:

spring.flyway.locations=classpath:db/migration,filesystem:/opt/migration

您还可以添加一个特殊的{vendor}占位符使用特定于供应商的脚本。假设如下:

spring.flyway.locations=classpath:db/migration/{vendor}

而不是使用db/migration,上面的配置根据数据库的类型设置要使用的文件夹(如db/migration/mysql(用于MySQL)。支持的数据库列表可在DatabaseDriver.

有关可用设置(如架构和其他设置)的详细信息,请参见天桥核心中的Flyway类。此外,SpringBoot还提供了一组小的属性(在FlywayProperties),可用于禁用迁移或关闭位置检查。弹簧启动呼叫Flyway.migrate()若要执行数据库迁移,请执行以下操作。如果您想要更多的控制,请提供一个@Bean实现FlywayMigrationStrategy.

Fidway支持SQL和Java回调。若要使用基于sql的回调,请将回调脚本放在classpath:db/migration文件夹。若要使用基于Java的回调,请创建一个或多个实现Callback。任何这样的bean都会自动注册到Flyway。它们可以通过使用@Order或通过实施Ordered。实现不推荐的bean。FlywayCallback接口也可以被检测到,但是它们不能与Callback豆子

在默认情况下,Flyway自动完成以下操作:@PrimaryDataSource在您的上下文中,并将其用于迁移。如果你想用不同的DataSource,您可以创建一个并标记其@Bean@FlywayDataSource。如果您这样做并想要两个数据源,请记住创建另一个数据源并将其标记为@Primary。或者,您也可以使用Flyway的本地DataSource通过设置spring.flyway.[url,user,password]在外部属性中。设置任一个spring.flyway.urlspring.flyway.user就足以使天桥使用它自己的DataSource。如果没有设置这三个属性中的任何一个,则表示其等效值。spring.datasource财产将被使用。

有一个飞道样本这样你就能看到如何安排好一切。

您还可以使用Flyway为特定方案提供数据。例如,可以将特定于测试的迁移放在src/test/resources只有当应用程序开始进行测试时,它们才会运行。此外,您还可以使用特定于配置文件的配置来自定义。spring.flyway.locations因此,某些迁移仅在特定配置文件处于活动状态时才运行。例如,在application-dev.properties,可以指定以下设置:

spring.flyway.locations=classpath:/db/migration,classpath:/dev/db/migration

使用该设置,迁移到dev/db/migration只在dev侧写是活动的。

84.5.2启动时执行Liquibase数据库迁移

若要在启动时自动运行Liquibase数据库迁移,请添加org.liquibase:liquibase-core到你的类路径。

默认情况下,主更改日志是从db/changelog/db.changelog-master.yaml,但是您可以通过设置spring.liquibase.change-log。除了YAML之外,Liquibase还支持JSON、XML和SQL更改日志格式。

在默认情况下,Liquibase提供了以下内容:@PrimaryDataSource在您的上下文中,并将其用于迁移。如果您需要使用不同的DataSource,您可以创建一个并标记其@Bean@LiquibaseDataSource。如果您这样做并且需要两个数据源,请记住创建另一个数据源并将其标记为@Primary。或者,您也可以使用Liquibase的本机DataSource通过设置spring.liquibase.[url,user,password]在外部属性中。设置任一个spring.liquibase.urlspring.liquibase.user足以使Liquibase使用它自己的DataSource。如果没有设置这三个属性中的任何一个,则表示其等效值。spring.datasource财产将被使用。

看见LiquibaseProperties有关可用设置(如上下文、默认架构和其他设置)的详细信息。

有一个液相样品这样你就能看到如何安排好一切。

85.信息传递

SpringBoot提供了许多启动程序,包括消息传递。本节回答了在SpringBoot中使用消息传递时出现的问题。

85.1禁用事务JMS会话

如果JMS代理不支持事务处理会话,则必须完全禁用对事务的支持。如果你自己创造JmsListenerContainerFactory,没有什么可做的,因为在默认情况下,它不能被处理。如果您想使用DefaultJmsListenerContainerFactoryConfigurer要重用SpringBoot的默认设置,可以禁用事务会话,如下所示:

@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(
		ConnectionFactory connectionFactory,
		DefaultJmsListenerContainerFactoryConfigurer configurer) {
	DefaultJmsListenerContainerFactory listenerFactory =
			new DefaultJmsListenerContainerFactory();
	configurer.configure(listenerFactory, connectionFactory);
	listenerFactory.setTransactionManager(null);
	listenerFactory.setSessionTransacted(false);
	return listenerFactory;
}

前面的示例覆盖默认工厂,并且它应该应用于应用程序定义的任何其他工厂(如果有的话)。

86.批处理应用程序

本节回答了在SpringBoot中使用SpringBatch时出现的问题。

[Note]

默认情况下,批处理应用程序需要DataSource来存储工作细节。如果您想要偏离这一点,则需要实现BatchConfigurer。看见.的Javadoc@EnableBatchProcessing更多细节。

有关SpringBatch的更多信息,请参见春季批处理项目页面.

86.1启动时执行Spring批处理作业

通过添加@EnableBatchProcessing(从SpringBatch)上下文中的某个地方。

默认情况下,它执行 Jobs在启动时的应用程序上下文中(请参见JobLauncherCommandLineRunner详细情况)。您可以通过指定spring.batch.job.names(这需要一个以逗号分隔的作业名称模式列表)。

如果应用程序上下文包括JobRegistry,工作spring.batch.job.names在注册表中查找,而不是从上下文中自动查找。这是更复杂系统的常见模式,在子上下文中定义多个作业并集中注册。

看见BatchAutoConfiguration@EnableBatchProcessing更多细节。

87.致动器

弹簧启动包括弹簧启动执行器。本节回答使用它时经常出现的问题。

87.1更改执行器端点的HTTP端口或地址

在独立应用程序中,Actuator HTTP端口默认为与主HTTP端口相同。若要使应用程序侦听其他端口,请设置外部属性:management.server.port。若要侦听完全不同的网络地址(例如,当您有用于管理的内部网络和用于用户应用程序的外部网络时),您还可以设置management.server.address到服务器能够绑定到的有效IP地址。

有关更多细节,请参见ManagementServerProperties源代码和“第53.2节,“自定义管理服务器端口”在“生产准备功能”部分。

87.2自定义“白色标签”错误页

当您遇到服务器错误时,SpringBoot会安装一个‘Whitelabel’错误页面,当您在浏览器客户机中看到该页面时(使用JSON和其他媒体类型的机器客户端应该会看到正确的错误代码的合理响应)。

[Note]

server.error.whitelabel.enabled=false若要关闭默认错误页,请执行以下操作。这样做可以还原您正在使用的servlet容器的缺省值。请注意,SpringBoot仍然试图解决错误视图,因此您可能应该添加自己的错误页面,而不是完全禁用它。

使用自己的模板技术覆盖错误页取决于您使用的模板技术。例如,如果使用Thymeleaf,可以添加error.html模板。如果使用FreeMarker,则可以添加error.ftl模板。一般来说,你需要一个View名称为error或者是@Controller处理/error路径。除非您替换了一些默认配置,否则您应该找到BeanNameViewResolver在你的ApplicationContext,所以@Bean命名error是一种简单的方法。看见ErrorMvcAutoConfiguration寻找更多的选择。

另见关于“错误处理“有关如何在servlet容器中注册处理程序的详细信息。

87.3消毒敏感值

返回的信息envconfigprops端点可能有些敏感,因此匹配特定模式的键在默认情况下会被清除(即它们的值被替换为).

Spring Boot对这些键使用合理的缺省值:例如,以“密码”、“秘密”、“键”或“令牌”结尾的任何键都会被净化。也可以使用正则表达式,例如credentials.对任何保存单词的键进行消毒credentials作为钥匙的一部分。

可以使用management.endpoint.env.keys-to-sanitizemanagement.endpoint.configprops.keys-to-sanitize分别。

88.保安

本节讨论使用SpringBoot时的安全性问题,包括在SpringBoot中使用SpringSecurity时出现的问题。

有关Spring安全性的更多信息,请参见Spring安全项目页面.

88.1关闭SpringBoot安全配置

如果定义@Configuration带着WebSecurityConfigurerAdapter在您的应用程序中,它关闭了SpringBoot中默认的Webapp安全设置。

88.2更改UserDetailsService并添加用户帐户

如果你提供一个@Bean类型AuthenticationManagerAuthenticationProvider,或UserDetailsService,默认@BeanInMemoryUserDetailsManager未创建,因此可以使用完整的SpringSecurity功能集(如各种身份验证选项).

添加用户帐户的最简单方法是提供您自己的帐户。UserDetailsService豆子

88.3在代理服务器后面运行时启用HTTPS

确保所有主要端点只能在HTTPS上使用是任何应用程序的一项重要工作。如果使用Tomcat作为servlet容器,那么SpringBoot添加了Tomcat自己的RemoteIpValve如果它检测到某些环境设置,则会自动执行,并且您应该能够依赖于HttpServletRequest报告它是否安全(即使是处理实际SSL终端的代理服务器的下游)。标准行为取决于是否存在某些请求头(x-forwarded-forx-forwarded-proto),其名称是传统的,因此它应该适用于大多数前端代理。您可以通过添加一些条目来打开阀门。application.properties,如以下示例所示: